The original link: fuckcloudnative. IO/posts/insta…

CoreDNS is a plug-in DNS server written by Golang. It is the default DNS server built in after Kubernetes 1.13. CoreDNS aims to be a DNS server and service discovery solution in cloud-native environments, namely:

Our goal is to make CoreDNS the cloud-native DNS server and service discovery solution.

It has the following features:

  • Plugins

    Based on Caddy server framework, CoreDNS implements a plug-in chain architecture, which abstracts a lot of application logic into the form of plugin (such as Kubernetes DNS service discovery, Prometheus monitoring, etc.) and exposes it to users. CoreDNS preconfigures the different plugins into a chain that executes the logic of the plugin sequentially. At the compilation level, the user selects the desired plugin and compiles it into the final executable, making it more efficient. CoreDNS is written in Go, so at the code level, each plugin is a component that implements its defined interface. Third parties can easily integrate into CoreDNS by writing custom plug-ins that follow the CoreDNS Plugin API.

  • Configuration simplification

    Introduce a more expressive DSL, a configuration file in the form of Corefile (also developed based on the Caddy framework).

  • Integrated solutions

    Different from Kube-DNS, CoreDNS is compiled as a separate binary executable file with built-in functions such as cache, Backend storage, and Health check. It does not require third-party components to implement other functions, making deployment easier and memory management more secure.

In fact, from a functional standpoint, CoreDNS is more like a generic DNS solution (similar to BIND), and then greatly extends its capabilities through a plug-in pattern that can be applied to different scenarios (such as Kubernetes). As the official blog says:

CoreDNS is powered by plugins.

1.Corefile is introduced


Corefile is the CoreDNS configuration file (derived from Caddy framework configuration file Caddyfile), which defines:

  • serverWith which protocol to listen on which port (you can define multiple servers to listen on different ports at the same time)
  • Which one is server responsible for?zoneAuthoritative DNS resolution
  • Which plug-ins will be loaded by server

Typically, a typical Corefile format looks like this:

ZONE:[PORT] {
	[PLUGIN] ...
}
Copy the code
  • ZONE: Defines the zone that the server is responsible for,PORTThe default value is 53.
  • PLUGIN: Defines the PLUGIN that the server loads. Each plugin can have multiple parameters;

Such as:

. {
    chaos CoreDNS-001
}
Copy the code

The above configuration file expresses that server is responsible for resolving the root domain. Plugin is CHAOS and has no parameters.

Define the server

The simplest configuration file can be:

. {}Copy the code

That is, the server listens on port 53 without using the plug-in. ** If you are defining other servers, ensure that the listening ports do not conflict. If a zone is added to a server, ensure that the zones do not conflict with each other. For example:

54 {}. {}. :Copy the code

The other server runs on port 54 and is responsible for root domain. Resolution.

Such as:

example.org {
    whoami
}
org {
    whoami
}
Copy the code

The same server is responsible for parsing different zones and has different plug-in chains.

Define Reverse Zone

Like other DNS servers, Corefile can define a Reverse Zone:

0.0.10. The in - addr. ARPA {whoami}Copy the code

Or a simplified version:

10.0.0.0/24 {whoami}Copy the code

A reverse query can be done with DIG:

10.0.0.1 $dig - xCopy the code

Use different communication protocols

CoreDNS supports TLS and gRPC, namely dnS-over TLS and DNs-over gRPC:

tls://example.org:1443 {
#...
}
Copy the code

2.The working mode of the plug-in


When CoreDNS starts, it starts different servers based on their configuration files, each with its own plug-in chain. When a DNS request is received, it goes through the following three steps of logic:

  1. If the server with the current request has multiple zones, the greedy rule is adopted to select the most matching zone.
  2. Once a matching server is found, plugins on the plug-in chain are executed in the order defined by plugin.cfg;
  3. Each plug-in will determine whether the current request should be processed, and there are several possibilities:
  • The request is processed by the current plug-in

    The plug-in will generate the corresponding response and return to the client, at this point the request ends, the next plug-in will not be called, such as whoami plug-in;

  • Requests are processed as Fallthrough by the current plug-in

    If the request is forwarded to the next plug-in during the processing of the plug-in, the process is called fallthrough, and the keyword fallthrough is used to determine whether the operation is allowed. For example, if the host plug-in is not in /etc/hosts, the next plug-in is invoked.

  • The request is carried Hint during processing

    The request is processed by the plug-in, and some hint is added in its response, which is then forwarded to the next plug-in for processing. This additional information makes up the final response to the client, such as the Metric plug-in;

3.How does CoreDNS handle DNS requests


If Corefile is:

coredns.io:5300 {
    file db.coredns.io
}

example.io:53 {
    logErrors file db.example. IO} example.net:53 {file db.example.net}.:53 {kubernetes proxy.8.8.8.8log
    health
    errors
    cache
}
Copy the code

