0% found this document useful (0 votes)
60 views127 pages

Lab Guide Cacheserve7.6-Rev D

Uploaded by

ja.simarro82
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
60 views127 pages

Lab Guide Cacheserve7.6-Rev D

Uploaded by

ja.simarro82
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 127

DNSi CacheServe

Lab Guide
Software Release 7.6 | Revision D

Akamai Technologies, Inc.


150 Broadway
Cambridge, MA
United States 02142
www.akamai.com
Akamai secures and delivers digital experiences for the world’s largest companies. Akamai’s
intelligent edge platform surrounds everything, from the enterprise to the cloud, so customers
and their businesses can be fast, smart, and secure. Top brands globally rely on Akamai to help
them realize competitive advantage through agile solutions that extend the power of their
multi-cloud architectures. Akamai keeps decisions, apps, and experiences closer to users than
anyone — and attacks and threats far away. Akamai’s portfolio of edge security, web and mobile
performance, enterprise access, and video delivery solutions is supported by unmatched
customer service, analytics, and 24/7/365 monitoring. To learn why the world’s top brands trust
Akamai, visit www.akamai.com, blogs.akamai.com, or @Akamai on Twitter. You can find our
global contact information at www.akamai.com/locations.

Akamai is headquartered in Cambridge, Massachusetts in the United States with operations in


more than 57 offices around the world. Our services and renowned customer care are designed
to enable businesses to provide an unparalleled Internet experience for their customers
worldwide. Addresses, phone numbers, and contact information for all locations are listed on
www.akamai.com/locations.

© 2021 Akamai Technologies, Inc. All Rights Reserved. Reproduction in whole or in part in any
form or medium without express written permission is prohibited. Akamai and the Akamai wave
logo are registered trademarks or service marks in the United States (Reg. U.S. Pat. & Tm. Off).
Akamai Intelligent Edge Platform is a trademark in the United States. All other trademarks
contained herein are the property of their respective owners. Akamai believes that the
information in this publication is accurate as of its publication date; such information is subject
to change without notice.

Published 1/2021.

Additional License Information

Solaris™ is a registered trademark of Oracle and/or its affiliates. All rights reserved.
Java™ is a registered trademark of Oracle and/or its affiliates. All rights reserved.
Windows® is a registered trademark of Microsoft, Inc. All rights reserved.
Python is copyright © 2001, 2002 Python Software Foundation; All rights reserved.
Introduction DNSi CacheServe

Table of Contents
Introduction .........................................................................................................................iii

Lab 1: “Default” CacheServe Behavior ....................................................................................1

Lab 2: More Configuration Objects .......................................................................................10

Lab 3: Operations I—Resource Use and Cache Performance ..................................................14

Lab 4: Operations II—Looking at a Resolver ..........................................................................19

Lab 5: Operations III—Using Policy to Deny Service ...............................................................23

Lab 6: Operations IV—Events, SNMP, and basic “rate-limiting” .............................................26

Lab 7: Increasing Resistance to Cache Poisoning ...................................................................33


Query Source Port Randomization ......................................................................................... 33
Query Name Case Randomization.......................................................................................... 34
Lab 8: DNSSEC support with Managed Keys ..........................................................................37

Lab 9: Understanding “Real Time Visibility” ..........................................................................41

Lab 10: Threshold Monitoring with “Real Time Alerts” ..........................................................51

Lab 11: Offline access to the CacheServe configuration Database ..........................................56

Lab 12: Troubleshooting snmpagent with CacheServe ........................................................59

Lab 13: Working with Stub and Forward statements .............................................................62

Lab 14: Recording authoritative traffic with Auth-Querystore ...............................................65

Lab 15: Response customization with Precision Policies ........................................................68


Dropping “ANY” queries to selected domains ........................................................................ 68
Preferred Address Sorting ...................................................................................................... 69
Lab 16: Advanced Rate-Limiting............................................................................................73

Lab 17: ECS and Equivalence Classes .....................................................................................76

Lab 18: IPv6 and DNS64 ........................................................................................................79

Lab 19: Customizing the CacheServe Service Script ................................................................82

Lab 20: Installing the Perl API ...............................................................................................84

Lab 21: Simple and Useful Program ......................................................................................87

Lab 22: Your First Perl CC API Program ..................................................................................89

Akamai Confidential Page i


DNSi CacheServe Introduction

Answers to Exercises ............................................................................................................93


ANSWER TO EXERCISE 1 ......................................................................................................... 93
ANSWER TO EXERCISE 2 ......................................................................................................... 95
ANSWER TO EXERCISE 3 ......................................................................................................... 96
ANSWER TO EXERCISE 4 ......................................................................................................... 96
ANSWER TO EXERCISE 7 ......................................................................................................... 96
ANSWER TO EXERCISE 8 ......................................................................................................... 96
ANSWER TO EXERCISE 10 ....................................................................................................... 97
Appendix: Anatomy of a dig display....................................................................................98

Appendix: CacheServe SNMP objects.................................................................................. 101

Appendix: CacheServe Solaris 11 Installation Notes ............................................................ 108

Appendix: CacheServe RHEL7 Installation Notes ................................................................. 111

Appendix: Perl API Installation Notes ................................................................................. 114


1: HOW TO prepare the Perl environment for Nominum’s CC API ....................................... 114
2: HOW TO Check Perl’s installed modules .......................................................................... 116
3: Detailed Examination of a Trivial Program ...................................................................... 117

Page ii Akamai Confidential


Introduction DNSi CacheServe

Introduction
This guide should be used with the CacheServe slide presentation. The student should have
understood the concepts presented in the seminar in order to benefit from the material in this
guide.

Exercises help illustrate basic features of resolvers such as preload. The contents of the cache
are explored and troubleshooting tools such as server.query are introduced.
Troubleshooting tools such as the “inspect(-delegation)” commands for reading cache entries
are demonstrated. Use of the recursing command to help recognize domains toward which a
PRSD attack is directed is shown. More sophisticated, but general purpose, configuration such as
policy creation for ignoring (“blackhole”) specific clients, rate-limiting client activity overall and
to specific domains are introduced. Uses of policy for very specific purposes such as DNS64 can
be demonstrated if there is audience interest. Real Time Visibility for detailed inspection of DNS
query patterns and statistics gathering is shown. The use of CacheServe events and their relation
to the SNMP agent are explored.

A framework for simulating a cache poisoning attack is described at the end of this introduction.

An overview of the Command Channel API using Perl is included to acquaint the reader with
sample utilities included with the Software Development Kit (SDK) package, and to demonstrate
how simple programs can fetch CacheServe data. No programming experience is required to
complete these exercises.

It is assumed the student has root access on a Red Hat or Solaris host with the Akamai DNSi
CacheServe version 7.6 or higher installed with a valid license key, and that Internet access is
available. CacheServe installation instructions appear in the Appendix. It is also assumed that a
recent version of dig (higher than 9.6) is installed on the student’s host. This utility is usually
found at /usr/local/bin/dig or /usr/bin/dig. It is further recommended that Adobe
Acrobat Reader be available to access the product documentation (Akamai CacheServe
Administrator’s Manual) which is available from Akamai Carrier support portal
(support.nominum.com), the same location from which a customer downloads CacheServe.

The instructor will provide an environment with the following utilities:

1. A DNS traffic generation utility is helpful to illustrate querystore behavior,


querythreshold and rate limiting configuration, and use of cacheserve-stats. This
script allows query rate per second per student to be set by editing the file
DNS_load_generator.pl and adjusting the variable $qps.
a. The script uses Perl and the Net::DNS framework, so the instructor machine
must have this module installed. This is often conveniently accomplished with
commands such as
# yum install perl-Net-DNS
b. To emulate DNS amplification attacks, logic that enables EDNS0 in the
synthesized client requests when the query name matches one of the known
“amplification domains” published at

Akamai Confidential Page iii


DNSi CacheServe Introduction

http://dnsamplificationattacks.blogspot.com/ was added to the training lab with


the release of DNSi CacheServe version 7. The site has not been updated with
current domains for several years, but the concepts for defense against such
attacks remain unchanged.
c. To activate the Success-based Rate Limiting (SRL) feature and the corresponding
statmon SRL flag’s value for detecting Psuedo Random SubDomain (PRSD)
attacks, two constituents must be available in the lab:
i. A query generator that sends randomized first label queries for a
domain, and
ii. A stub configured for that domain that points to an authority server
with rate-limiting enabled.
d. For IPv6 query generation, the Perl environment must also have the appropriate
libraries (Socket6 and IO::Socket::INET6). The script can report
whether IPv6 transport is available by using the resolver object’s print method.
See the Appendix for additional info about Perl modules.

Link local IPv6 addresses should not be used for inter-host communication.
Instead, permanently add unique local (RFC 4193) addresses by including
NETWORKING_IPV6=yes in the /etc/sysconfig/network file and
including IPV6INIT=yes and a suitably chosen
IPV6ADDR="fd0c:a43a:811f:00ac:10bb::10/64" entry in the
 /etc/sysconfig/network-scripts/ifcfg-eth0 (or other interface)
file.

Temporary addresses can be assigned with a command such as:


/sbin/ip -6 addr add fd0c:a43a:811f:ac:10bb::0000/64
dev vmnet8

2. An SNMP trap watcher verifies that the snmp_agent is configured adequately for
traps.
3. OPTIONAL: A collection of querystore files which represents results of DNS activity
against a CacheServe instance in Nominum’s lab.
4. OPTIONAL: The Metasploit framework can be used to create “spoofed” DNS responses
to help illustrate certain aspects of CacheServe’s cache poisoning defenses. Some of the
facilities used include
a. the “spoofhelper” service—an authoritative server which responds to any TXT
query with the client’s query source port
b. the “spoof bailiwicked domain” module. It requires options as shown here:

Page iv Akamai Confidential


Introduction DNSi CacheServe

Name Default Setting Required Description

---- --------------- -------- -----------

DOMAIN example.com yes Domain to hijack

NEWDNS yes Hostname of the replacement DNS server

RECONS 208.67.222.222 yes Nameserver used for reconnaissance

RHOST yes Target address

SRCADDR Real yes Source address for sending queries (Real/Random)

SRCPORT yes Target server's source port (0 for automatic)

TTL 47954 yes TTL for the malicious host entry

XIDS 0 yes Number of XIDs tried per query (0 for automatic)

Some of the commands needed to start these services are:

# export PATH=$PATH:/usr/local/msf32/trunk

# msfcli auxiliary/server/dns/spoofhelper e &

# msfcli auxiliary/spoof/dns/bailiwicked_domain DOMAIN=wellsfargo.com


NEWDNS=myns.wellsfargo.com RECONS=172.16.187.1 RHOST=172.16.187.10 SRCPORT=0 e &

Answers and Hints for the Exercises (where applicable) appear at the end of this document.

Akamai Confidential Page v


“Default” CacheServe Behavior DNSi CacheServe

Lab 1: “Default” CacheServe Behavior


OVERVIEW: The main purpose is to illustrate CacheServe operation when started without any
modification of its default configuration. We first install CacheServe, and then start the server.
To gain familiarity with its behavior, we query the server with dig, and inspect the messages
logged by CacheServe. We discuss the automatically generated world resolver and introduce
basic interactive control of CacheServe with the nom-tell utility.

 DNSi CacheServe has built-in root hints. If Internet access is unavailable, the root
servers will be unreachable, and name resolution will fail.

STEP-BY-STEP:
1. Login as root.
2. Install DNSi CacheServe, if it is not already installed. Instructions are found in the
Appendix of this guide. See page 108 for the Solaris operating system and page 111 for
Linux.
3. Copy the license file provided by the instructor to the directory
/usr/local/nom/etc/:

# cp /root/cacheserve.license /usr/local/nom/etc/

A typical license file for the DNSi CacheServe product is shown here. It has limited validity
because it is used for the training lab. License files provided for production servers do not have
expiration dates:

Akamai Confidential Page 1


DNSi CacheServe “Default” CacheServe Behavior

product = cacheserve

customerid = 306

reqid = 2

created = "2020-08-21 09:57:52"

customer_name = "Nominum Training"

expires = "2021-06-30 23:59:59"

limits = ((concurrency 1))

uuid = "ed744313-3d91-47a4-bc98-9684c21b1d69"

--

CJOzcso907lMO1yhs0HJm9ORGcwPybGNL/0ZZVzg4me2mo06PLXkYsQ=

The “concurrency” limit restricts the number of cores used—to one each in this
example—by the CacheServe process for 3 high-intensity tasks: UDP reception,
TCP reception and recursions.

An “n2” feature is required for unlimited access to the policy framework, or to

 use the provisioning capabilities of the SPS (formerly N2) platform. Special
features such as “threatavert” may be required for some products.

The license used in this course permits up to10 basic policies (having restrictions
on actions and selectors). Lists are confined to a limited quantity of objects: 10
lists, with up to 100 nodes per list.

4. By default, DNSi CacheServe writes log output to the host’s syslog utility. Open a
separate window with your terminal emulation program so that you can monitor DNSi
CacheServe activity by viewing syslog output, with the command:

# tail –f /var/log/messages or # tail –f /var/adm/messages

 General operational information is sent to syslog with priority LOG_INFO. Consult


the DNSi CacheServe documentation for priority of other types of messages.

Page 2 Akamai Confidential


“Default” CacheServe Behavior DNSi CacheServe

5. Start the DNSi CacheServe server using the command:

# /bin/systemctl start cacheserve

 The “auto Nanny” which starts the actual DNS server is also called cacheserve,
so expect to see two cacheserve processes when viewing the process list with
ps or similar utility.

6. Confirm that DNSi CacheServe has started:


a. Check the syslog file, where you should find a message indicating that DNSi
CacheServe is running.
b. Check whether DNSi CacheServe is running by sending a message which
requests process details:

# nom-tell cacheserve process-information

The process ID field identifies the working DNS server process, not the auto-Nanny.

7. Request the DNSi CacheServe software’s version, then display the server and resolver
objects with the version, server.get, and resolver.mget “Command
Channel” instructions shown here:

# nom-tell cacheserve version

# nom-tell cacheserve server.get

# nom-tell cacheserve resolver.mget

Sample output is shown in the answers section of this guide.

 For convenience, Akamai recommends adding /usr/local/nom/sbin to


your path.

Akamai Confidential Page 3


DNSi CacheServe “Default” CacheServe Behavior

In the training environment this has already been done for you. Because
CacheServe’s installer does not modify any environment variables; this must be
done as an extra manual step.

8. Test that the server will answer DNS requests by using dig to query for a name which
we know will resolve. At your shell prompt, type the following:

# dig @127.1 google.com

The results should include several address records for google.com.

Because we will use the loopback address repeatedly, we exploit the fact that the

 dig utility interprets 127.1 as a contraction of the full IP address 127.0.0.1.

We prefer to be explicit about the target DNS server in the dig command.

Next, find the “routable” IP addresses (v4 and v6) of your CacheServe instance and send
a query to those interfaces, rather than the loopback:

# ip addr
# dig @<your-IPv4-address> google.com

# dig @<your-IPv6-address> google.com

Response should be the same as before, but from the CacheServe resolver’s cache.

9. Query for a special CHAOS class name:

# dig @127.1 version.server CH TXT

Page 4 Akamai Confidential


“Default” CacheServe Behavior DNSi CacheServe

 CHAOS-class support is available only for the standard names such as id.server
and version.server described in RFC 4892.

10. Try to query for another name which we know does NOT exist:

# dig @127.1 localhost

You should find DNSi CacheServe responds with NXDOMAIN.

11. We wish to make a modification to the CacheServe configuration, but before doing so
(in the next step) we backup the current configuration:

# mkdir /var/nom/cacheserve.ex1

# nom-tell cacheserve server.block-checkpoints

# cp -r /var/nom/cacheserve/* /var/nom/cacheserve.ex1/

# nom-tell cacheserve server.unblock-checkpoints

The complete backup procedure for a production CacheServe application would


normally include making copies of several other directories and files, such as
/usr/local/nom/etc/ and /etc/channel.conf,. For details, see the
DNSi CacheServe manual.

 The restoration procedure is simply to stop DNSi CacheServe, copy archived files
back to their original location, and then start DNSi CacheServe.

For example, to restore the training environment to its initial state using the
backup files created in this exercise, do the following:
# cp -r /var/nom/cacheserve.ex1/* /var/nom/cacheserve/

Akamai Confidential Page 5


DNSi CacheServe “Default” CacheServe Behavior

12. In this step we over-write the default server “listener” configuration. Start nom-tell
in interactive mode:

# nom-tell cacheserve

From the empty nom-tell (“cacheserve”) command line, you can type the “tab”
character to show valid commands. A response is shown here:

cacheserve> <TAB>

action. device-list. name-node. server.

address-list. device-node. policy. stop

address-node. dns64. process-information telemetry.

auth-monitoring. instance-information public-key. tls-certificate.

auth-server-list. layer. ratelimiter. uuid

auth-server-node. monitoring. resolver. version

binding. name-group. restart view.

connection. name-list. selector. view-selector.

CacheServe objects which constitute the server’s working configuration make up

 most of the above display. They can be recognized by the trailing dots, which
indicate that a method (such as update, add or delete) is expected when
manipulating that type of object.

Type a server.update instruction to change the listen-on-matching Server


configuration statement to include only your host’s local loopback address (127.0.0.1):

cacheserve> server.update listen-on-matching=({patterns=(127.0.0.1)})

cacheserve> server.get

Page 6 Akamai Confidential


“Default” CacheServe Behavior DNSi CacheServe

Check that you can still send a query to CacheServe on your loopback address, but that a
request to the routable IP address fails:

# dig @127.1 google.com  this should work