From the configuration file, we define two servers (albeit with four blocks), listening on port 5300 and 53 respectively. The logical diagram can be as follows:

Each request to a server will execute its loaded plug-ins in the order defined by plugin.cfg.

From the figure above, we should note the following:

  • In spite of the53. :Configure thehealthPlug-in, but it does not appear in the logic diagram above because the plug-in does not participate in the request-related logic (that is, it is not on the plug-in chain) and only modiifies the server configuration. More generally, we can divide plug-ins into two types:
    • Normal plug-in: participates in request-related logic and is inserted into the plug-in chain;
    • Other plug-ins: does not participate in request-related logic and does not appear in the plug-in chain, but is used to modify the server configuration, for examplehealth.tlsSuch as plug-in;

4.Configuration CoreDNS


If CoreDNS is so good, wouldn’t it be nice if I used it against the Great Firewall? The only drawback is that proxies are not supported, but you can force them through proxychians-ng or Proxifier. Now we’re going to do something.

The specific idea is very simple, that is, to forward the domestic domain name query requests to 114 and other domestic public DNS servers, and to forward the foreign domain name query requests to 8.8.8.8 and other foreign public DNS servers. However, CoreDNS’s plugin chain is a bit counter-intuitive. Each plugin in the same plugin chain can only appear once, and using only the Forward plugin is not enough to meet the requirements.

CoreDNS also has a plugin called proxy, which is similar to the function of forward. But the gap between ideal and reality is always very big, DO not know when to start, CoreDNS official compilation of binary files has no proxy plug-in, it is really irritating.

dnsredir

I stumbled across a third party plugin, Dnsredir, that seemed to solve all my problems. This plug-in combines all the advantages of proxy and forward plug-ins. It supports UDP, TCP, DNS-over-TLS, and DNS-over-HTTPS. It also supports multiple backends, health check, and failover.

The syntax looks like this:

dnsredir FROM... {
    to TO...
}
Copy the code
  • FROM… Dnsmasq is a list of files that match the domain name and the server that resolves the domain name.

    Server=/0-100.com/114.114.114.114 server=/0-100.com/114.114.114.114Copy the code

    Why use this format? For convenience, of course.

    Why would that be convenient? Of course, in order to directly use FelixOnMars’ continental region list… FelixOnMars also provides a list of Google and Apple domain names, which in some regions can give certain isps access to the IP of a domestic mirror, thus speeding up access, which is exciting to think about.

  • Of course, in addition to using file lists, you can also use., similar to the root field mentioned above. The best thing about this plugin is that you can reuse the dNSredir plugin in the plugin chain, as long as FROM… Just don’t repeat it.

  • to TO… Used to send DNS resolution requests to the upstream DNS server. Support for almost all DNS protocols, for example:

    DNS: / / 1.1.1.1 8.8.8.8 TCP: / / 9.9.9.9 udp: / / 2606:4700-4700: : 1111 TLS: / / [email protected] TLS: / / 8.8.8.8 tls://dns.quad9.net doh://cloudflare-dns.com/dns-query json - doh: / / 1.1.1.1 / DNS query json - doh: / / DNS. Google/resolve ietf-doh://dns.quad9.net/dns-queryCopy the code

Enhanced version CoreDNS

Dnsredir is sweet, but don’t forget that it is a third party plugin and is not included in the official default binary. You can choose to build it yourself, but what if you need to upgrade often? You can’t compile it manually every time, it’s too tiring.

Fortunately, a big guy has integrated and compiled all the third party plug-ins needed through CI/CD process, and updated them regularly, which is my good news. Big Guy’s project address is:

  • Github.com/missdeer/co…

Now all you need to do is download the binaries for your operating system, copy them everywhere, and you’re up and running.

Let’s take MacOS as an example. The same is true for Openwrt gameplay, which will not be discussed in this article.

Download binaries directly:

$ wget 'https://appveyorcidatav2.blob.core.windows.net/missdeer-15199/coredns-custom-build/1-7-1-514/idbodwxwywg1xgdg/distrib/c oredns-linux-amd64.zip?sv=2015-12-11&sr=c&sig=BhMWcOVtDuaETyz2DcjpOr9GdvkpNVOqoIa7iWFpFNQ%3D&st=2020-12-23T15%3A26%3A19Z &se=2020-12-23T15%3A32%3A19Z&sp=r'
$ $ tar zxf coredns-linux-amd64.zip
$ mv coredns-linux-amd64/coredns /usr/local/bin/
Copy the code

configuration

To learn more about CoreDNS, check out its documentation and plugins. Here is my configuration file:

cat > /usr/local/etc/Corefile <<EOF # https://coredns.io/plugins/cache/ (global_cache) { cache { # [5, 60] success 65536 3600 300 # [1, 10] denial 8192 600 60 prefetch 1 60m 10% } } .:7913 { ads { default-lists blacklist https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt whitelist https://files.krnl.eu/whitelist.txt log auto-update-interval 24h list-store ads-cache } errors hosts { fallthrough } health prometheus :9153 import global_cache template ANY AAAA { rcode NXDOMAIN } dnsredir accelerated-domains.china.conf  google.china.conf apple.china.conf mydns.conf { expire 15s max_fails 3 health_check 3s policy round_robin path_reload Expire 60s max_fails 5 Health_check 5s policy random spray //[email protected] TLS ://[email protected] to TLS ://[email protected] //[email protected] # Global TLS servername # tls_servername cloudflare-dns.com} log loop reload 6s } EOF
Copy the code
  • hosts : hostsIs a plugin to CoreDNS, and this section means load/etc/hostsParsing information in the file. Hosts comes first. If a domain name exists in the hosts file, this information is returned preferentially.
  • fallthroughIf:hostsIf no, enter the next plugin to continue. Without this directive, the plugins are meaningless.
  • Cache: The result of tracing to the source is cached for a specified time. TTL like concept;
  • Reload: How often the configuration file is scanned. If there is change, automatic loading;
  • Errors: Prints/stores error logs.
  • dnsredirThis is the key plug-in. The first dNSredir configuration uses four file lists, all of which areFelixOnMars’ list of continental regional namesHere I also add a custom file listmydns.conf. The second dnsredir configuration represents the default resolution configuration, which can be understood as failover. If a domain name does not match any of the file lists, the upstream DNS server of the second dnsredir is used for resolution. In this configuration mode, the domestic domain name query requests are forwarded to domestic public DNS servers such as 114 and foreign domain name query requests are forwarded to foreign public DNS servers such as 8.8.8.8.

Here’s my own understanding:

  1. Configuration files are similar in format to nginx configuration files;
  2. The outermost level of braces corresponds to the concept of “service”. Multiple services can share a port;
  3. The curly braces one level inside correspond to plugins, and each curly brace is a plugin. As you can see here, plugins were first class citizens of CoreDNS;
  4. There is no sense of sequential correlation between services, but plugins are severely sequential. Some plugins must be usedfallthroughKeywords flow to the next plugin;
  5. The configuration options within the plugin are sequential;
  6. CoreDNS can be easily transferred from BIND and is compatible with the operation and maintenance habits of the old-style DNS server.
  7. From the performance indicators of CoreDNS, it is suitable for large services.

Note: The premise of this scenario is to be able to force CoreDNS to use the proxy, or more precisely, 8.8.8.8 and 8.8.4.4 to use the proxy. The method here is a bit more complicated and will not be introduced in this article. If you really don’t know what to do, you can remove the 8.8.8.8 line and use Cloudflare’s DNS service, which is a bit slow but accessible.

If you can’t stand Cloudflare’s response speed, consider using the domestic pollution-free DNS: Redfish DNS. And then go straight for good:

cat > /usr/local/etc/Corefile <<EOF # https://coredns.io/plugins/cache/ (global_cache) { cache { # [5, 60] success 65536 3600 300 # [1, 10] denial 8192 600 60 prefetch 1 60m 10% } } .:7913 { ads { default-lists blacklist https://raw.githubusercontent.com/privacy-protection-tools/anti-AD/master/anti-ad-domains.txt whitelist https://files.krnl.eu/whitelist.txt log auto-update-interval 24h list-store ads-cache } errors hosts { fallthrough } health prometheus :9153 import global_cache template ANY AAAA { rcode NXDOMAIN } dnsredir accelerated-domains.china.conf  google.china.conf apple.china.conf mydns.conf { expire 15s max_fails 3 health_check 3s policy round_robin path_reload Expire 60s max_fails 5 Health_check 5s policy random spray to doh://13800000000.rubyfish.cn } log loop reload 6s } EOF
Copy the code

So CoreDNS doesn’t have to worry about walking proxies.

Update domestic domain name list regularly

The list of mainland domain names is updated daily, so you need to write a script to update the file list. No need to check whether the file exists, just simple and senseless update:

$ cat > /usr/local/bin/update_coredns.sh <<EOF
#!/bin/bash

rm accelerated-domains.china.conf
wget https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/accelerated-domains.china.conf -O /usr/local/etc/accelerated-domains.china.conf
rm apple.china.conf
wget https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/apple.china.conf -O /usr/local/etc/apple.china.conf
rm google.china.conf
wget https://cdn.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/google.china.conf -O /usr/local/etc/google.china.conf
EOF
$ sudo chmod +x /usr/local/bin/update_coredns.sh
Copy the code

Run the script to update the Corefile configuration:

$ /usr/local/bin/update_coredns.sh
Copy the code