# dig @<your-IPv4-address> google.com  this should time-out

# dig @<your-IPv6-address> google.com  this should time-out

The DNSi CacheServe configuration is modified immediately when the update


command is executed. No further operator steps are necessary for the changes to
take effect.

Depending on the change, the server may restart automatically or flush its cache.

Modify the listen-on-matching field to contain two patterns for the routable IP
addresses of your host:

cacheserve> server.update listen-on-matching+=({patterns=(10.128.0.0/9


fe80::4001:0:0:0/80)})

The IP addresses used here are examples; your value for the IP addresses may differ.

Note the “+=” instead of a simple “=”. This is called the command channel’s


incremental syntax for manipulating elements of a list:

• Use incremental syntax “+=” to add values to an existing list.


• Use the assignment operator “=” to overwrite (replace) a field’s contents.

Check that the Server object is updated:

Akamai Confidential Page 7


DNSi CacheServe “Default” CacheServe Behavior

cacheserve> server.get

Confirm you can use dig to successfully query on any of the three IP addresses:

# dig @127.1 google.com

# dig @<your-IPv4-address> google.com

# dig @<your-IPv6-address> google.com

13. Although the domain name localhost is not a valid top-level domain (TLD), it has a
conventional interpretation as the name of the loopback interface, for which the IPv4
address is 127.0.0.1. When a preload statement is configured, CacheServe provides
this address to clients directly, avoiding lookups to the root servers.
Type a resolver.update instruction as shown below. Then, verify that the change
was successfully implemented with the resolver.get command:

cacheserve> resolver.update name=world preload=((localhost A 127.0.0.1))

cacheserve> resolver.get name=world

14. Repeat your request to DNSi CacheServe for localhost:

# dig @127.1 localhost

You should find that the result is now “127.0.0.1” instead of NXDOMAIN.

15. Stop the server using the service script:

# /bin/systemctl stop cacheserve

The termination of CacheServe should be noted with messages in syslog.

Page 8 Akamai Confidential


“Default” CacheServe Behavior DNSi CacheServe

SUMMARY:
Congratulations! You installed, started, backed-up, modified, and stopped DNSi CacheServe.

You learned:

a. nom-tell is used to send Command Channel instructions to a running


DNSi CacheServe,
b. by default, DNSi CacheServe responds to DNS requests received from any
client on any of the interfaces on the server host,
c. Since listening on all interfaces can lead to problems with clients not
accepting responses on multi-homed machines, we customized “listen-on-
matching”, and
d. It is possible to permanently add a record to DNSi CacheServe’s cache using
a “preload” resolver update.

Using a port other than the default DNS (53) requires another description in the

 list of listen-on-matching dictionary elements, such as


{patterns=(127.0.0.1) port=5353}

More on the fields of listen-on-matching in a later exercise.

Akamai Confidential Page 9


DNSi CacheServe More Configuration Objects

Lab 2: More Configuration Objects


OVERVIEW: In this exercise we explore other modifications of the DNSi CacheServe
configuration. We focus on the following:

1) Resolver objects, which consist of a cache and instructions for looking up names which
do not appear that cache.
2) Creating new View-selectors, Views and Resolvers. Views help return alternative DNS
data based on information such as the client IP address. We learn that View-selectors
determine which View should be used to resolve the query.
3) View-selectors without criteria match all requests that do not match more specific View-
selectors.
4) Output of the resolver.statistics command helps confirm requests are
satisfied from the desired View(s).

STEP-BY-STEP:
1. Restart CacheServe:

# systemctl start cacheserve

If DNSi CacheServe is not running, it is not possible to use nom-tell (i.e. the

 Command Channel) to change the configuration.

To directly edit the configuration when DNSi CacheServe is not running, use the
cacheserve-editconf tool. More on this utility in a later exercise.

2. Using dig, confirm that DNSi CacheServe responds to a few queries (e.g. localhost,
google.com, akamai.com) in the same way as before.

# dig @127.1 localhost

3. Create a new Resolver by adding a Resolver object called “internal”:

Page 10 Akamai Confidential


More Configuration Objects DNSi CacheServe

cacheserve> resolver.add name=internal

4. Check that the Resolver has been added by using a “multiple get” (mget) command:

cacheserve> resolver.mget

♦ What is the result of querying the server for localhost again? You should find no
change.

A Resolver can be removed with the resolver.delete command. All its

 properties are removed with it, and the only way to restore the Resolver is to
recreate it.

5. Create a View called “internal” that uses the Resolver you just created, and then specify
that queries from the loopback address should use the “internal” View:

cacheserve> view.add name=internal resolver=internal

cacheserve> view-selector.add source-address=127.0.0.1 view=internal

6. Repeat the localhost query:

# dig @127.1 localhost

♦ Is the response for the A record of localhost still determined by our preload
statement in the “world” Resolver? In other words, is the response still 127.0.0.1?
Why?

Akamai Confidential Page 11


DNSi CacheServe More Configuration Objects

♦ Find the IP address of another student’s CacheServer instance. Use dig to query for
localhost against their machine. Explain your results.

7. The instructor can use a traffic generator to send a few queries to your DNSi CacheServe
server. Use the resolver.statistics command to display information about
DNSi CacheServe activity for each of the resolvers:

cacheserve> resolver.statistics name=internal

cacheserve> resolver.statistics name=world

From the output, you will be able to answer the next question.

♦ Which Resolver responded to the instructor’s queries?

The previous steps illustrate that CacheServe uses the most-specific view-
selector when processing DNS requests. During the lecture, the instructor
will demonstrate the results of NO matching view-selector: the REFUSED

 response.

In the statmon traffic analysis tool we meet later in the course, this condition
(no matching view-selector for a query) is represented by
view=<none>. In the nom-kafka traffic analysis tool used for the SPS
(Security and Personalization Services) products, the view tag is simply absent.

8. Stop CacheServe again:

# systemctl stop cacheserve

Page 12 Akamai Confidential


More Configuration Objects DNSi CacheServe

9. The following command is expected to fail, but try it anyway:

cacheserve> start

♦ What is the result of sending a Command Channel instruction to a stopped


CacheServe?

SUMMARY:
You have now completed a basic introduction to the configuration of DNSi CacheServe.

1. The configuration database contains several types of objects:


a. A Server object controls the operation of DNSi CacheServe as a whole. Only one
server object is permitted.
b. Resolver objects can be created, modified, and removed with add, update,
and delete methods, respectively.
c. Views must be associated with a resolver.
2. A Resolver is used to lookup answers for client requests. That process can be
customized for bulk numbers of clients. The population for which a given customization
applies is defined by a view-selector that associates requests to views—and
thus, resolvers.
3. Statistics are reported on a per-resolver basis with the resolver.statistics
instruction. In the next exercise we show that statistics for the server as a whole can be
obtained with the server.statistics command.

Akamai Confidential Page 13


DNSi CacheServe Operations I—Resource Use and Cache
Performance

Lab 3: Operations I—Resource Use and Cache Performance


OVERVIEW: We next consider typical operational concerns. We discuss how to check current
resource use and understand options for controlling memory consumption.

STEP-BY-STEP:
1. Restart your CacheServe instance:

# systemctl start cacheserve

2. Assuming the instructor is sending queries to your server, you will see counters for
“requests-received” and “responses-sent” in the output from server.statistics:

cacheserve> server.statistics

♦ Are the counters for responses-sent and requests-received equal?

♦ Record the memory and recursion-contexts values:


memory-in-use =>
recursion-contexts-in-use =>

If recursion contexts is zero, it will not be listed. Use server.statistics


all=1 to see all stats.

3. Each Resolver maintains its own statistics. Compare the memory in use for each of the
two caches

cacheserve> resolver.statistics name=internal

cacheserve> resolver.statistics name=world

Page 14 Akamai Confidential


Operations I—Resource Use and Cache Performance DNSi CacheServe

♦ Which Resolver has the bigger cache size? Why?

internal: cache-memory-in-use =>


world: cache-memory-in-use =>

4. Fetch the object you just created to see that the Resolver currently has no options set.

cacheserve> resolver.get name=internal

5. Constrain the amount of memory CacheServe uses for the internal Resolver’s cache to
an artificially small size:

cacheserve> resolver.update max-cache-size=100m name=internal

cacheserve> resolver.get name=internal

This value is much smaller than the defaults in DNSi CacheServe 7 (1 GB).

6. Inspect the statistics output again:

cacheserve> resolver.statistics name=internal

Notice that the cache-memory-in-use statistics are gauges of current activity.


However, the maximum values of these gauges will not exceed the constraints defined
on the Resolver object.

Akamai Confidential Page 15


DNSi CacheServe Operations I—Resource Use and Cache
Performance

The resolver’s max-cache-size should be increased beyond 1 GB only if


quantitative performance measurements in your environment indicate it is

 beneficial.

The server’s max-recursive-contexts is limited internally to 250,000.


Increasing beyond this value will have no effect.

7. A breakdown of CPU usage is reported though the server.usage command:

cacheserve> server.usage

8. A program called cacheserve-stats can be used to get real-time statistics


information. Its output is generated by repeatedly executing the
server.statistics instruction, and displaying the difference in the counters over
1-second intervals.
Run this program to show data about client and auth server requests and responses:

# cacheserve-stats

A simplified version of this program is provided in the training environment to

 demonstrate the Nominum SDK. See the appendix “Installing the Python API”
for details.

9. The cacheserve-stats program can be invoked with --cpu (optionally with –o


all to output all fields) which displays the processor load due to UDP/TCP reception
and recursion activities rather than numbers of DNS requests/responses:
This monitoring provides insight to whether more concurrency units may be needed.

Page 16 Akamai Confidential


Operations I—Resource Use and Cache Performance DNSi CacheServe

# cacheserve-stats --cpu

10. In some circumstances, multiple Views are used to provide alternative policy behavior
(such as malicious domain redirection) but otherwise do not differ in their resolution of
DNS names.
For the purposes of this course, we will create a View which uses the “world” Resolver,
but exists solely to isolate an individual client which has behaved suspiciously in the
past:

cacheserve> view.add name=instructor resolver=world

11. Bind the “instructor” View to the instructor’s traffic generator source IP with a view-
selector.add command:

cacheserve> view-selector.add source-address=<instructor_IP> view=instructor

The instructor IP address is usually 10.128.0.4.

12. A benefit of using a shared Resolver is its shared cache for clients. Any customizations of
the Resolver object are also shared. Here is an example: to make DNSi CacheServe
return the loopback address for both IPv4 and IPv6, update the Resolver object as
follows:

cacheserve> resolver.update name=world preload+=((localhost AAAA ::1))

The instructor will verify that the behavior is correct for the “instructor” view.

13. Delete the instructor View:

cacheserve> view-selector.delete source-address=<instructor_IP>

cacheserve> view.delete name=instructor

Akamai Confidential Page 17


DNSi CacheServe Operations I—Resource Use and Cache
Performance

SUMMARY:
You have learned how memory is used and reported in CacheServe. Determining overall server
activity is facilitated by a script that fetches statistics periodically. You have added a view which
can hold policies specific to a particular user, without the inefficiency of a separate Resolver.

Page 18 Akamai Confidential


Operations II—Looking at a Resolver DNSi CacheServe

Lab 4: Operations II—Looking at a Resolver


OVERVIEW: In this section we concentrate on typical diagnostic tasks. Some of these include
showing the cache contents, flushing selected zones or resource record sets, and examining the
resolution process with the server.query command.

STEP-BY-STEP:
1. Active resolutions are visible with the recursing command:

cacheserve> resolver.recursing name=world

Under light load—such as in the training lab—repeated use of the command may be
needed to produce any output.

The recursing command can be used to help identify “Random

 Subdomain” attacks: a gibberish-looking first label appears prefixed to a


common apex for the vast majority of queries.

2. To determine the status of specific contents of the cache you can use the “inspect”
command channel instructions. Assuming the instructor has queried your server with a
traffic generator, you will almost certainly have an entry for www.google.com. Enter the
following command:

cacheserve> resolver.inspect name=world domain=www.google.com

If the records for the name have expired, the name will exist—however, the type
information will be absent.

♦ Does the output indicate what clients have requested this name?

♦ What result do you expect from resolver.inspect name=internal for this


domain?

3. Compare the result of searching the “world” Resolver cache for a never-queried name
such as www.giggle.com:

Akamai Confidential Page 19


DNSi CacheServe Operations II—Looking at a Resolver

cacheserve> resolver.inspect name=world domain=www.giggle.com

4. To delete all records throughout the domain google.com enter the following command:

cacheserve> resolver.flush name=world target=(domain google.com)

Check for entries in the flushed domain using inspect to confirm the operation:

cacheserve> resolver.inspect name=world domain=www.google.com

♦ What impact does this have for users of the “internal” Resolver?

5. To check the delegation cache, use the inspect-delegation command. For


example, to view the servers used in delegations for the domain com enter the
following:

cacheserve> resolver.inspect-delegation name=world domain=com

♦ What is the IP address of the fastest-responding nameserver for the com zone?

Now that we can look into the cache, the next question to explore is “How did data get
into the cache in the first place?”

server.query is a useful command for troubleshooting resolution problems by


emulating queries with various properties. The tool can be run with different cache
conditions and optionally shows the complete path taken by the server in its attempt to
resolve a name.

Page 20 Akamai Confidential


Operations II—Looking at a Resolver DNSi CacheServe

6. In its simplest form, server.query represents a sort of “built-in” interactive DNS


client—similar to having dig inside nom-tell(i.e. the command channel). That means
we can do things like lookup the A record for a query name localhost like this:

cacheserve> server.query qname=localhost

♦ What View and Resolver is used to lookup the result? Repeat. Is the result cached?

7. To simulate behavior of a query to the “world” View , add its name to the command:

cacheserve> server.query qname=localhost view=world

You should get the preloaded answer this time, rather than the natural Internet’s
answer.

Previously you saw that server.query resulted in the caching of the names it
fetches. Likewise server.query USES the appropriate Resolver’s cache to PROVIDE
responses. To suppress the use of the cache, server.query supports the force-
resolution option.

8. Look up the name localhost in the “internal” View again:

cacheserve> server.query qname=localhost force-resolution=1

♦ Repeat the command a few times. How can you tell the result is not from the cache?

9. Tracing mode allows the administrator to examine in detail what CacheServe does to
resolve names that cannot be found in the cache. The amount of detail can be
overwhelming as well as instructive, so we interpret a few simple examples to show
how it works:

Akamai Confidential Page 21


DNSi CacheServe Operations II—Looking at a Resolver

cacheserve> server.query qname=localhost tracing=1

The detailed result in the trace-messages field shows the receipt and processing of
the query.

10. If you repeat the command with force-resolution, you will find trace-
messages output that corresponds to the server’s query to the root servers:

cacheserve> server.query qname=localhost tracing=1 force-resolution=1

SUMMARY:
You have seen how to access and remove name and delegation information from the DNSi
CacheServe cache.

The server.query instruction can provide helpful diagnostic information, particularly when
combined with force-resolution.

Note that force-resolution does not completely start a resolution from scratch, as any
delegations that might exist can and will be used. To demonstrate the difference, flush the
“internal” resolver’s cache and execute the command again. You will find a new entry in the
trace, specifically: 'closest known zone cut is root hints'. This shows that from a completely fresh
start, the root name servers themselves must first be located from the built-in (or explicitly
defined) root hints.

Page 22 Akamai Confidential


Operations III—Using Policy to Deny Service DNSi CacheServe

Lab 5: Operations III—Using Policy to Deny Service


OVERVIEW: CacheServe supports a rich and powerful set of features called precision policies.
Here we introduce the CacheServe policy framework by showing how to deny service to
selected clients.

STEP-BY-STEP:
1. A simple example is used here to implement a kind of “black-hole” behavior where the
ignored clients are maintained on an address list. Create the list as shown here:

cacheserve> address-list.add name=blocked_clients

2. Add the instructor’s IP address (often 10.128.0.4) to the list of blocked clients:

cacheserve> address-node.add address=<instructor_IP> list=blocked_clients

3. Verify the list is populated as expected with one of these commands:

cacheserve> address-node.mget list=blocked_clients

cacheserve> address-node.mget

cacheserve> address-list.mget

To write the list of IP addresses in the blocked_clients list to disk, you can
use the command:

 cacheserve> address-list.dump name=blocked_clients

The list will appear in the file address-list.dump in the DNSi CacheServe
working directory, which is usually /var/nom/cacheserve.

Similar capabilities for load also exist.

Akamai Confidential Page 23


DNSi CacheServe Operations III—Using Policy to Deny
Service

4. Next, create a policy that drops all requests from a client if its IP address appears in the
blocked-clients list:

cacheserve> policy.add name=blackhole selector=(client-address blocked_clients )


action=drop

5. Bind the policy to the server:

cacheserve> binding.add policy=blackhole server=1 priority=50

6. Check whether the policy is enforced by using cacheserve-stats:

# cacheserve-stats

clnt clnt auth auth user sys total q/ recur

req/s resp/s req/s resp/s %cpu %cpu %cpu cpusec cntxs

------- ------- ------ ------ ----- ----- ----- ------- ------

19 0 0 0 0.0 0.4 0.4 - 0

In the display above, the instructor sends 19 queries. Note that none of them get a
response.

7. Other IP addresses can be included in the “blackhole” by adding them with the
Command Channel instruction:

cacheserve> address-node.add address=10.138.0.5 list=blocked_clients

8. You can check the policy’s behavior by requesting a “simulation” of a particular client:

Page 24 Akamai Confidential


Operations III—Using Policy to Deny Service DNSi CacheServe

cacheserve> server.query view=world client-address=10.138.0.5 qname=foo

9. Remove the instructor’s IP address from the address list:

cacheserve> address-node.delete address=<instructor_IP> list=blocked_clients

Removing the instructor IP address leaves the policy (and its binding) in place.

 A policy that is conditioned on an “address list”, or a “name-list” is isolated from


these deletions and additions. Only the lists need adjustment when targets of the
policy change.

SUMMARY:
Client blacklisting can be implemented with the help of the policy engine in CacheServe.

Akamai Confidential Page 25


DNSi CacheServe Operations IV—Events, SNMP, and
basic “rate-limiting”

Lab 6: Operations IV—Events, SNMP, and basic “rate-limiting”


OVERVIEW: CacheServe events are used to monitor server activities such as resource
consumption, configuration changes, and startup/shutdown. The event messages sent by
CacheServe can be processed by any application that can send and receive Command Channel
instructions. CacheServe ships with a program called SNMPagent that opens a connection for
event messages and relays them as traps to an SNMP management application.

STEP-BY-STEP:
1. In the previous exercises we have used nom-tell in interactive mode as a
convenience. Here, we are required to use interactive mode so that messages sent by
CacheServe will have a destination (your terminal). If you have not already done so,
establish a Command Channel connection with your running DNSi CacheServe instance:

# nom-tell cacheserve

2. From the cacheserve prompt, request the Connection object. It represents the
current TCP session that nom-tell uses to communicate with your CacheServe
instance:

cacheserve> connection.get

The event list for every new Connection will be empty.

3. Register for all possible events by using the special subscribe-all instruction:

cacheserve> connection.subscribe-all

4. Check that your instance of nom-tell now displays the complete list of possible
events in its events field:

Page 26 Akamai Confidential


Operations IV—Events, SNMP, and basic “rate-limiting” DNSi
CacheServe

cacheserve> connection.get

5. From another terminal window, send the DNSi CacheServe server the command to
delete the entire cache:

# nom-tell cacheserve resolver.flush name=world

The event called resolver.flush should instantly appear at the cacheserve


prompt.

To make DNSi CacheServe events more useful, they can be relayed to an SNMP
tool by a standalone application called snmpagent. The use of snmpagent is

 illustrated in the next section. We assume that an application capable of


capturing and displaying SNMP traps is available in the lab. In instructor-led
sessions, this will reside on the instructor’s machine.

6. Install the snmpagent package that is included in the DNSi CacheServe distribution. In
most classroom environments this will already have been done.

7. Edit/create the file /etc/snmpagent.conf to include the following directives:

masteragent

driver cacheserve cacheserve

8. Next, edit/create a file called /var/nom/snmpagent/snmpagent_master.conf


with the following contents. Your instructor will provide you with an IP address to which
SNMP traps can be sent (usually it’s the instructor IP address). Substitute that IP address
for <IP_addr_of_trap_receiver> in the text below:

Akamai Confidential Page 27


DNSi CacheServe Operations IV—Events, SNMP, and
basic “rate-limiting”

trap2sink <IP_addr_of_trap_receiver>

9. Start the agent application with the following command line:

# systemctl start snmpagent

10. Send the resolver flush command again.

# nom-tell cacheserve resolver.flush name=world

You will see a trap appears in the management tool.

Follow your vendor’s instructions to configure your SNMP application with the
Nominum and DNSi CacheServe MIBs (included in the


/usr/local/nom/share/snmp/mibs directory). Then, the management
application will display descriptive information about events it has recorded.

The appendix illustrates the use of standard SNMP utilities to fetch various
statistics, as well as the structure of some of the SNMP objects available.

11. We conclude the exercise by showing an example of a customized event: notification of


a rate-limiting detection. For illustration we configure “per client rate-limiting” to a
small (2 queries per second) value in order to trigger the ratelimiter.onset
event.
Add the following ratelimiter object to the CacheServe configuration:

cacheserve> ratelimiter.add name=first qps=2 fields=((client-network (32 128)))

Page 28 Akamai Confidential


Operations IV—Events, SNMP, and basic “rate-limiting” DNSi
CacheServe

12. By itself, the ratelimiter only establishes that statistics be collected according to the
specified rule. In this case, “client-network” mask values of 32 and 128 mean that each
client is tracked individually.
Current values can be fetched at any time, but you will see that currently the ratelimiter
has no “uses”:

cacheserve> ratelimiter.statistics name=first all=true

 Setting all=true displays all statistics, even those that have zero counts.

13. Create a policy which truncates the responses when the rate is higher than the
threshold:

cacheserve> policy.add name=client_ratelimit selector=(ratelimiter first) action=truncate

14. Bind the ratelimiter to the “world” view:

cacheserve> binding.add policy=client_ratelimit view=world priority=100

15. Ask the instructor to send a stream of traffic that exceeds the threshold specified in the
previous step (for example, 4 QPS). Depending on the rate, after a few seconds you
should receive an event similar to the following:

Akamai Confidential Page 29


DNSi CacheServe Operations IV—Events, SNMP, and
basic “rate-limiting”

event:

type => 'ratelimiter.onset'

name => 'first'

creation-time => '1402963746.733898'

qps => '2'

unenforced => 'false'

client-network-family => 'ipv4'

client-network-mask-length => '32'

client-network => '10.128.0.4'

fields => ('client-network')

entry-creation-time => '1402963746.915183'

last-limited-time => '1402963749.729018'

last-use-time => '1402963749.729018'

For queries in excess of the threshold, CacheServe sends truncated responses to this
client.

16. If you were not receiving the events corresponding to rate limiting, you could probe the
ratelimiter for abusive clients with the following command:

cacheserve> ratelimiter.limited name=first

17. Check the statistics again for your ratelimiter:

cacheserve> ratelimiter.statistics name=first all=1

You should find the number of “indications” increases at the rate of excess queries.

Page 30 Akamai Confidential


Operations IV—Events, SNMP, and basic “rate-limiting” DNSi
CacheServe

18. To help understand how the statistics are interpreted, adjust the ratelimiter’s threshold
to a high value, say 10, so the instructor’s traffic no longer exceeds it:

cacheserve> ratelimiter.update qps=10 name=first

A ratelimiter.abate event appears since tracking according to the original


ratelimiter stops.

19. Check the statistics again. Not only should you find they are reset, but the number of
indications should remain zero:

cacheserve> ratelimiter.statistics name=first all=1

type => 'ratelimiter.statistics'

name => 'first'

creation-time => '1405814323.680414'

reset-time => '1405814323.690262'

current-time => '1405815062.996065'

server-start-time => '1405807997.709197'

user-time => '12.474103'

system-time => '6.167062'

memory-in-use => '54934104'