Then create a scheduled task with Crontab to update the domain list every two days at 2 PM:

$ crontab -l
0 14 */2 * * /usr/local/bin/update_coredns.sh
Copy the code

Boot from the rev.

MacOS can use Launchctl to manage services. It can control which services need to be enabled when the computer is started, and it can also set up scripts to perform specific tasks on a regular basis, like Linux crontab, by installing *.plist files to execute commands. Launchd scripts are stored in the following locations and you need to create your own personal LaunchAgents directory by default:

  • ~/Library/LaunchAgents: User-defined task item
  • /Library/LaunchAgents: Task item defined by the administrator for users
  • /Library/LaunchDaemons: Daemon task item defined by the administrator
  • /System/Library/LaunchAgents: Task item defined by MacOS for the user
  • /System/Library/LaunchDaemons: Daemon task item defined by MacOS

We chose to create the coredns.plist file in the /Library/LaunchAgents/ directory as follows:


      
<! DOCTYPEplist PUBLIC "- / / Apple Computer / / DTD PLIST / 1.0 / EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>coredns</string>
    <key>ProgramArguments</key>
    <array>
      <string>/usr/local/bin/coredns</string>
      <string>-conf</string>
      <string>/usr/local/etc/Corefile</string>
    </array>
    <key>StandardOutPath</key>
    <string>/var/log/coredns.stdout.log</string>
    <key>StandardErrorPath</key>
    <string>/var/log/coredns.stderr.log</string>
    <key>KeepAlive</key>
    <true/>
    <key>RunAtLoad</key>
    <true/>
  </dict>
</plist>
Copy the code

Set coreDNS to automatically start after startup:

$ sudo launchctl load -w /Library/LaunchAgents/coredns.plist
Copy the code

View services:

$ sudo launchctl list|grep coredns

61676	0	coredns
Copy the code
$ sudo launchctl list coredns

{
	"StandardOutPath" = "/var/log/coredns.stdout.log";
	"LimitLoadToSessionType" = "System";
	"StandardErrorPath" = "/var/log/coredns.stderr.log";
	"Label" = "coredns";
	"TimeOut" = 30;
	"OnDemand" = false;
	"LastExitStatus" = 0;
	"PID" = 61676;
	"Program" = "/usr/local/bin/coredns";
	"ProgramArguments" = (
		"/usr/local/bin/coredns";
		"-conf";
		"/usr/local/etc/Corefile";
	);
};
Copy the code

Check the port number:

$sudo ps - ef | grep egrep - v | grep coredns 1 0 0 81819 2:54 afternoon?? 0:04. 70 / usr /local/bin/coredns -conf /usr/local/etc/Corefile
    
$ sudo lsof -P -p 81819|egrep "TCP|UDP"coredns 81819 root 5u IPv6 0x1509853aadbdf853 0t0 TCP *:5302 (LISTEN) coredns 81819 root 6u IPv6 0x1509853acd2f39ab 0t0 UDP *:5302 coredns 81819 root 7u IPv6 0x1509853aadbdc493 0t0 TCP *:53 (LISTEN) coredns 81819 root 8u IPv6 0x1509853acd2f5a4b 0t0 UDP *:53 coredns 81819 root 9u IPv6 0x1509853ac63bfed3 0t0 TCP *:5301 (LISTEN) coredns 81819 root  10u IPv6 0x1509853acd2f5d03 0t0 UDP *:5301Copy the code

You’re done. Now all you need to do is set your system’s DNS IP to 127.0.0.1.

validation

$doggo www.youtube.com @udp://127.0.0.1 NAME TYPE CLASS TTL ADDRESS NAMESERVER www.youtube.com. CNAME IN 293s Youtui.l.google.com. 127.0.0.1:53 youtui.l.google.com. A IN 293s 172.217.14.110 127.0.0.1:53 A IN 293s 172.217.11.174 127.0.0.1:53 youtube-ui.l.google.com. A IN 293s 172.217.5.206 Youtube-ui.l.google.com. A IN 293s 172.217.5.78 127.0.0.1:53 youtube-ui.l.google.com. A IN 293s A IN 293s 142.250.72.238 127.0.0.1:53 youtube-ui.l.google.com. A IN Youtube-ui.l.google.com. A IN 293s 142.250.68.110 127.0.0.1:53 youtube-ui.l.google.com A IN 293s 142.250.68.78 127.0.0.1:53 youtube-ui.l.google.com. A IN 293s 172.217.4.142 127.0.0.1:53 Youtui.l.google.com. A IN 293s 142.250.68.14 127.0.0.1:53Copy the code

Get things done.

What? What is doggo? Scan the qr code below to follow the public account:

Public account backstage reply doggo can get what you want 😬

5.The resources


  • CoreDNS usage and architecture analysis
  • CoreDNS setup pollution-free DNS