statistics => {

uses => '226'

all-indications => '0'

indications-by-qps => '0'

indications-by-bps => '0'

expiring-entry-age => '0'

current-entry-count => '2'

current-limited-count => '0'

Akamai Confidential Page 31


DNSi CacheServe Operations IV—Events, SNMP, and
basic “rate-limiting”

A general problem with setting thresholds of any kind is determining what a “normal”
rate is without disrupting legitimate service. The next step shows how to do this.

20. If monitoring of high-query rate clients—without truncation—is desired, use a


“unenforced=true” in the ratelimiter definition. This has the effect of sending events
when clients exceed the threshold, but does not actually affect queries.

cacheserve> ratelimiter.update name=first unenforced=true qps=2

After making this change, confirm a query excess is reported by an event (or ratelimiter
statistics).

However, in this (unenforced) mode, the server answers queries normally. Inspection of
the RTV querystore, which we introduce in another exercise, allows you to prove this.

SUMMARY:
You have seen how to subscribe to events and configure the Nominum SNMP Agent to relay
Command Channel data to an SNMP tool. The rate-limiting feature can be enabled to truncate
DNSi CacheServe’s responses to those clients with very high query rates. The rate-limiting
apparatus demonstrated in this exercise is somewhat “blunt”. A more surgical approach is
described later.

Real Time Alerts is a DNSi CacheServe feature which permits thresholds to be

 established on arbitrary conditions, providing a flexible mechanism for alerting on


significant rate changes independent of policy enforcement.

Page 32 Akamai Confidential


Increasing Resistance to Cache Poisoning DNSi CacheServe

Lab 7: Increasing Resistance to Cache Poisoning


OVERVIEW: Understanding the costs and benefits of applying various “security” measures to an
intrinsically insecure service like DNS is the subject of this lab. You will learn to control query
source port randomization (QSPR) and query-name case randomization (sometimes called
0x20), two DNSi CacheServe features which reduce the probability for successful cache
poisoning using common spoofing attacks.

STEP-BY-STEP:

Query Source Port Randomization


1. QSPR is active by default, but the number of source ports used varies by platform. Check
the source ports used by your DNSi CacheServe server with the following command:

# lsof -p <PID_of_Cacheserve> | grep UDP | cut -f2 -d:| sort -u

♦ How many source ports are open on your instance of DNSi CacheServe?

2. Using more source ports than the default will reduce the probability of a given spoofing
attack succeeding but doing so requires more file descriptors.
Your IP address will probably be different. The #0 tells DNSi CacheServe to choose any
ports:

cacheserve> resolver.update query-source-pool=(2048 10.138.0.6#0) name=world

3. Again use “lsof” to find the number of source ports for DNSi CacheServe now that it has
the new resolver configuration. NOTE THE PID SHOULD BE THE SAME AS BEFORE:

# lsof -p <PID_of_Cacheserve> | grep UDP | cut -f2 -d:| wc -l

♦ How many source ports are open on your CacheServe now?

Akamai Confidential Page 33


DNSi CacheServe Increasing Resistance to Cache
Poisoning

4. It can be useful to log information about possible spoofing attacks. Enable the log-
id-spoofing resolver configuration statement:

cacheserve> resolver.update name=world log-id-spoofing=true

This information allows you to know which domain is being attacked.

Query Name Case Randomization


DNSi CacheServe can be configured to send DNS requests to authoritative servers with
mixed case. By default all queries are sent lower-case; by sending mixed-case requests
to authorities, the format of the responses may identify spoofing attempts.

5. Several different behaviors are configurable. The unenforced option tells CacheServe
to send mixed-case, and then log a message if the corresponding response does not
match:

cacheserve> resolver.update qname-case-randomization=unenforced name=world

6. To make sure that CacheServe sends new (mixed-case) lookups to the authorities, and
does not simply answer from its cache, flush the resolver’s cache with:

cacheserve> resolver.flush name=world

7. Examine your syslog and look for case mismatches. For example, you might find
something like this:

info: case mismatch in response from 63.236.2.231 (wWw.89.com.)

8. Pick one of these, and use dig to verify directly for yourself that a query to that
nameserver does not echo the original query case. For the example we have chosen:

Page 34 Akamai Confidential


Increasing Resistance to Cache Poisoning DNSi CacheServe

# dig +qr @63.236.2.231 wWW.89.CoM

Here, dig’s +qr flag causes the outgoing DNS request to be printed.

9. To understand how CacheServe provides a defense against possible spoofing, change


the resolver to enforced mode:

cacheserve> resolver.update qname-case-randomization=enforced name=world

10. You saw the offending authoritative server fails to preserve case, so we now want to see
how DNSi CacheServe responds when you ask it to resolve a mis-matched name when it
enforces case matching. Check the response, being sure your query hits the correct
resolver:

# dig @<your-IP-addresss> www.89.com

Notice that DNSi CacheServe resolves the name. However, behind the scenes, it has
looked up the name using TCP to avoid falling victim to a potential UDP spoofing
attempt.

The DNS queries to the authorities can be captured by configuring an


“Authoritative Querystore” with the auth-monitoring CacheServe object. Not only
are the mis-matched responses captured (and identified with the SPOOFING-

 SUSPECTED flag), but the subsequent TCP communication to defend against a


potential intrusion is also recorded.

More on the use of the Authoritative Querystore (also called Authoritative RTV)
later.

Akamai Confidential Page 35


DNSi CacheServe Increasing Resistance to Cache
Poisoning

11. To work around deficient authoritative servers, you can place problem domains in a kind
of whitelist called qname-case-randomization-exclusions. It is especially
useful because some domains have nameservers that do not respond at all to mixed
case queries:

cacheserve> resolver.update qname-case-randomization-exclusions=89.com name=world

Try another query for the problem domain. CacheServe resolves it, but no mismatch is
logged.

 Use the silent-enforced mode to suppress all logging of case-mismatch.

SUMMARY:
DNSi CacheServe offers several kinds of defenses against spoofing. By increasing the number of
source ports, the likelihood of a spoof succeeding is made smaller, at the cost of additional
machine resources. By randomizing the case of lookups sent to authoritative servers (and
requiring that responses match the randomized case), an attacker’s job is made even more
difficult, but this method has drawbacks because some authorities do not reply (at all) to mixed-
case requests. An exclusions list can be used to suppress mixed-case requests for domains
sending using those servers.

Page 36 Akamai Confidential


DNSSEC support with Managed Keys DNSi CacheServe

Lab 8: DNSSEC support with Managed Keys


OVERVIEW: DNSSEC is based on the ability of a DNS resolving server (such as CacheServe) to
cryptographically verify that data it obtains originates, and arrives unaltered, from zones
published by the correct authoritative servers. In this exercise we learn how to use DNSi
CacheServe’s managed-keys (also known as RFC 5011) for DNSSEC support, using the built-in
root zone’s public key.

STEP-BY-STEP:
1. Use dig +dnssec to demonstrate that validation is not offered by default, and
DNSSEC records are not returned by DNSi CacheServe without further configuration:

# dig @127.1 +dnssec gov

# dig @127.1 +dnssec fbi.gov

♦ What records (types) appear in the responses?

If your response has the flag “ad” set, your DNSi CacheServe instance has

 validated the authoritative server’s data. With DNSi CacheServe’s default


configuration, we do not expect to find this flag.

2. Look in the “internal” view’s cache (in the “internal” resolver) at the content for these
two names:

cacheserve> resolver.inspect name=internal domain=gov

cacheserve> resolver.inspect name=internal domain=fbi.gov

Note the absence of a “trust” field, which would have been populated if DNSSEC were
enabled.

Akamai Confidential Page 37


DNSi CacheServe DNSSEC support with Managed Keys

3. Next we enable DNSSEC processing (but without providing any keys, which are required
for validation):

cacheserve> resolver.update name=internal dnssec-aware=true

4. Note the cache has been cleared as a result of DNSSEC “awareness”:

cacheserve> resolver.inspect name=internal domain=gov

type => 'resolver.inspect'

err => 'domain not found'

cacheserve> resolver.inspect name=internal domain=fbi.gov

type => 'resolver.inspect'

err => 'domain not found'

5. Repeat queries to the domains used previously and note the difference in the response:

# dig @127.1 +dnssec gov

# dig @127.1 +dnssec fbi.gov

♦ What records (types) appear in the responses now? Does the cache show the trust
field?

Page 38 Akamai Confidential


DNSSEC support with Managed Keys DNSi CacheServe

Enabling DNSSEC with DNSi CacheServe’s dnssec-aware instruction increases


the amount of information requested and stored by DNSi CacheServe, but is not


sufficient to actually validate any data.

To perform validation, DNSi CacheServe needs trusted data in the form of a public
key to be configured via an out-of-band (that is, non-DNS) mechanism. For
CacheServe, that mechanism is to compile the current root zone key in the binary.

6. CacheServe has a built-in root-zone public key. To activate validation, set the managed –
key field for the resolver as shown in the following:

cacheserve> resolver.update name=internal managed-keys=(('.' ( ) ))

7. Get the “internal” resolver:

cacheserve> resolver.get name=internal

Verify the root key, and its state, now appears in the managed-keys field.

The hash of the root zone’s public key is available from the IANA site. If you want
 to confirm that the built-in public key CacheServe used is legitimate, compute the
hash of the key and compare it to trusted data.

8. Try to resolve fbi.gov and gov again:

# dig @127.1 +dnssec gov

# dig @127.1 +dnssec fbi.gov

Akamai Confidential Page 39


DNSi CacheServe DNSSEC support with Managed Keys

♦ Does dig report that DNSi CacheServe provides a validated answer now? Does DNSi
CacheServe’s cache?

♦ Use resolver.get to determine the next time this key will be checked for
changes. What is the frequency of checks to the root server?

To remove all managed keys, update the resolver with unset=managed-keys


.

 To remove a managed-key for a single domain, use CacheServe’s incremental


syntax (managed-keys-=) to delete that element of the managed key field
corresponding to the domain you wish to remove.

9. If a domain should be excluded from DNSSEC verification, use a “negative” trust anchor:

cacheserve> resolver.update negative-trust-anchors+=(irs.gov) name=internal

 A negative trust anchor has the same effect as removing the DS record from the
parent zone.

SUMMARY:
Now that the root zone is signed, the best approach for providing DNSSEC support is to
configure managed-keys, which provide for automated public key maintenance via RFC 5011.

Troubleshooting can be aided by enabling the DNSi CacheServe resolver statement “log-dnssec”.

It is not necessary to use the built-in root key. Arbitrary managed keys can be configured with:
resolver.update managed-keys=(('example' ('257 3 8 AwEagAIKl...')

Page 40 Akamai Confidential


Understanding “Real Time Visibility” DNSi CacheServe

Lab 9: Understanding “Real Time Visibility”


OVERVIEW: In this exercise we learn how to enable Real Time Visibility (RTV) for flexible query
analysis that goes beyond the capabilities of DNSi CacheServe’s built-in analysis functions.

Real Time Visibility is not configured by default. The tools described in this section can only be
used after changing DNSi CacheServe’s monitoring object to activate storage and begin data
acquisition to a querystore.

DNSi CacheServe’s querystore is an on-disk archive of all queries with corresponding result
codes. DNSi CacheServe’s statistics monitor service provides a set of command-channel
instructions to retrieve information from the store, such as filtering by various criteria, or
determining the top N most active clients or domains, where N and the time period within the
store can be user-specified.

Automated data processing with RTV frequently involves periodic fetches using the same search
again and again. In some of these cases the searches may be computationally intensive, so DNSi
CacheServe provides “reports”: a mechanism for analyzing data as it accrues in the
querystore.

To collect Real Time Visibility information, send instructions to a repository called


 the querystore through an independent “monitor service” called statmon.
The process name is cacheserve-statmon.

STEP-BY-STEP:
1. With a new installation, the statmon service is by default not running. We start it
here:

# systemctl start statmon

2. Upon startup you should see the process listed:

# ps –ef | grep statmon

root 4177 1 0 13:43 ? 00:00:00 statmon: running

Akamai Confidential Page 41


DNSi CacheServe Understanding “Real Time Visibility”

 If you use neither RTV nor RTA, you need neither the statmon service nor its
cacheserve-statmon process.

3. Check whether monitoring is enabled with the following command:

cacheserve> monitoring.get

If an empty configuration for the monitoring object appears, Real Time Visibility is not
enabled.

4. To avoid resource exhaustion, Real Time Visibility works with a finite amount of space
dedicated to query analysis. As an example, suppose we wanted to maintain only the
most recent 5 minutes of traffic and allow the file to grow to be no more than 100 MB in
size. The following command sets up the querystore to those specifications:

cacheserve> monitoring.update querystore={duration=300 max-size=100M}

If a location is otherwise unspecified, the querystore will be created under the

 directory /var/nom/statmon, with default duration of 1 day and unlimited


maximum size. The DNSi CacheServe man page (cacheserve(8)) describes
monitoring configuration under the documentation for the monitoring object.

5. Now that you have established an active repository of data in the querystore, it can
be queried with an instruction to the monitor process (not to the DNSi CacheServe
instance itself). Notice here a new nom-tell session is opened to the service called
statmon.

Page 42 Akamai Confidential


Understanding “Real Time Visibility” DNSi CacheServe

# nom-tell statmon

statmon> querystore.status

type => 'querystore.status'

configuration => {

duration => '300'

max-size => '104857600'

size => '0'

first-query => '0'

last-query => '0'

6. The instructor will send a stream of DNS traffic to your DNSi CacheServe server, which is
now collecting data with RTV. Use cacheserve-stats or similar to verify traffic is
appearing at your server.

RTV is perhaps most useful when accessed through the Command Channel API

 rather than over nom_tell. Some examples included in the file


cacheserve_perl.tar show how to access the querystore
programmatically.

For more information, see the Exercises which cover the Perl API.

7. With our first example we retrieve the count or total number of queries that have been
recorded in the querystore This number represents the number of DNS requests

statmon> querystore.count

type => 'querystore.count'

count => '936'

received since monitoring was enabled.

Akamai Confidential Page 43


DNSi CacheServe Understanding “Real Time Visibility”

8. Next, fetch the derived rate of queries per second over that time:

statmon> querystore.qps

type => 'querystore.qps'

qps => '9.935'

9. The user can constrain the time period to consider when determining the number or
rate of queries. The first way to do this uses the duration tag. The following
command gets the numbers of queries in the most recent 5 second interval:

statmon> querystore.count duration=5

If the traffic stream to your server has stopped, you will find zero (0) counts.

10. To find the number of queries occurring in a specific period of time delimited by two
dates, use the interval tag. Here we count the number of queries between 1:30pm
and 1:33pm (local time of the server, which in our lab is often UTC) on September 28,
2020:

statmon> querystore.count interval=(2020-09-28:13:30:00, 2020-09-28:13:33:00)

It is not an error to describe the time interval with endpoints outside the window

 of the active querystore. In such a case, a request for the query count would
simply return zero. Adjust the date/time shown above to extract data for an
interval appropriate for your querystore.

11. The most frequently requested domains in the querystore can be returned with the
following command:

Page 44 Akamai Confidential


Understanding “Real Time Visibility” DNSi CacheServe

statmon> querystore.top-domains

By default, the 20 most-queried domains are returned. In the next step we modify this
quantity.

The DNSi CacheServe querystore man page (statmon_querystore) describes


the search commands that can be sent to the statmon service. Of interest for

 statistical analysis are:


querystore.count querystore.qps
querystore.top-clients querystore.top-domains
querystore.group-count querystore.group-count-size

12. To restrict the output to just the top 10 domains, use the max-results tag.

statmon> querystore.top-domains max-results=10

13. All data related to individual queries collected in the querystore can be listed
through the statistics monitor. This capability is called replay and the example below
shows how to display every query in the current querystore:

statmon> querystore.replay

 Qualifiers such as interval or duration (with or without an explicit end


argument) SHOULD ALWAYS be used with replay.

Akamai Confidential Page 45


DNSi CacheServe Understanding “Real Time Visibility”

14. The results of any search can be constrained by almost any criteria included in DNS
messages. A query filter is a list of rules. As soon as one rule decides that a query should
be filtered out, filtering stops and the query is dropped. Therefore to pass through the
filter a query must pass all rules. The following examples will attempt to show some of
the capabilities:

statmon> querystore.top-clients filter=()

This filter is a null operation. No queries are dropped because none match a rule.

A list of rules can be found in the man page or PDF documentation. When using

 nom_tell, have the monitor provide a list of criteria by using the “tab” key to
display valid syntax, or specify an invalid filter such as filter=(( )).

15. Suppose we wish to get the number of queries for the arpa domain (and all its
subdomains):

statmon> querystore.count filter=((domain (true (arpa))))

If you want to find the number of queries to names outside the arpa domain we can
reverse the logic by setting the filter condition to false:

statmon> querystore.count filter=((domain (false (arpa))))

An additional rule can select the type of query (eg PTR): as described above, the second
rule is treated as a logical “and”:

Page 46 Akamai Confidential


Understanding “Real Time Visibility” DNSi CacheServe

statmon> querystore.count filter=((domain (true (arpa))) (client-network (true ((netblock


10.128.0.0/9)) )))

16. Logical “or” can be implemented within a single property of a filter as in this example,
which searches for queries in the arpa domain or the com domain:

statmon> querystore.count filter=((domain (true (arpa com) )))

17. A powerful way of “sorting” the data in the querystore uses the “group-count”
commands.
Suppose we wanted to know how many clients were sending traffic to this querystore.
While it is possible to generate “top-clients” requests until the maximum number does
not change, it is more practical to use the group-count and group-count-size
commands:

statmon> querystore.group-count group-by=client-address

statmon> querystore.group-count-size group-by=client-address

The group-count-size gives the raw number of UNIQUE client-addresses, while the
group-count enumerates each one and provides a count of queries each is responsible
for.

In a production environment, queries for random subdomains of legitimate zones are


commonly used for denial of service attacks. For example, requests for
lhkdrt5sj9d.google.com and other variations of the first label might appear in vast
numbers. Besides the impact on both authoritative and caching servers, these attacks
present difficulties for analysis with statmon as well.

18. To characterize the DNS data found in the querystore, it can be useful to introduce the
“core domain” concept of a domain name. The core domain is an “effective top-level
domain” plus one label:

Akamai Confidential Page 47


DNSi CacheServe Understanding “Real Time Visibility”

statmon> querystore.group-count group-by=core-domain

The core-domain treats all queries of the form <any-label>.google.com as if they were
for the same name, google.com. This of course means that in this sorting,
www.google.com and google.com are counted as the same name.

19. Suppose we need to know the number of queries to the domain netflix.com (which of
course includes both www.netflix.com and netflix.com) in a 100-second window. The
command which searches the archive for these requests is:

statmon> querystore.count filter=((domain (true (netflix.com)))) duration=100

If the same data must be collected for consecutive windows, over an indefinite period of
time, it can be useful to create a DNSi CacheServe “report”:

statmon> report.add search=(count {filter=((domain (true (netflix.com))))}) name=netflix


interval=100

 The DNSi CacheServe Report man page (statmon_report(5)) describes the


report module.

20. Examine the results of your report definition:

Page 48 Akamai Confidential


Understanding “Real Time Visibility” DNSi CacheServe

statmon> report.mget

type => 'report.mget'

search => (

'count'

filter => (('domain' ('true' ('netflix.com'))))

name => 'netflix'

interval => '100'

status => (

start => '1331327547'

status => 'complete'

query-count => '50'

dropped-queries => '0'

memory-used => '0'

start => '1331327647'

status => 'in-progress'

query-count => '29'

dropped-queries => '0'

memory-used => '0'

Note query-count displayed here is the total number of queries processed.

21. To get the number of counts that matched the filter, you must retrieve the value by
indicating the specific start time of the interval of interest:

statmon> report.retrieve name=netflix start=1331327647

Akamai Confidential Page 49


DNSi CacheServe Understanding “Real Time Visibility”

The amount of memory devoted to reports can be clamped with the DNSi CacheServe
monitoring object’s report-max-memory configuration.

22. To record the CacheServe responses in addition to the queries, modify the monitoring
object by adding include-answers=1 in the list of its properties:

cacheserve> monitoring.update include-answers=true

Verify with a replay command that your querystore now contains responses.

23. If long term storage of querystore data in text format is required, a dumper utility is
available:

# statmon_export

This utility accepts nxd as one of its output formats:


statmon_export -f nxd

This causes the log to be output in the Nominum “nxdomain log” format:

 1248460354.000 127.0.0.1#49303 fladfrwe.com IN A com

Note that the msecs field of the time value will always be zero.

Another option, -N (or --nxdomain), outputs only queries with an rcode of


NXDOMAIN. Combined with the formatting described above, this can be used to
quickly generate a log file for use by the legacy utility vantio_nxr_analyze.

SUMMARY:
The statistics monitor (statmon) process can record query information to a local querystore.
This allows analysis after the data is collected, or with the help of “reports”, real-time analysis

Page 50 Akamai Confidential


Threshold Monitoring with “Real Time Alerts” DNSi CacheServe

Lab 10: Threshold Monitoring with “Real Time Alerts”


OVERVIEW: In this exercise we learn how to use automated query analysis to asynchronously
notify (“alert”) on DNSi CacheServe’s DNS traffic increases. We can apply threshold tracking to
the total query rate or to specific query attributes.

STEP-BY-STEP:
1. A simple use of Real Time Alerts is alerting if the total query rate received by the server
exceeds a given value, as demonstrated with the following:

cacheserve> monitoring.update querythreshold=((total {id=server_qps action=log


threshold=(15 10 5) } ))

The keyword “total” in the above declaration causes DNSi CacheServe to watch all
server traffic.

The DNSi CacheServe threshold is defined by three values: “duration” (in

 seconds), its “onset” (in queries per second) and “abate” (also in queries per
second).

2. Check that the querythreshold defined in the previous step is configured:

cacheserve> monitoring.get

3. You can retrieve live statistics on all thresholds with the


querythreshold.statistics command-channel instruction:

statmon> querythreshold.statistics

Akamai Confidential Page 51


DNSi CacheServe Threshold Monitoring with “Real Time
Alerts”

The CacheServe Query Threshold man page

 (statmon_querythreshold(5)) describes the commands that can be sent


to the statmon service which are related to this feature.

4. The instructor will send a traffic stream which exceeds the threshold of 10 queries per
second over a 15-second duration. Verify that your system issues a log message similar
to the following:

Sep 22 16:21:11 localhost statmon[27403]: info: query/threshold: total (server_qps):


duration 15 onset 10 abate 5 current 12 active 1 source base

When the rate drops below 5 qps, another message (containing “active 0”) will
appear.

Note that when you configure a querythreshold filter in DNSi CacheServe, it

 will not affect what the monitoring writes to its querystore repository, or
what it returns to search requests.

5. In the next example, we are interested to know when any single name is queried more
than 5 times per second. This is accomplished by declaring that we wish to track the
“name” attribute, but do not specify any particular target domain name:
DNSi CacheServe tracks rates of all unique names during the most recent 15-second
window.

cacheserve> monitoring.update querythreshold+=((name { id=test_2 action=log threshold=(15


5 2) } ))

6. Look again at the statistics through statmon:

Page 52 Akamai Confidential


Threshold Monitoring with “Real Time Alerts” DNSi CacheServe

statmon> querythreshold.statistics

♦ What statistics appear?

7. As the previous question suggests, querythreshold.statistics returns data


only for explicitly configured targets. To display all names currently in the test_2
tracker, use the all=true tag:

statmon> querythreshold.statistics all=true

Setting all to true can make this command slow and memory-intensive, and it

 may fail if the number of targets is so great that the message exceeds command-
channel size limits.

8. If only the query rate for a specific name is of interest, add a target qualifier as shown
here:

cacheserve> monitoring.update querythreshold+=(( name { id=test_3 action=log


threshold=(15 5 2) target=www.google.com } ))

9. It can be more practical to express thresholds as ratios rather than absolute query rates.
In this example, we configure an alert which fires when the fraction of queries to any
view is more than 70% of the total server queries:

cacheserve> monitoring.update querythreshold+=(( view { id=view_thrash action=log


threshold-percentage=(20 70 30 server_qps)} ))

10. Besides log messages, threshold crossings can also generate events. Examine the events
supported by the statistics monitor with the list-events instruction:

Akamai Confidential Page 53


DNSi CacheServe Threshold Monitoring with “Real Time
Alerts”

statmon> list-events

 The variety of statmon events is significantly less than those supported in the
DNSi CacheServe Base Server itself.

11. Subscribe to the query/threshold event in nom_tell:

statmon> request-events events=(query/threshold)

12. Verify that your instance of nom-tell is configured to receive querythreshold


events:

statmon> show-events

13. Here is an example of adding another targeted name with a filter, which restricts the
trigger to NS queries:

cacheserve> monitoring.update querythreshold+=(( name {target=nominum.com threshold=(15 5


2) action=log-and-event id=nom-ns filter=((query-type(true (ns))))} ))

SUMMARY:
Real Time Alerts can be used to trigger an event when a query rate (for a particular type of
query or the queries as a whole) exceeds a configured threshold. These events, like other DNSi

Page 54 Akamai Confidential


Threshold Monitoring with “Real Time Alerts” DNSi CacheServe

CacheServe events, can be processed by the SNMP agent and sent to a network management
tool.

To configure SNMP traps corresponding to RTA activity, add the line indicated in
bold below to the /etc/snmpagent.conf file:

 masteragent
driver cacheserve cacheserve
driver cacheserve-statmon cacheserve-statmon

Akamai Confidential Page 55


DNSi CacheServe Offline access to the CacheServe
configuration Database

Lab 11: Offline access to the CacheServe configuration Database


OVERVIEW: Here we gain experience configuring DNSi CacheServe by using the database utilities
such as cacheserve-editconf. We also learn how to use these tools to access the
configuration database when the DNSi CacheServe server is not running. Entirely new databases
can be created and modified with these tools.

STEP-BY-STEP:
1. We can read the Server’s (as well as Resolvers’ and Views’) configuration with the
database utility cacheserve-dumpconf as shown with these commands:

# cacheserve-dumpconf –-object-type server

# cacheserve-dumpconf --object-type resolver --name world

# cacheserve-dumpconf –-object-type resolver --list-all

2. In addition to displaying the current contents of these objects, we can edit them as well
with the cacheserve-editconf tool. For practice, change one of the server’s
listeners:
a. Run cacheserve-editconf against the server object:

# cacheserve-editconf --object-type server

b. The configuration will appear in your environment’s default text editor (usually
vi). Use the text editor to remove or modify a listen-on-matching value.
c. Write and save the file.
d. Check that the change succeeded by again dumping the server configuration:

# cacheserve-dumpconf –-object-type server

Page 56 Akamai Confidential


Offline access to the CacheServe configuration Database DNSi
CacheServe

The tools demonstrated above provide access to information that could have
been read (or written) with nom-tell or other command channel client, and

 so requires DNSi CacheServe is running.

More commonly, these tools are used with DNSi CacheServe stopped. We will
learn next that they can access the database files directly.

3. Stop DNSi CacheServe.


4. Suppose we need to change the number of recursion contexts to 150 while CacheServe
is shutdown. Do the following:
a. Run cacheserve-editconf with the –c argument to specify the database
path and base name:

# cacheserve-editconf –c /var/nom/cacheserve/cacheserve --object-type server

If you attempt to use this tool while DNSi CacheServe is running, you will get an

 error such as this:


/var/nom/cacheserve/cacheserve.vdb2/lock: cannot lock database: in
use

b. Add (or edit) a max-recursive-clients entry, setting it to 150 as shown


below in bold:

Akamai Confidential Page 57


DNSi CacheServe Offline access to the CacheServe
configuration Database

max-recursive-clients => 150

listen-on-matching => (

patterns => ("127.0.0.1/32")

patterns => ("10.0.128.0/9" "fe80::4001:0:0:0/80")

c. Save the file and quit the editor.


d. Dump the configuration and verify server’s setting for max-recursive-
clients:

# cacheserve-dumpconf --all –c /var/nom/cacheserve/cacheserve

SUMMARY:
The database utilities allow text editor-based configuration when DNSi CacheServe is running or
stopped. cacheserve-loadconf can even be used to create a new database from a text
input file with the command cacheserve-loadconf --object-type server -c
/tmp/new_cacheserve_database_directory_name <infile>.

Page 58 Akamai Confidential


Troubleshooting snmpagent with CacheServe DNSi CacheServe

Lab 12: Troubleshooting snmpagent with CacheServe


OVERVIEW: Tips for troubleshooting data communication between the components of an SNMP
system.

STEP-BY-STEP:
1. In the previous exercise you created the Akamai configuration file for the snmpagent
application. By default, snmpagent will use the configuration it finds in
/etc/snmpagent.conf. It is usually easiest to run it as the master agent, as shown
here:

masteragent

driver cacheserve cacheserve

The default configuration file for the snmpagent application is


/etc/snmpagent.conf. Like all Akamai DNSi products, the snmpagent

 can be customized—to modify, for example, the location of the configuration


file—by applying changes through
/usr/local/nom/etc/sysconfig/snmpagent

2. To show the status of the Agent, use a command channel client such as nom-tell:

# nom-tell snmpagent show-agent

3. The status of drivers can be fetched over the command channel also:

Akamai Confidential Page 59


DNSi CacheServe Troubleshooting snmpagent with
CacheServe

# nom-tell snmpagent show-drivers

4. To aid in troubleshooting of the Agent, it may be useful to enable logging. By default


snmpagent logs none of the following classes of actions:
a. command/executed, command/unknown
b. snmp/get, snmp/set, snmp/trap, snmp/status
c. cacheserve/event
To enable logging of, say, CacheServe events and SNMP GETs, add the lines in bold to
the /etc/snmpagent.conf file:

masteragent

driver cacheserve cacheserve

log cacheserve/event yes

log snmp/get yes

5. SNMP-specific configuration is applied through the


/var/nom/snmpagent/snmpagent_master.conf file. This file uses a format
described in various documentation sources, such as that found at http://www.net-
snmp.org. A simple configuration which creates users might look like this:

trap2sink 10.128.0.4

rocommunity public

rwcommunity private

Add the community configuration elements to the snmpagent_master.conf file,


then restart snmpagent to enable the changes.


Note that the Agent supports only version SNMP 2c, not SNMP 3.

For this reason, we define access by community strings, not users.

Page 60 Akamai Confidential


Troubleshooting snmpagent with CacheServe DNSi CacheServe

6. We are now ready to collect information from the SNMP Agent. Using an SNMP tool
such as one of those included in /usr/local/nom/bin, we can test GET access:

# /usr/local/nom/bin/snmpwalk -v2c -c public 127.0.0.1 1.3.6.1.4.1.5901.4.16.1.1.2

The result should include configured resolvers from the NOMINUM-RESOLVER-


MIB::nrsvResolverName table.

Most of the statistics in Akamai nameserver products are accumulated by 64-

 bit counters. Because SNMPv1 does not support 64-bit integers, be careful
when using SNMPv1-only tools such as Getif
(http://www.wtcs.org/snmp4tpc/getif.htm)

SUMMARY:
We have given basic troubleshooting and access tips with the Akamai SNMP Agent. See the
Appendix for some helpful information regarding OIDs for the various configuration and
statistics objects in CacheServe.

Akamai Confidential Page 61


DNSi CacheServe Working with Stub and Forward
statements

Lab 13: Working with Stub and Forward statements


OVERVIEW: We have already seen the preload statement for a specific record, but DNSi
CacheServe allows other types of resolution-altering behavior. In this exercise, we compare
synthesize-nxdomain and preload-nxdomain. We conclude with stub statements
which allow DNSi CacheServe to “short-circuit” the resolution process by sending queries to an
authoritative server that it would not ordinarily discover, and forward statements which
direct DNSi CacheServe to send queries to other recursive servers.

STEP-BY-STEP:
1. Configure DNSi CacheServe to return NXDOMAIN for 10.in-addr.arpa and everything
beneath it for the internal view:

cacheserve> resolver.update name=internal synthesize-nxdomain+=(10.in-addr.arpa)

2. Use dig to query for the PTR record for 10.in-addr.arpa and 1.0.0.10.in-addr.arpa.

# dig @127.1 10.in-addr.arpa PTR

# dig @127.1 1.0.0.10.in-addr.arpa PTR

You should find your DNSi CacheServe returns NXDOMAIN to both queries.

3. In this step we configure preload-nxdomain statement for wpad, and then


investigate how subdomains are treated:

a. Add a new preload-nxdomain statement to the world view:

cacheserve> resolver.update name=internal preload-nxdomain+=(wpad)

b. Test the results by first using dig to get “any” record for wpad:
You should get NXDOMAIN.

Page 62 Akamai Confidential


Working with Stub and Forward statements DNSi CacheServe

# dig @127.1 wpad ANY

c. Next, use dig to get a record for test.wpad:

# dig @127.1 test.wpad ANY

Although the answer is still NXDOMAIN, you will find this answer from the Internet.

To respond with NXDOMAIN for every name under a given domain, use

 synthesize-nxdomain . To respond with NXDOMAIN for a given name


without affecting subdomains, use preload-nxdomain.

Neither is intended for claiming the nonexistence of records that actually exist.

4. The following example demonstrates how to add stubs. The target of the stub could be
a locally administered Vantio AuthServe (at 1.2.3.4) that publishes the zone movie.edu.
a. Add a new entry for the domain movie.edu:

cacheserve> resolver.update name=world stub+=((movie.edu ((ssh.sjc2.training


(1.2.3.4)))))

b. Use dig to again check the result of your configuration change movie.edu. The
domain is resolved according to the local authoritative server. The answers
should come from the local name server instance, not the Internet.

5. Next we get some practice entering forwarders. Try the following:

cacheserve> resolver.update name=internal forward=((168.192.in-addr.arpa 'only' (1.1.1.1


2.2.2.2) ))

cacheserve> resolver.update name=internal forward+=((1.168.192.in-addr.arpa 'off' () ))

Akamai Confidential Page 63


DNSi CacheServe Working with Stub and Forward
statements

The second instruction suspends forwarding; DNSi CacheServe resolves 1.168.192.in-


addr.arpa as normal.

SUMMARY:
The configured resolution instructions might contain synthesize-nxdomain, preload-
nxdomain, or even preload-nxrrset (for specific types of data). Configuring DNSi
CacheServe to find answers from name servers specified by the administrator include forward
and stub statements. If a stub appears within a forwarded domain, DNSi CacheServe uses the
stub only if forwarding is turned “off”.

Page 64 Akamai Confidential


Recording authoritative traffic with Auth-Querystore DNSi CacheServe

Lab 14: Recording authoritative traffic with Auth-Querystore


OVERVIEW: In this simple exercise we show how to configure a new kind of querystore in which
DNSi CacheServe records traffic exchanged with authoritative servers.

STEP-BY-STEP:
1. Initiate recording of authoritative data by updating DNSi CacheServe’s auth-
monitoring:

cacheserve> auth-monitoring.update auth-querystore={}

2. Confirm that the auth-querystore is active by checking its status in the statistics
monitor:

# nom-tell statmon

statmon> auth-querystore.status

3. Send a single query to your DNSi CacheServe instance using dig to populate the auth-
querystore. For example, we will look up google.es:

# dig @127.1 google.es

4. Check that you have captured traffic in the auth-querystore by verifying the count
is non-zero, and then show the details for the name just queried:

statmon> auth-querystore.count

statmon> auth-querystore.replay filter=((client-qname (true (google.es))))

Depending on the contents of your cache, there may be many authoritative requests, or
none!

Akamai Confidential Page 65


DNSi CacheServe Recording authoritative traffic with
Auth-Querystore

 Note the use of client-qname rather than name in the filter. In this context,
name refers to the Authority Server’s name.

5. The Authority Querystore is a valuable source of troubleshooting information. The next


several steps outline a sequence you might follow if you experience trouble resolving
names. For example you can list the top-domains for which CacheServe is timing out
against authority servers:

statmon> auth-querystore.top-domains filter=((auth-flags (true (TIMEDOUT ))))


duration=300

6. The next Authority Querystore analysis sorts the TIMED OUT queries by the authority
server’s IP address and client query name (that is, the original request that led to the
authoritative request):

statmon> auth-querystore.group-count group-by=(server-address client-qname)


filter=((auth-flags (true (TIMEDOUT )))) duration=300

7. If you have a specific name which is resolving erratically, a variation of the above
approach is to apply a filter to that domain and sort by servers and indicators of their
behavior:

statmon> auth-querystore.group-count group-by=(result-code auth-flags server-address)


filter=((domain (true (google.es)))) duration=300

In practice, applying an appropriate interval rather than duration would likely be


needed.

8. You can filter on the authoritative server’s IP address. To create an example, send a
request for a name in the stubbed domain 16.172.in-addr.arpa. As long as the name is
not in DNSi CacheServe’s cache, the query should force recursion to the server we
referred to as <YOUR-IP-ADDRESS> above:

Page 66 Akamai Confidential


Recording authoritative traffic with Auth-Querystore DNSi CacheServe

# dig @127.1 20.187.16.172.in-addr.arpa PTR

9. Looking back into the auth-querystore, we can search for all lookups that went to
the server with the IP address of our stub:

statmon> auth-querystore.replay filter=((server-address (true (<YOUR-IP-ADDRESS>))))

SUMMARY:
The auth-querystore is a separate recording mechanism specifically designed for analyzing
traffic between DNSi CacheServe and authoritative DNS servers with which it communicates.
This feature can be especially useful for troubleshooting. Some of this information can be
learned from the cache, but the searching and analysis features of the statmon do not exist with
the inspect commands.

Akamai Confidential Page 67


DNSi CacheServe Response customization with Precision
Policies

Lab 15: Response customization with Precision Policies


OVERVIEW: This lab introduces two applications of DNSi CacheServe’s policy features: selective
dropping of ANY queries used for DNS amplification attacks and preferred address sorting

The first application provides mitigation of DNS amplification attacks by dropping selected
queries for domains which have been identified as vectors in these circumstances.

The second part of the exercise shows how to implement a policy which favors (in the sense of
promoting to first response in the list) those returned A records which fall within IP address
boundaries configured by the administrator.

STEP-BY-STEP:

Dropping “ANY” queries to selected domains


Configuring DNSi CacheServe to completely ignore queries which satisfy certain criteria is one
approach to counter an amplification attack. Because queries of type ANY are popular for
amplification and have almost no legitimate use, we set up CacheServe to simply drop requests
for this type of query ONLY IF the query name falls within domains which have been identified
as being exploited for this purpose.

1. Query DNSi CacheServe for isc.org with the ANY metatype:

# dig @127.1 isc.org ANY

You should find a large number of RRSETS in the response.

2. The list of domain names which will be subject to dropping is created first. We arbitrarily
call the list “amplification-domains” in this example:

cacheserve> name-list.add name=amplification-domains

3. Next we add a commonly exploited domain name, isc.org, to that list:

cacheserve> name-node.add name=isc.org list=amplification-domains

4. The behavior we wish to enforce on queries of type ANY is ignore or “drop”, so we


create a policy called “drop-any” for this purpose:

Page 68 Akamai Confidential


Response customization with Precision Policies DNSi CacheServe

cacheserve> policy.add name=drop-any action=drop selector=(and ((qtype (ANY))(qname


(amplification-domains exact-or-www) )))

5. The last step is to restrict the action to those queries processed by the internal view:

cacheserve> binding.add view=internal policy=drop-any priority=1000

6. To verify the policy is enforced, send another request to DNSi CacheServe for isc.org
ANY. The query should time-out:

# dig @127.1 isc.org ANY

Other domains can be added and deleted as needed without changing the
definitions associated with the policy or binding. All that is needed is to
modify the list of names as suggested by the following commands:

 cacheserve> name-node.delete name=isc.org


list=amplification-domains
cacheserve> name-node.add name=ripe.net
list=amplification-domains

7. Remove the name isc.org from the list because we will apply a better remediation for
this in a later exercise:

cacheserve> name-node.delete name=isc.org list=amplification-domains

Preferred Address Sorting


The sequence in which sets of address records are returned can be adjusted by the
administrator. DNSi CacheServe’s default rrset-order value is cyclic—also known as round-
robin—which is popular because of its load-sharing effects. In some cases, network operators

Akamai Confidential Page 69


DNSi CacheServe Response customization with Precision
Policies

benefit by applying environment-specific policies which are implemented with policies as shown
in the following example.

8. As an example we will use the domain amazon.com to illustrate how certain addresses
can be promoted. A few queries for this name should demonstrate that by default,
address records are returned in cyclic order:
Repeat the query several times to show that the top-most IP address varies for each
response.

# dig @127.1 amazon.com

9. Use nom-tell to create an address list which will contain those network blocks to
favor:

cacheserve> address-list.add name=in-net

IP addresses (or blocks in CIDR notation) will be added in the next step. This step only
creates the list.

10. Populate the list you just created with some IP addresses which you wish to influence.
For example:

cacheserve> address-node.add list=in-net address=176.32/16

11. Verify the list contains the intended values:

cacheserve> address-node.list

12. We now need to inform the system what action should be taken when one of these
addresses appears in a response. This is done with a policy, which in this example we
call “sortlist”:

Page 70 Akamai Confidential


Response customization with Precision Policies DNSi CacheServe

cacheserve> policy.add name=sortlist action=(sort-addresses ((in-net) false ))

The Boolean in the sort-addresses action is called the “remove-unmatched” flag. It


controls the behavior when some addresses in the answer do not match any of the
specified lists. If true, these answers are removed from the response. If false, these
answers will be present in the response, after all addresses which do match a list.

13. The last step is to associate the policy with a scope, which for this example applies to
the entire server (that is, all views) and that the execution takes place AFTER resolution:

cacheserve> binding.add server=1 policy=sortlist priority=2000 when=postquery

A binding executes at the point in processing defined by the “when” field. The
default is “prequery.”

 If a selector or action only makes sense at some subset of times, and is invoked at
some other time, it has no effect.

Since our policy only makes sense after the A records have been fetched, the
binding must be defined as a “postquery” one.

14. Repeat the query to DNSi CacheServe for amazon.com. You should find that any
addresses in the 176.32.0.0/16 network are always returned first:

# dig @127.1 amazon.com

Addresses can be added and deleted as needed without changing the definitions

 associated with the policy or binding. All that is needed is to modify the list
of IP networks as suggested by the following command:

Akamai Confidential Page 71


DNSi CacheServe Response customization with Precision
Policies

cacheserve> address-node.delete list=in-net


address=72.21.211/24
cacheserve> address-node.add list=in-net
address=141.62.0.0/16.

SUMMARY:
The ability to manipulate DNSi CacheServe behavior with policies has been demonstrated by
dropping ANY queries to selected domains and using preferred address sorting to manipulate all
responses. Other features, such as per-client and address-synthesis behaviors, are intended for
use with Akamai’s SPS platform and require an additional license with the “N2” feature enabled.

Page 72 Akamai Confidential


Advanced Rate-Limiting DNSi CacheServe

Lab 16: Advanced Rate-Limiting


OVERVIEW: The concept of the “ratelimiter” object and its configuration is explored for use in
combating a DNS Amplification Attack. First, we look at analyzing traffic using statmon’s “rate-
limiting-by-response-size,” and then apply a targeted mitigation solution using a policy.

STEP-BY-STEP:
1. In a previous exercise we used policies to drop the ANY type query for isc.org, and
described how a list of domain names could be maintained in Vantio for which that same
policy applies.
But how did we know to “block” isc.org?

Identifying those domains names for which queries generated large responses is
possible using the analysis capabilities of the statmon:

statmon> querystore.top-domains-by-response-size duration=100 max-results=5

2. If unexpected names appear in the list, you might want to check for the size of the
responses by applying an additional filter. Here we look at response sizes greater than
1kB:

statmon> querystore.top-domains-by-response-size duration=100 filter=((response-size-ge


(true (1024))))

3. After you have identified those names which are responsible for consuming the greatest
amount of response traffic, analyze their request types:

statmon> querystore.group-count group-by=(query-type name) duration=100 filter=((name


(true (q1w.in 067.cz))))

You should find a few types of query dominate; these may change at attacks evolve.

♦ What is the ratio of response-size to request-size for each of these? It is probably


easiest to examine a few of the queries with “replay” to find the answer.

Akamai Confidential Page 73


DNSi CacheServe Advanced Rate-Limiting

The domain q1w.in might be called “purpose-built” for amplification attacks


because it would appear to have no legitimate use. It would be a very good
candidate for the approach earlier used with isc.org: just DROP “ANY”-type

 queries for the domain, or possibly even sub-domains.

Because it may not always be obvious what the purpose of a domain is; that is,
whether a name has both legitimate use and is also attractive to attackers, other
approaches are useful.

4. Suppose we suspect that the domains we identified earlier were “dual use” in the sense
that their large-sized responses were sometimes legitimate, and that it was possible your
clients require (un-truncated) responses at rates of a few QPS, but not more. In this case
we can use a ratelimiter object combined with the query selection capability. First
create a list for exact and sub-domain matches:

cacheserve> name-list.add name=ratelimit-lrg-answers-exact

cacheserve> name-list.add name=ratelimit-lrg-answers-inexact

5. Populate the lists with 067.cz and q1w.in, respectively:

cacheserve> name-node.add list=ratelimit-lrg-answers-exact name=067.cz

cacheserve> name-node.add list=ratelimit-lrg-answers-inexact name=q1w.in

6. Add a ratelimiter which allows 1qps for type A (and any other type) requests:

cacheserve> ratelimiter.add name=dual_use qps=1 fields=(query-type)

7. The creation of the ratelimiter itself has no effect on anything. You can verify it does
nothing by looking at the ratelimiter’s statistics:

Page 74 Akamai Confidential


Advanced Rate-Limiting DNSi CacheServe

cacheserve> ratelimiter.statistics name=dual_use all=1

You will find only zeroes in the statistics field of the output

8. Create the policy that will apply the ratelimiter only for the domains on the lists:

cacheserve> policy.add name=truncate_dual_use action=truncate selector=(and ((or ((qtype


(A)) (qtype (ANY)) (qtype (TXT)) )) (or ((qname (ratelimit-lrg-answers-exact exact))
(qname (ratelimit-lrg-answers-inexact subdomain)) )) (ratelimiter dual_use)))

9. Bind the policy to the server object to begin enforcing rate-limiting:

cacheserve> binding.add server=1 policy=truncate_dual_use priority=30

10. Check whether the ratelimiter’s statistics are being incremented:

cacheserve> ratelimiter.statistics name=dual_use

You can also check the response bandwidth and verify it has decreased.

SUMMARY:
Using a ratelimiter with a policy is targeted and efficient but suffers from the drawback that the
lists of domains must be maintained.

Akamai Confidential Page 75


DNSi CacheServe ECS and Equivalence Classes

Lab 17: ECS and Equivalence Classes


OVERVIEW: An authoritative DNS server which supplies a response to a recursive (caching)
server traditionally has no awareness of what client(s) might be consuming the results. The
EDNS0 Client Subnet (ECS) mechanism provides authoritative servers with IP address
information about the end client, which can be used to provide customized DNS answers.

The use of ECS and an optimization Nominum calls “Equivalence Classes” are described in this
lab.

STEP-BY-STEP:
1. By default, ECS is not enabled for any part of the DNS name space. One reason for this is
not every authoritative server supports it, but more importantly the use of ECS can
significantly increase resource needs of CacheServe.
We begin by enabling ECS on all queries to the google.com domain:

cacheserve> resolver.update name=internal client-subnet={whitelist=(google.com)}

2. Force your CacheServe to lookup www.google.com on behalf of two different clients


using the server.query command:

cacheserve> server.query resolver=internal client-address=25.24.8.1 qname=www.google.com

cacheserve> server.query resolver=internal client-address=25.185.8.1 qname=www.google.com

The second address is different in the second octet.

CacheServe allows the administrator to disable ECS treatment of certain

 subdomains. For example, you may wish to append the directive


blacklist=(mail.google.com) to the client subnet definition.

Page 76 Akamai Confidential


ECS and Equivalence Classes DNSi CacheServe

3. Use resolver.inspect to verify that your server cached two distinct entries for the
two different client IP addresses:

cacheserve> resolver.inspect name=internal domain=www.google.com

♦ What is the scope (network mask) for each of these cache entries?

♦ What answer is returned for the two cases?

4. In the case where the administrator knows that client networks should receive the same
responses, he can create an equivalence class. For our example, we create an
equivalence class consisting of the two networks above by creating an address-
list:

cacheserve> address-list.add name=A

cacheserve> address-node.add address=25.24.8.0/24 list=A

cacheserve> address-node.add address=25.185.8.0/24 list=A

5. Now associate the equivalence class with the resolver:

cacheserve> resolver.update name=internal client-subnet={whitelist=(google.com)


equivalence-classes=A}

6. Inspect the cache for www.google.com. You should find that it has been cleared.
7. Repeat the server.query commands from before:

cacheserve> server.query resolver=internal client-address=25.24.8.1 qname=www.google.com

cacheserve> server.query resolver=internal client-address=25.185.8.1 qname=www.google.com

Akamai Confidential Page 77


DNSi CacheServe ECS and Equivalence Classes

8. Once more look in the cache. Notice that the cache no longer contains separate entries:
consolidating the networks results in much more efficient cache use.

SUMMARY:
The ECS feature can result in MUCH more caching and recursion, requiring more resources than
if it was not enabled. Equivalence classes provide a way around this, at the cost of creating and
maintaining address lists.

Page 78 Akamai Confidential


IPv6 and DNS64 DNSi CacheServe

Lab 18: IPv6 and DNS64


OVERVIEW: The objective of DNS64 (RFC 6147) is to provide an IPv6 address for services which
publish only IPv4 addresses in the DNS. This is required in environments where translation
between IPv4 and IPv6 is deployed. In this exercise we configure DNSi CacheServe to synthesize
AAAA records using this feature.

Before enabling DNS64, it is useful to review how diagnostic tools are used with IPv6.

STEP-BY-STEP:
1. Verify that you can successfully use ping6 with the loopback address configured on the
local interface:

# ping6 ::1

2. Repeat with one or more of the addresses bound to the Ethernet interface (substitute
addresses from your local host, which can be displayed with the /sbin/ip addr
command):

# ping6 fd0c:a43a:811f:40:59eb::12

# ping6 –I eth0 fe80::20c:29ff:fe2e:528e

The second address is a link-local (not global) address, so ping6 requires that the user supply
an interface.

ping6 allows the explicit declaration of the interface as a command-line

 argument. Other tools express the interface as a numbered suffix on the IPv6
address.

3. Use dig to verify that your server can respond to a DNS request for A and AAAA
records when carried over IPv6 (your address may be different):

Akamai Confidential Page 79


DNSi CacheServe IPv6 and DNS64

# dig @fd0c:a43a:811f:ac:10bb::1 espn.com

# dig @fd0c:a43a:811f:ac:10bb::1 espn.com AAAA

♦ What address could an IPv6-only client use to reach the espn.com website?

4. Add a prefix to be used in DNS64 response synthesis:

cacheserve> dns64.add name=64:ff9b::/96 prefix=64:ff9b::/96

5. The existence of the prefix by itself does not enable the DNS64 functionality. Create a
policy which examines the result of a query and does DNS64 synthesis according to the
mapping rules found in the dns64 object configured above:

cacheserve> policy.add name=dns_64_a action=(dns64 64:ff9b::/96 )

6. Bind the policy (at postquery time) with prefix 64:ff9b::/96 to the entire server:

cacheserve> binding.add server=1 when=postquery priority=140 policy=dns_64_a

7. Repeat your IPv6 query to your DNSi CacheServe instance for nominum.com’s AAAA
record:

# dig @fd0c:a43a:811f:ac:10bb::1 espn.com aaaa

You should now find a list of AAAA records, where the previous response was
NOANSWER/NOERROR.

♦ Are the synthesized responses cached?

Page 80 Akamai Confidential


IPv6 and DNS64 DNSi CacheServe

8. Picking one of the IPv6 addresses from the response above, find out whether reverse
DNS64 responses are also synthesized:

# dig @fd0c:a43a:811f:ac:10bb::1 –x 64:ff9b::cebe:242d

Reverse record (PTR) request processing for DNS64 prefixes must be configured
separately with a policy that performs the dns64-reverse action. Completion


of this is left as a challenge for the reader.

Synthesized addresses are as defined in the policy in addition to the Well-Known


Prefix (RFC 6052). In the case of the DNS64 object used for this exercise
(64:ff9b::/96) they are the same.

SUMMARY:
The DNS64 feature enables additional processing for queries of type AAAA in any view with
DNS64 configuration. If no AAAA records exist for the queried name, but A records do exist,
AAAA records may be generated from A records according to a set of mapping rules, and the
synthesized answer returned to the client. Additional configuration of the DNS64 feature allows
further refinement of which clients are affected and what addresses are returned to them.

Akamai Confidential Page 81


DNSi CacheServe Customizing the CacheServe Service
Script

Lab 19: Customizing the CacheServe Service Script


OVERVIEW: It is often useful to add command-line arguments when starting DNSi CacheServe. In
this exercise we show how to configure the file
/usr/local/nom/etc/sysconfig/cacheserve for this purpose. The command-line
argument which forces DNSi CacheServe to read a text configuration file will be used as a
demonstration of this feature.

STEP-BY-STEP:
1. Before we begin let’s make a backup of the database:

# mkdir /var/nom/cacheserve.ex18

# cp -r /var/nom/cacheserve /* /var/nom/cacheserve.ex18/

2. Create/edit a new file /usr/local/nom/etc/sysconfig/cacheserve:

# vi /usr/local/nom/etc/sysconfig/cacheserve

3. Add the following line of text to the file and save it:

CACHESERVE_OPTIONS="--license /root/cacheserve.license"

4. Start DNSi CacheServe in the usual way:

# systemctl start cacheserve

♦ With what configuration does CacheServe start?

Page 82 Akamai Confidential


Customizing the CacheServe Service Script DNSi CacheServe

SUMMARY:
You have customized the command-line argument for CacheServe by applying an environment
variable in the sysconfig file.

All Akamai products support this mechanism for customization. You must

 •

Replace the file name with the appropriate product name and
Change the environment variable name to the product

Akamai Confidential Page 83


DNSi CacheServe Installing the Perl API

Lab 20: Installing the Perl API


OVERVIEW: In this exercise we install the Akamai components needed to use the Perl CC
interface.

STEP-BY-STEP:
1. Login as root.
2. Confirm that a version of Perl on the host is 5.6 or above. Use the following command to
check the version:

# perl -v

The command must return Perl version 5.6 or higher.

Multiple Perl installations may exist on some machines. The default instance
might be older than other versions on the system. For example, it is not


uncommon for the default installation to appear in /usr/bin/perl, and
another version at /usr/local/bin/perl.

Examples in this guide will invoke the Perl binary without an absolute path.
Your path may be different.

3. Add the SDK to your environment by uncompressing and extracting the files needed for
all the Command Channel language bindings to your system to a temporary directory.
When this step is completed, you will find a number of files related to programming
languages supported by the Akamai Command Channel API:

# cd /tmp

# tar xvzf nomsdk-3.0.0.1-1.tar.gz

# cd nomsdk-3.0.0.1-1

Page 84 Akamai Confidential


Installing the Perl API DNSi CacheServe

4. The Akamai Perl CC API installation requires steps that will be familiar to you if you have
ever manually installed (that is, not using CPAN) a Perl module. To begin the process,
change to the Perl subdirectory where the API files were copied in the previous step:

# cd perl

5. We now execute Perl on makefile.PL in preparation for installing the Perl module.
Run the following command

# perl Makefile.PL

The system writes a file called Makefile in the perlcc subdirectory.

6. Assuming that make is in your path (frequently, make is found in /usr/local/bin,


but it is sometimes found in /usr/ccs/bin) type the command:

# make

 To install the Perl API on Windows, substitute nmake for make.

7. Finally, install the module with the command make install:

# make install

8. The output of the make install command should conclude with installation
information. Confirm that the installation succeeded by typing a command:

Akamai Confidential Page 85


DNSi CacheServe Installing the Perl API

# perl –e 'use Nom::CC::Channel;'

The command should execute without error. If there are errors, something went wrong.

SUMMARY:
We have installed the CC API for Perl. In the next section we read some of the ANS configuration
from a Perl program as a simple illustration of a typical script.

Page 86 Akamai Confidential


Simple and Useful Program DNSi CacheServe

Lab 21: Simple and Useful Program


OVERVIEW: To illustrate practical use of the Perl API, in this exercise we run a script that
repeatedly gets statistics from CacheServe, and displays the results in a tabular format.

STEP-BY-STEP:
1. In /tmp you will have a tar file called cacheserve_perl.tar. Extract its contents
as shown here:

# cd /tmp

# tar xvf cacheserve_perl.tar

2. You should now find vantio_stats.pl. Run it with the command:

# perl cacheserve_stats.pl

If you send two queries to DNSi CacheServe, you might find output similar to this:

client authority recur requests TCP

req resp req resp cntx no view sent

------ ------ ------ ------ ------ --------- ----

0 0 0 0 0 0 0

0 0 0 0 0 0 0

1 1 3 3 0 0 0

1 1 11 11 0 0 0

0 0 0 0 0 0 0

 This script uses the server.statistics instruction.

Akamai Confidential Page 87


DNSi CacheServe Simple and Useful Program

SUMMARY:
The script repeatedly fetches statistics from DNSi CacheServe, displaying—for each 1-second
interval—the following:

a. amount of traffic from and to clients,


b. amount of traffic to and from authoritative servers,
c. requests with no view,
d. TCP requests sent to authority servers.

Page 88 Akamai Confidential


Your First Perl CC API Program DNSi CacheServe

Lab 22: Your First Perl CC API Program


OVERVIEW: You are now ready to try the Perl CC API for yourself. We begin with a simple
program that performs the same function as the command nom-tell cacheserve
version. Unlike the nom-tell output, this script writes only the version number to the
display.

STEP-BY-STEP:
1. In the /tmp directory find the file cc_test.pl. For your reference this is the
contents of the file:

#!/usr/local/bin/perl

use Nom::CC::Message;

use Nom::CC::Channel;

my $chan = new Nom::CC::Channel("cacheserve");

my $request = new Nom::CC::Message({type => "version"});

my $response = $chan->send($request);

print $response->{version}, "\n";

2. Run the program. You should see the version of the DNSi CacheServe server printed to
standard output.

# perl cc_test.pl

7.6.0.2

 For clarity, no error handling is provided in this sample script. In the next
exercise we add a line of code which gives an indication of problems.

Akamai Confidential Page 89


DNSi CacheServe Your First Perl CC API Program

For a detailed examination of the code, see the Appendix.

Now let’s get our first look at a configuration object, and provide examples of extracting various
known elements from the configuration.

3. From the /tmp directory, locate and run cacheserve_getserver.pl which


contains this code:

#!/usr/bin/perl
use Nom::CC::Channel;
use Nom::CC::Message;
my $chan = new Nom::CC::Channel("cacheserve");

my $request = new Nom::CC::Message({


type => "server.get"
});
my $response = $chan->send($request);
die $response->{err} if $response->{err};

print "--- CacheServe Configuration ---\n";


foreach my $k (keys %$response) {
print "$k: $response->{$k}\n";
}

A typical response is shown below:

# perl cacheserve_getserver.pl

--- Cacheserve Configuration ---


type: server.get
log-command-channel: true
listen-on-matching: ARRAY(0x17e8fa0)

Page 90 Akamai Confidential


Your First Perl CC API Program DNSi CacheServe

The previous page shows that a DNSi CacheServe server configuration is returned as a hash, and
that the keys to the hash are familiar fields of the server object. The same is true of all objects
we might request. As a concrete example, we’ll next modify the code to get the “world”
resolver’s configuration.

4. Copy the file cacheserve_getserver.pl to a file named


cacheserve_getworldresolver.pl
5. Edit the file cacheserve_getworldresolver.pl
6. Add or modify the boldface text for those lines of code which define the message sent
to the server:

my $request = new Nom::CC::Message({


type => "resolver.get",
name => "world"
});

7. Run the script vantio_getworldresolver.pl:

--- Cacheserve Configuration ---


preload: ARRAY(0x1a03610)
name: world
query-source-pool: ARRAY(0x18e46c8)
type: resolver.get

The output should be similar to that shown above.

Some commands, such as the list method, return a sequence. A sequence is a set of data
items, returned one at a time, that can be identified by the appearance of the tag _more in the
control section of the message.

You can use nom-tell in verbose mode (-v option) to see an example of
 processing a command channel sequence. Issue this command at the shell
prompt:
# nom-tell –v cacheserve resolver.list

Akamai Confidential Page 91


DNSi CacheServe Your First Perl CC API Program

This approach does not work with non-interactive mode (the “cacheserve”
prompt).

The programmer can detect and request items in a sequence with code that is illustrated in the
example file cacheserve_ listresolvers.pl.

Idea for other simple programs:

A. Create a program to get the most-requested domains from statmon


B. Create a program to find the name server used to resolve delegations from a given
domain. Hint: use the inspect-delegation command.

SUMMARY:
A few sample scripts included on your lab instance should inspire some of your own ideas for
programs.

Page 92 Akamai Confidential


Answers to Exercises DNSi CacheServe

Answers to Exercises
ANSWER TO EXERCISE 1
Sample output from nom-tell when DNSi CacheServe responds to the “version” command.

request:
{
type => 'version'
}

response:
{
type => 'version'
vendor => 'Akamai'
product => 'Vantio CacheServe'
platform => 'rhel-7-x86_64'
version => '7.6.0.2'
build => '234542'
expiration => 'Wed Sep 30 23:59:59 2020'
}

 Expiration dates only appear for temporary license files, such as those issued
for product evaluations and training.

Because the server object is in its default configuration, the server.get response does not
include any fields:

Akamai Confidential Page 93


DNSi CacheServe Answers to Exercises

# nom-tell cacheserve server.get

request:

type => 'server.get'

response:

type => 'server.get'

Modifications to the server will result in the appearance of the applied values. The same is true
of all object types, such as Resolvers. As shown below, the default world resolver appears to
have only one default property: its name.

# nom-tell cacheserve resolver.mget


request:
{
type => 'resolver.mget'
}

response:
{
type => 'resolver.mget'
name => 'world'
}

After modifying the server configuration with the listen-on-matching statement, the
response to server.get response is no longer empty:

Page 94 Akamai Confidential


Answers to Exercises DNSi CacheServe

cacheserve> server.get

type => 'server.get'

listen-on-matching => (

patterns => ('127.0.0.1/32')

patterns => ('10.132.0.0/9' 'fe80::4001:0:0:0/80')

cacheserve>

ANSWER TO EXERCISE 2
What is the result of querying the server for localhost again? You should find no change

The command still consulted the “world” resolver. The presence of the second
(“internal”) has no effect until we direct queries to be answered from it.

Is the response for the A record of localhost still determined by our preload statement in the
“world” resolver? In other words, is the response still 127.0.0.1? Why?

No longer, because a query sent to 127.0.0.1 appears to be coming FROM 127.0.0.1, and
so is answered through the internal view, which means the “internal” resolver.

Use dig to query for localhost on another student’s instance of DNSi CacheServe. Explain
your results.

Should get the “world” resolvers answer, which is the preloaded data. The query arrives
on the routed interface.

Which view responded to the instructor’s queries?

Should be the “world” resolver for the same reason.

What is the result of sending a command channel instruction after DNSi CacheServe has
stopped?

Should be an error could not send to 'cacheserve': Connection


refused because there is no command channel when the server is stopped.

Don’t let the presence of the prompt fool you.

Akamai Confidential Page 95


DNSi CacheServe Answers to Exercises

ANSWER TO EXERCISE 3
Are the counters for responses-sent and requests-received equal?

Yes. Normally CacheServe responds (even if it’s REFUSED) to every query.

Which resolver has the bigger cache size? Why?

The traffic (and therefore variety of query names) to the world resolver is much greater.
If the exact same name was being requested over and over in both cases, the RATE itself
would not affect the size of the cache.

ANSWER TO EXERCISE 4
Does the output indicate what clients have requested this name?

No. The cache does not record what clients made requests to a specific name. It can be
recorded with other mechanisms like the querystore.

What result do you expect with resolver.inspect name=internal for this domain?

Does not exist (in that cache) because it has not been requested.

What impact does this have for users of the internal resolver?

No impact, because the two resolver’s caches are completely independent.

What view and resolver is used to lookup the result? Repeat. Is the result cached?

The server.query command assumes the source IP is 127.0.0.1, so the internal view (and
therefore internal resolver) is used. The NXDOMAIN is cached.

Repeat the command a few times. How can you tell the result displayed is not from the cache?

The “res” flag indicates that a recursion was required.

ANSWER TO EXERCISE 7
How many source ports are open on your instance of DNSi CacheServe??

256 by default, per resolver.

How many source ports are open on your instance of DNSi CacheServe now?

1024. The number is capped at 2048 so even if you configure more, it will not exceed this
value.

ANSWER TO EXERCISE 8
What records (types) appear in the responses?

Only A records.

Page 96 Akamai Confidential


Answers to Exercises DNSi CacheServe

What records (types) appear in the responses now? Does the cache show the trust field?

Includes the RRSIG records. There is no trust indicator.

Does dig report that DNSi CacheServe provides a validated answer now? Does DNSi
CacheServe’s cache?

Yes to both. The resolver is validating.

ANSWER TO EXERCISE 10
What statistics appear?

The name statistics (because there is a property to look for, unlike the total number)
appear empty at first. As new names are queried, their statistics appear.

type => 'querythreshold.statistics'

statistics => (

target-type => 'total'

qps => '0.059'

id => 'server_qps'

trigger-count => '0'

active => '0'

}}

Akamai Confidential Page 97


DNSi CacheServe Appendix: Anatomy of a dig display

Appendix: Anatomy of a dig display


DNS is a client-server protocol which is commonly used to provide a simple database-lookup
functionality. This “database” has a “dictionary” or key-value structure, where a domain name
and resource record type (TYPE) is the key and the resource record data (RDATA) is the value.

dig is a DNS client: a command-line program which implements the query mode of DNS
operation. Other operations defined in the DNS can be exercised with different client programs.
For example, nsupdate provides support for DNS update (often called DDNS) which allows a
client to modify a DNS zone entry.

In the illustrations which follow, several important elements of the dig display are identified.
Consider a query for the “A” record (IPv4 address) of akamai.com. Note that dig uses type A
for its default if no explicit type is declared on the command line. It is assumed that a recursive
name server (e.g. DNSi CacheServe) is listening for DNS requests on the loopback interface
127.0.0.1:

Page 98 Akamai Confidential


Appendix: Anatomy of a dig display DNSi CacheServe

# dig @127.1 akamai.com

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-16.P2.el7_8.6 <<>> @127.1 akamai.com

; (1 server found)

;; global options: +cmd

;; Got answer:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39771

;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:

; EDNS: version: 0, flags:; udp: 512

;; QUESTION SECTION:

;akamai.com. IN A

;; ANSWER SECTION:

akamai.com. 20 IN A 184.50.167.23

;; Query time: 358 msec

;; SERVER: 127.0.0.1#53(127.0.0.1)

;; WHEN: Mon Aug 31 04:05:22 UTC 2020

;; MSG SIZE rcvd: 55

Referring to the response above (which includes the question, per the DNS specification), we
see the result code is NOERROR (the server was able to process the query) and the contents are
summarized as follows:
QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

This means the response has one (1) question entry and one (1) answer entry. The answer
section consists of the TTL (time-to-live, in this case 20 seconds) and the IP address (in this case,
184.50.167.23). If more than one A records (addresses) were available, they would be included
as separate entries. The collection of all records at a name of a specific type is called a resource
record set (RRSET).

It is sometimes useful to examine greater detail about the response. The flags field in a DNS
message indicates how a client wishes a request to be handled as well as what action the server
has taken. In our example, only three flags are set and they show the following:

Akamai Confidential Page 99


DNSi CacheServe Appendix: Anatomy of a dig display

qr Query-Response bit is one (query=0 response=1), so this message is a response

rd Recursion Desired (set by client)

ra Recursion Available (set by server)

Note also the reduced TTL in the example below. It was originally 20 seconds, but as data in the
cache ages, this number decreases.

# dig @127.1 akamai.com

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-16.P2.el7_8.6 <<>> @127.1 akamai.com

; (1 server found)

;; global options: +cmd

;; Got answer:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39771

;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:

; EDNS: version: 0, flags:; udp: 512

;; QUESTION SECTION:

;akamai.com. IN A

;; ANSWER SECTION:

akamai.com. 6 IN A 184.50.167.23

;; Query time: 358 msec

;; SERVER: 127.0.0.1#53(127.0.0.1)

;; WHEN: Mon Aug 31 04:05:22 UTC 2020

;; MSG SIZE rcvd: 55

Page 100 Akamai Confidential


Appendix: CacheServe SNMP objects DNSi CacheServe

Appendix: CacheServe SNMP objects


To communicate with DNSi CacheServe via SNMP commands, one needs an acquaintance with
the DNSi CacheServe SNMP object structure. It is possible to extract the relationship between
elements exposed through SNMP and those available directly over the command channel by
reading the product documentation (particularly, the MIBs), but concrete examples should be
helpful.

Standard SNMP utilities were used to generate the output shown below. Some text produced by
running these commands has been edited. For example, structures appropriate to authoritative
name servers (e.g., ANS) are suppressed for clarity.

Figure 1: Server (nnsmServerObjects) representation

# snmptranslate -Tp SNMPv2-SMI::enterprises.5901.4.5.1.2


+--+--nnsmServerObjects(1)
|
+--nnsmServerCacheStatsTable(1)
| |
| +--nnsmServerCacheStatsEntry(1)
| | Index: applIndex
| |
| +-- -RW- BitString nnsmServerCacheStatsControl(2)
| | Values: client(0), domain(1)
| +-- -R-- Gauge nnsmServerCacheMemoryInUse(3)
| +-- -R-- Gauge nnsmServerCacheRecursionContextsActive(4)
| +-- -R-- Gauge nnsmServerCacheStatsTcpClients(5)
| +-- -R-- TimeTicks nnsmServerCacheStatsDiscontinuityTime(6)
| | Textual Convention: TimeStamp
| +-- -R-- Counter64 nnsmServerCacheStatsRequestNoView(7)
| +-- -R-- Counter64 nnsmServerCacheStatsRequestRecv(8)
| +-- -R-- Counter64 nnsmServerCacheStatsRequestSent(9)
| +-- -R-- Counter64 nnsmServerCacheStatsResponseRecv(10)
| +-- -R-- Counter64 nnsmServerCacheStatsResponseSent(11)

| +-- -R-- Counter64 nnsmServerCacheStatsMonitorDrops(27)
|
+--nnsmServerCacheTopClientStatsTable(2)
| |
| +--nnsmServerCacheTopClientStatsEntry(1)
| | Index: applIndex, nnsmServerCacheTopClientID
| |
| +-- ---- Unsigned nnsmServerCacheTopClientID(1)
| +-- -R-- EnumVal nnsmServerCacheTopClientInetAddrType(2)
| | Textual Convention: InetAddressType

The Ratelimiting Drops, Top Client and Top Domain tables (and the StatsControl parameter that
enables them) are not supported in CacheServe 7; these appear in the MIBS because they are
shared with Vantio 5.

Akamai Confidential Page 101


DNSi CacheServe Appendix: CacheServe SNMP objects

An example of fetching a specific value for the current count of Recursion Contexts appears
here:

# snmpget -v2c -c test 1.2.3.4 1.3.6.1.4.1.5901.4.5.1.1.1.1.4.1

NOMINUM-NSM-MIB::nnsmServerCacheRecursionContextsActive.1 = Gauge32: 95

Figure 2: View (nnsmViewObjects) representation

# snmptranslate -Tp SNMPv2-SMI::enterprises.5901.4.5.1.2


+--nnsmViewObjects(2)
|
+--nnsmViewNameToViewIdTable(1)
| |
| +--nnsmViewNameToViewIdEntry(1)
| | Index: applIndex, nnsmViewNameAsIndex
| |
| +-- ---- String nnsmViewNameAsIndex(1)
| | Textual Convention: SnmpAdminString
| | Size: 0..104
| +-- -R-- Unsigned nnsmViewNameToViewID(2)
| Textual Convention: NominumViewID
| Range: 0 | 1..-1
|
+--nnsmViewTable(2)
| |
| +--nnsmViewEntry(1)
| | Index: applIndex, nnsmViewID
| |
| +-- ---- Unsigned nnsmViewID(1)
| | Textual Convention: NominumViewID
| | Range: 0 | 1..-1
| +-- -R-- String nnsmViewName(2)
| | Textual Convention: SnmpAdminString
| | Size: 0..255
| +-- -R-- EnumVal nnsmViewType(3)
| Textual Convention: NominumViewType
| | Values: auth(1), cache(2), lwCache(3), other(4)
| +-- -R-- Unsigned nnsmViewResolverID(4)
| Textual Convention: NominumResolverIdOrZero
| Range: 0 | 1..4294967295
|

This command returns the list of DNSi CacheServe’s views and corresponding resolvers:

Page 102 Akamai Confidential


Appendix: CacheServe SNMP objects DNSi CacheServe

# snmpwalk -v2c -c test 1.2.3.4 1.3.6.1.4.1.5901.4.5.1.2.2

NOMINUM-NSM-MIB::nnsmViewName.1.1 = STRING: internal

NOMINUM-NSM-MIB::nnsmViewName.1.2 = STRING: world

NOMINUM-NSM-MIB::nnsmViewType.1.1 = INTEGER: lwCache(3)

NOMINUM-NSM-MIB::nnsmViewType.1.2 = INTEGER: lwCache(3)

NOMINUM-NSM-MIB::nnsmViewResolverID.1.1 = Gauge32: 1

NOMINUM-NSM-MIB::nnsmViewResolverID.1.2 = Gauge32: 2

fetches the nnsmViewTable which tells us that the view called internal has view ID 1, is a “light-
weight” (lwCache) view type—the only type of view that exists in DNSi CacheServe 7—and it
points to a resolver with ID 1.

Resolver information is exposed in the resolver mib, which is shown next.

Figure 3: Resolver (nrsvObjects) representation

# snmptranslate -Tp SNMPv2-SMI::enterprises.5901.4.16


+--nrsvObjects(1)
| +--nrsvBaseObjects(1)
| | |
| | +--nrsvResolverNameToResolverIdTable(1)
| | | |
| | | +--nrsvResolverNameToResolverIdEntry(1)
| | | | Index: applIndex, nrsvResolverNameAsIndex
| | | |
| | | +-- ---- String nrsvResolverNameAsIndex(1)
| | | | Textual Convention: SnmpAdminString
| | | | Size: 0..104
| | | +-- -R-- Unsigned nrsvResolverNameToResolverID(2)
| | | Textual Convention: NominumResolverID
| | | Range: 1..4294967295
| | |
| | +--nrsvResolverTable(2)
| | |
| | +--nrsvResolverEntry(1)
| | | Index: applIndex, nrsvResolverID
| | |
| | +-- ---- Unsigned nrsvResolverID(1)
| | | Textual Convention: NominumResolverID
| | | Range: 1..4294967295
| | +-- -R-- String nrsvResolverName(2)
| | Textual Convention: SnmpAdminString
| | Size: 0..255
| |
| +--nrsvStatisticsObjects(2)
| | |
| | +--nrsvResolverStatsTable(1)
| | |
| | +--nrsvResolverStatsEntry(1)

Akamai Confidential Page 103


DNSi CacheServe Appendix: CacheServe SNMP objects

| | | Index: applIndex, nrsvResolverID


| | |
| | +-- -R-- TimeTicks nrsvResolverStatsDiscontinuityTime(1)
| | | Textual Convention: TimeStamp
| | +-- -R-- Counter64 nrsvResolverStatsLookUps(2)
| | +-- -R-- Counter64 nrsvResolverStatsRequests(3)
| | +-- -R-- Counter64 nrsvResolverStatsRecursiveLookUps(4)
| | +-- -R-- Counter64 nrsvResolverStatsSentRequests(5)
| | +-- -R-- Counter64 nrsvResolverStatsTcpSentRequests(6)
| | +-- -R-- Counter64 nrsvResolverStatsIdSpoofingDefenseQueries(7)
| | +-- -R-- Counter64 nrsvResolverStatsMisses(8)
| | +-- -R-- Counter64 nrsvResolverStatsDnsSecFailedValidations(9)
| | +-- -R-- Counter64 nrsvResolverStatsDnsSecInsecureValidations(10)
| | +-- -R-- Counter64 nrsvResolverStatsDnsSecSuccessfulValidations(11)
| | +-- -R-- Counter64 nrsvResolverStatsProactiveLookups(12)
| |)
This command returns the name of the resolver with ID 2:

# snmpget -v2c -c test 1.2.3.4 1.3.6.1.4.1.5901.4.16.1.1.2.1.2.1.2

NOMINUM-RESOLVER-MIB::nrsvResolverName.1.2 = STRING: world

If the name of the resolver is known, but not the ID, it is possible to get the ID by fetching the
nrsvResolverNameToResolverID value using the ASCII code representation of the name
as the index:

# snmpget -v2c -c test 1.2.3.4 1.3.6.1.4.1.5901.4.16.1.1.1.1.2.1.5.87.79.82.76.68

NOMINUM-RESOLVER-MIB::nrsvResolverNameToResolverID.1."WORLD" = Gauge32: 2

The next commands return total queries processed by DNSi CacheServe’s resolvers with IDs 1
and 2.

# snmpget -v2c -c public 127.0.0.1 1.3.6.1.4.1.5901.4.16.1.2.1.1.3.1.1

NOMINUM-RESOLVER-MIB::nrsvResolverStatsRequests.1.1 = Counter64: 525 DNS requests

# snmpget -v2c -c public 127.0.0.1 1.3.6.1.4.1.5901.4.16.1.2.1.1.3.1.2

NOMINUM-RESOLVER-MIB::nrsvResolverStatsRequests.1.2 = Counter64: 11130 DNS requests

Page 104 Akamai Confidential


Appendix: CacheServe SNMP objects DNSi CacheServe

Figure 4: Policy Based Ratelimiter (nprlObjects) representation

# snmptranslate -Tp SNMPv2-SMI::enterprises.5901.4.21.1


+--nprlObjects(1)
|
+--nprlLimiterTable(1)
| |
| +--nprlLimiterEntry(1)
| | Index: applIndex, nprlLimiterID
| |
| +-- ---- Unsigned nprlLimiterID(1)
| | Range: 1..4294967295
| +-- -R-- String nprlLimiterName(2)
| | Textual Convention: SnmpAdminString
| | Size: 0..255
| +-- -R-- EnumVal nprlLimiterUnenforced(3)
| | Textual Convention: TruthValue
| | Values: true(1), false(2)
| +-- -R-- TimeTicks nprlLimiterReassertTime(4)
| +-- -R-- TimeTicks nprlLimiterDeassertTime(5)
| +-- -R-- Unsigned nprlLimiterTrackerMax(6)
| +-- -R-- BitString nprlLimiterTrackerFields(7)
| | Textual Convention: NomPbRateLimiterTrackerFields
| | Values: other(0), responseClass(1), requestType(2),
responseName(3), clientAddress(4), requestName(5), clientNetwork(6),
responseSize(7)
| +-- -R-- Unsigned nprlLimiterThresholdRequests(8)
| +-- -R-- Counter64 nprlLimiterThresholdOctets(9)
| | Textual Convention: NominumUnsigned64
| +-- -R-- Unsigned nprlLimiterIpV4Prefix(10)
| | Textual Convention: InetAddressPrefixLength
| | Range: 0..2040
| +-- -R-- Unsigned nprlLimiterIpV6Prefix(11)
| | Textual Convention: InetAddressPrefixLength
| | Range: 0..2040
| +-- -R-- Integer32 nprlLimiterRequestNamePostfix(12)
| | Range: -1 | 0 | 1..128
| +-- -R-- String nprlLimiterCreationTime(13)
| | Textual Convention: DateAndTime
| | Size: 8 | 11
| +-- -R-- TimeTicks nprlLimiterRemovedTrackerIdleTime(14)
| +-- -R-- Gauge nprlLimiterCurrTrackers(15)
| +-- -R-- Counter64 nprlLimiterUses(16)
| +-- -R-- Counter64 nprlLimiterIndicationsByRequests(17)
| +-- -R-- Counter64 nprlLimiterIndicationsByOctets(18)
|
+--nprlTrackerTable(2)
|
+-

To reference the nprlLimiterName (element 2 of a ratelimiter entry) for ID 1:

# snmpget -v2c -c test 1.2.3.4 –mALL 1.3.6.1.4.1.5901.4.21.1.1.1.2.1.1


NOMINUM-POLICY-BASED-RATE-LIMITER-MIB::nprlLimiterName.1.1 = STRING: first

Akamai Confidential Page 105


DNSi CacheServe Appendix: CacheServe SNMP objects

Other Examples: SNMPWALK


Fetching DNSi CacheServe statistics can be accomplished by “walking” the server, view or
ratelimiter table as shown in the following examples. Note that the application index (often—
but not always—having value 1) can be specified to select statistics from a particular instance of
DNSi CacheServe in cases where multiple nameservers appear under the management of a
single snmpagent process.

The first example displays the server statistics with the nnsmServerCacheStatsTable
object (referring to this object by name gives the same result as referring to it by OID). The
trailing “.1” following the names of individual entries indicates the application index is 1:

# snmpwalk -v2c -c test 1.2.3.4 1.3.6.1.4.1.5901.4.5.1.1.1

NOMINUM-NSM-MIB::nnsmServerCacheStatsControl.1 = BITS: 00

NOMINUM-NSM-MIB::nnsmServerCacheMemoryInUse.1 = Gauge32: 16558 kilobytes

NOMINUM-NSM-MIB::nnsmServerCacheRecursionContextsActive.1 = Gauge32: 95 recursive lookups

NOMINUM-NSM-MIB::nnsmServerCacheStatsTcpClients.1 = Gauge32: 0 TCP connections

NOMINUM-NSM-MIB::nnsmServerCacheStatsDiscontinuityTime.1 = Timeticks: (79099500) 9 days,


3:43:15.00

NOMINUM-NSM-MIB::nnsmServerCacheStatsRequestNoView.1 = Counter64: 0 DNS requests

NOMINUM-NSM-MIB::nnsmServerCacheStatsRequestRecv.1 = Counter64: 1254 DNS requests

NOMINUM-NSM-MIB::nnsmServerCacheStatsRequestSent.1 = Counter64: 1118 DNS requests

NOMINUM-NSM-MIB::nnsmServerCacheStatsResponseRecv.1 = Counter64: 2864 DNS responses

NOMINUM-NSM-MIB::nnsmServerCacheStatsResponseSent.1 = Counter64: 3254 DNS responses

NOMINUM-NSM-MIB::nnsmServerCacheStatsSystemTime.1 = Counter64: 35 milliseconds

NOMINUM-NSM-MIB::nnsmServerCacheStatsUserTime.1 = Counter64: 83 milliseconds

NOMINUM-NSM-MIB::nnsmServerCacheStatsRequestTcpSent.1 = Counter64: 0 DNS requests

The next example displays the nnsmViewNameToViewIdTable object, which contains the
mapping of view names to ViewIDs:

# snmpwalk -v2c -c test 1.2.3.4 1.3.6.1.4.1.5901.4.5.1.2.1

NOMINUM-NSM-MIB::nnsmViewNameToViewID.1."TEST0" = Gauge32: 2

NOMINUM-NSM-MIB::nnsmViewNameToViewID.1."WORLD" = Gauge32: 1

We see that views “test0” and “world” have been assigned ViewIDs 2 and 1, respectively.

Page 106 Akamai Confidential


Appendix: CacheServe SNMP objects DNSi CacheServe

The contents of the nnsmViewNameToViewIdTable object can be used to determine the


“world” view’s ViewID in other instances of DNSi CacheServe on this agent. To get the “world”
ViewID for application index 2, use an SNMPget which is indexed by its decimal-valued ASCII-
encoded name:
SNMPv2-SMI::enterprises.5901.4.5.1.2.1.1.2.2.5.87.79.82.76.68

In this example, the right-most “2” specifies the application index, and the “5” refers to the
number of characters in the string.

Akamai Confidential Page 107


DNSi CacheServe Appendix: CacheServe Solaris 11
Installation Notes

Appendix: CacheServe Solaris 11 Installation Notes


Akamai’s CacheServe 7.6 ships as a single file. The distribution for CacheServe 7.6.0.2 for Solaris
11 (64-bit “Intel” architecture) is called cacheserve-7.6.0.2-234542-solaris-
11.3-x86_64.tar.gz (approximately 1 GB). CacheServe installation on Solaris utilizes the
pkgadd facility, but it is first necessary to uncompress and untar the distribution. This will
require a total of about 2 GB of free disk space.

# gunzip cacheserve-7.6.0.2-234542-solaris-11.3-x86_64.tar.gz
# tar xvf cacheserve-7.6.0.2-234542-solaris-11.3-x86_64.tar

When the process of unpacking the files is complete, you will see a subdirectory called
cacheserve-7.6.0.2-234542. Change to that directory now:

# cd cacheserve-7.6.0.2-234542 /

You should find the following files:

INSTALL
UPGRADE
NOMbundle-tools-19.1.0.0.234542-sol11.3-x86_64

NOMcacheserve-7.6.0.2.234542-sol11.3-x86_64

NOMipanon-tool-19.1.0.0.234542-sol11.3-x86_64

NOMsnmpagent-19.1.0.0.234542-sol11.3-x86_64

NOMstatmon-19.1.0.0.234542-sol11.3-x86_64

NOMtimezone-data-2019.2.0.0.234542-sol11.3-x86_64

NOMutils-19.1.0.0.234542-sol11.3-x86_64

The files for later versions of the CacheServe package will have slightly different names.

Page 108 Akamai Confidential


Appendix: CacheServe Solaris 11 Installation Notes DNSi CacheServe

Note that the NOMutils package must be installed first, followed by the
NOMtimezone-data and NOMcacheserve packages. The other packages

 (NOMstatmon , NOMbundle-tools and NOMsnmpagent) are optional.


For the purposes of the course, install all of them.

Do not install the NOMipanon-tool package.

Install the packages using the command pkgadd -d:

# pkgadd –d NOMutils-19.1.0.0.234542-sol11.3-x86_64 all


# pkgadd –d NOMtimezone-data-2019.2.0.0.234542-sol11.3-x86_64 all
# pkgadd –d NOMcacheserve-7.6.0.2.234542-sol11.3-x86_64 all
# pkgadd –d NOMsnmpagent-19.1.0.0.234542-sol11.3-x86_64 all
# pkgadd –d NOMstatmon-19.1.0.0.234542-sol11.3-x86_64 all
# pkgadd –d NOMbundle-tools-19.1.0.0.234542-sol11.3-x86_64 all

There is no option to change the installation location. The only supported location for
CacheServe is in /usr/local/nom/.

Note that the installation creates a service script which will attempt the shutdown of
CacheServe whenever the system terminates gracefully (ie via /sbin/shutdown or similar),
as well as start the CacheServe on boot. These capabilities are controlled through the
/usr/sbin/svcadm enable cacheserve and /usr/sbin/svcadm disable
cacheserve commands. As an alternative use the -t flag which means that start on boot will
not be affected: /usr/sbin/svcadm disable -t cacheserve

To check the status of the service use svcs -x cacheserve

A note on logging:

By default, CacheServer writes log output through the host’s syslog utility using the daemon
facility. However, the default configuration of Solaris displays only messages of priority

Akamai Confidential Page 109


DNSi CacheServe Appendix: CacheServe Solaris 11
Installation Notes

NOTICE. If it appears that CacheServe logging is not printed to syslog, be sure to confirm
that syslog is configured to record daemon messages at priority INFO:

e. Check that /etc/syslog.conf contains facility and level declaration


daemon.info . If not, add a line similar to the following:

daemon.info /var/adm/messages

 The two fields in the syslog.conf file are TAB separated. See the syslogd
and syslog.conf man pages for more information.

f. If the destination file (/var/adm/messages, in the example above) does


not yet exist, be sure to touch the file. Reload the syslogd process by
sending the HUP signal.

Page 110 Akamai Confidential


Appendix: CacheServe RHEL7 Installation Notes DNSi CacheServe

Appendix: CacheServe RHEL7 Installation Notes


Akamai’s CacheServe ships as a single file. The distribution for the current release of
CacheServe 7.6 on Red Hat EL 7 64-bit is called cacheserve-7.6.1.0-243307-rhel-7-
x86_64.tar.gz (approximately 140 MB). The six-digit number between the version number
and the platform name is the Akamai build number.

CacheServe installation on Red Hat utilizes the operating system’s “RPM” package facility, but it
is first necessary to uncompress and untar the distribution:

# tar xvzf cacheserve-7.6.1.0-243307-rhel-7-x86_64.tar.gz

This command can be executed anywhere on the system with sufficient disk space.

Untarring the distribution kit will create a subdirectory cacheserve-7.6.1.0-243307 in


your current working directory. Change to this new directory:

# cd cacheserve-7.6.1.0-243307/

You should find the following files (subsequent releases will include components with slightly
different filenames):

INSTALL
UPGRADE

cacheserve-7.6.1.0-243307.el7.x86_64.rpm

ipanon-tool-19.1.2.0-243307.el7.x86_64.rpm

nom-bundle-tools-19.1.2.0-243307.el7.x86_64.rpm

nom-timezone-data-2020.2.0.0-243307.el7.x86_64.rpm

nomutils-19.1.2.0-243307.el7.x86_64.rpm

snmpagent-19.1.2.0-243307.el7.x86_64.rpm

statmon-19.1.2.0-243307.el7.x86_64.rpm

Akamai Confidential Page 111


DNSi CacheServe Appendix: CacheServe RHEL7
Installation Notes

 Note that the nomutils package must be added first, followed by other
packages. Do not install the tool to generate anonymous IP addresses from the
querystore (ipanon-tool).

Add the packages using the “install” command rpm –ivh:

# rpm -ivh nomutils-19.1.2.0-243307.el7.x86_64.rpm


# rpm -ivh nom-bundle-tools-19.1.2.0-243307.el7.x86_64.rpm
# rpm -ivh nom-timezone-data-2020.2.0.0-243307.el7.x86_64.rpm
# rpm -ivh cacheserve-7.6.1.0-243307.el7.x86_64.rpm
# rpm -ivh statmon-19.1.2.0-243307.el7.x86_64.rpm
# rpm -ivh snmpagent-19.1.2.0-243307.el7.x86_64.rpm

All packages are tagged with the RPM group Nominum, so the following command will list all
Akamai-supplied packages installed on the host:

# rpm –q –g Nominum

There is no option for the installation location. The only supported location is
/usr/local/nom/.

To view the package registration information, use commands such as the following:

# rpm –q –i nomutils
# rpm –q –i ans

To view the list of files installed by the package, use commands such as the following:

Page 112 Akamai Confidential


Appendix: CacheServe RHEL7 Installation Notes DNSi CacheServe

# rpm -q -l nomutils
# rpm -q -l cacheserve

Note that the installation enables CacheServe as a systemd service


/usr/lib/systemd/system/cacheserve.service which will attempt the shutdown
of CacheServe whenever the system terminates gracefully (ie via /sbin/shutdown or
similar), as well as start the CacheServe on boot.

Like other Red Hat service scripts, this allows starting and stopping of the application with the
service command /bin/systemctl start cacheserve and /bin/systemctl
stop cacheserve .

Akamai Confidential Page 113


DNSi CacheServe Appendix: Perl API Installation Notes

Appendix: Perl API Installation Notes


Before attempting to make use of the Perl language bindings for the Command Channel, make
sure the Perl API is installed. This requires a separate distribution file called nomsdk-
3.0.0.1-1.tar.gz. Upon expanding this file to a temporary directory, you will find the
Perl files in the directory nomsdk-3.0.0.1-1/perl.

1: HOW TO prepare the Perl environment for Nominum’s CC API


In order to install the Nominum Command Channel API, your Perl environment must satisfy the
following prerequisites:

• Perl version 5.6 or above


• The following modules must be available
o Digest (base)
o Digest::SHA1
o Digest::HMAC
Installing in the order presented here reduces the number of failed dependencies. Older
versions of the Perl API required the Digest::MD5 module as well, but this requirement has been
relaxed.

Modules which fulfill the prerequisites can be found using yum or CPAN (see note below) and
are installed using the exact same sequence of steps described here for installing the Nominum
CC API:

• Move the distribution to a directory with at least 1 MB of free space (e.g. /tmp)
• Uzip and unpack:
# tar xvzf nomsdk-3.0.0.1-1.tar.gz

• Change to the Perl subdirectory:


# cd nomsdk-3.0.0.1-1/perl

• Run Perl to create a makefile:


# perl Makefile.PL

• Run make:
# make

• Run make install:


# make install

Page 114 Akamai Confidential


Appendix: Perl API Installation Notes DNSi CacheServe

CPAN is the Comprehensive Perl Archive Network, a large collection of Perl


software and documentation. Some of the software archived at CPAN is required
for use of the Command Channel API with the Nominum::CC libraries. You can
begin exploring at http://www.cpan.org.

A useful search page (http://search.cpan.org) allows you to simply enter the


name of the module you want, and a web page offering a description, revision
history, access to source and a download option will appear.

If CPAN is installed at your site, you add modules with commands such as


# perl –MCPAN –e 'install Digest::SHA1'
# perl –MCPAN –e 'install Socket6'
# perl -MCPAN -e 'install IO::Socket::INET6'
# perl -MCPAN -e 'install Net::DNS::SEC'

Even easier is to install with yum as suggested by the following examples:


# yum install perl-Socket6
# yum install perl-Digest-MD5
# yum install perl-Digest-HMAC

Akamai Confidential Page 115


DNSi CacheServe Appendix: Perl API Installation Notes

2: HOW TO Check Perl’s installed modules


Nominum’s Perl API is provided in the form of a Perl module. To determine if this module (or
any other module) has already been installed, it is useful to know how to list the installed
modules at your site.

The CPAN web site lists several suggestions for listing the installed modules at
http://cpan.org/misc/cpan-faq.html#How_installed_modules.

It is particularly convenient to use Perl’s ExtUtils::Installed module to do this. An example using


this module is found at the CPAN FAQ website. For reference, the script is repeated here. You
can key in and run the following code to get a listing of installed modules:

#!/usr/local/bin/perl

use ExtUtils::Installed;

my $instmod = ExtUtils::Installed->new();

foreach my $module ($instmod->modules()) {

my $version = $instmod->version($module) || "???";

print "$module -- $version\n";

Typical output, following installation of Nominum’s Perl API, might look something like this:

Digest -- 1.05

Digest::HMAC -- 1.01

Digest::SHA1 -- 2.07

Net -- ???

Net::DNS -- 0.42

Net::Telnet -- 3.03

Nominum -- ???

Perl -- 5.8.8

Page 116 Akamai Confidential


Appendix: Perl API Installation Notes DNSi CacheServe

3: Detailed Examination of a Trivial Program


A simple script used to test the Perl API helps us understand several features of the interface,
including CC communications and message structure. The complete code sample (with line
numbers added for ease of reference) is repeated here as a unit:

1 #! /usr/local/bin/perl

2 use Nom::CC::Channel; use Nom::CC::Message;

3 my $conn1 = Nom::CC::Channel->new('cacheserve');

4 my $request = Nom::CC::Message->new ({ type => "version" });

5 my $response = $conn1->send($request);

6 print $response->{version}, "\n";

1 #! /usr/local/bin/perl
The first line of the program gives the path to a Perl installation to be used if the file containing
your script is executed. The version used with the Nominum CC API must be 5.003 or greater.

2 use Nom::CC::Channel; use Nom::CC::Message;


This line declares the Nominum module needed for any programmatic interaction with DNSi
CacheServe, Centris, ANS, DCS, or any other Command Channel listener.

3 my $conn1 = Nom::CC::Channel->new('cacheserve');
The local variable $conn1 is assigned a reference to an object defined by the Nominum Perl
API. Some may prefer to use new Nom::CC::Channel->("cacheserve"); either
syntax will work. Instead of declaring a service, it is possible to specify the connection
parameters directly as shown here:

my $conn2 = new Nom::CC::Channel(PeerAddr => "127.0.0.1",

PeerPort => 12345,

auth => "secret");

Akamai Confidential Page 117


DNSi CacheServe Appendix: Perl API Installation Notes

4 my $request = Nom::CC::Message->new({ type => "version" });

The local variable $request is assigned a reference to an anonymous data structure that
represents the user’s payload in a CC message. The format is a table described by tag/value
pairs, defined in the CC API documentation. The “instruction” is a hash (containing, in this
instance, the single tag/value pair type/version) which itself is a value of a hash member with
the tag _data that is manipulated by the API. If you were to print out this structure using
Dumper($request);you would find something like

$VAR1 = bless( {

'type' => 'version'

}, 'Nom::CC::Message' );

There are several ways to “pretty print” data structures. By formatting the
structures with indentation, it can be easier to visualize their contents and


troubleshoot bugs in your code.

The Perl module Data::Dumper is a popular method; it supports a function


Dumper($request)which formats structures for printing, the output of which
is shown above.

5 my $response = $conn1->send($request);
This invokes the send method with our payload. The message is sent with a timeout of 60
seconds.

The local variable $response is assigned a reference to the received message object. Printing
out the $response we find:

The API shows DNSi CacheServe’s response as a hash containing the result of processing the
request.

Page 118 Akamai Confidential


Appendix: Perl API Installation Notes DNSi CacheServe

$VAR1 = bless( {

'version' => '7.6.0.2',

'expiration' => 'Wed Sep 30 23:59:59 2020',

'platform' => 'rhel-7-x86_64',

'product' => 'Vantio Cacheserve',

'build' => '234542',

'type' => 'version',

'vendor' => 'Akamai'

}, 'Nom::CC::Message' );

6 print $response->{version}, "\n";


The last line of the program selects the data of interest and prints it to standard output.

It is instructive to compare the data structures constructed via the API with those
resulting from the “verbose” command nom-tell –v cacheserve


version. For the most part, API developers are concerned with creating and
manipulating the contents of the _data hash.

Elements that are hidden from the API user include the _ctrl and _auth
structures.

Akamai Confidential Page 119

You might also like