├── .gitignore ├── README.md ├── config_files └── tac_plus │ └── tac_plus.service ├── console-access.md ├── dhcp-server.md ├── dns-server.md ├── dynamic-dns.md ├── images └── rasp-config-01.png ├── network-interface-config.md ├── tacacs-server.md └── traffic-analysis.md /.gitignore: -------------------------------------------------------------------------------- 1 | tacacs_plus/ 2 | *.code-workspace 3 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Raspberry Pi and Network Lab 2 | The Raspberry Pi is an inexpensive computer that makes a great addition to everyone's network lab. In fact, you might want to pickup a few of them for your lab. 3 | 4 | This repository includes some documents I've put together with some ideas on how and where a RPi can be used in a network lab, as well as some quick guides to help you get started quickly. This repository is a work in progress, and some of the guides may not be complete yet. 5 | 6 | ## Raspberry Pi Resources and Overview 7 | I am not going to try to replace the wonderful official documentation available for getting started and setting up a Raspberry Pi. If you are new to RPi, here are very useful links to get started. 8 | 9 | * [Raspberry Pi OS Download Tool](https://www.raspberrypi.com/software/) 10 | * [Raspberry Pi Getting Started Guide](https://www.raspberrypi.com/documentation/computers/getting-started.html) 11 | 12 | 13 | # Possible Uses of a Raspberry Pi in a Network Lab 14 | Here are some great uses for an RPi in your network lab. I'm hoping to create short guides for each of these (and more as I think of them). Please enjoy the guides that I have put together so far! 15 | 16 | * Lab Management Station 17 | * Linux 18 | * [Console Access](console-access.md) 19 | * [Dual Network](network-interface-config.md) 20 | * Python / Programmability 21 | * Client Endpoint (wired/wireless) 22 | * Network Services 23 | * [DHCP](dhcp-server.md) 24 | * [DNS](dns-server.md) 25 | * [Dynamic DNS from DHCP](dynamic-dns.md) 26 | * File Services (SCP, TFTP, FTP, HTTP) 27 | * NTP 28 | * [TACACS](tacacs-server.md) 29 | * RADIUS 30 | * Syslog Server 31 | * [Traffic Analysis / Capture](traffic-analysis.md) 32 | * Application Server 33 | * General Purpose Web Server 34 | * Docker / Containers 35 | 36 | 37 | -------------------------------------------------------------------------------- /config_files/tac_plus/tac_plus.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=TACACS+ daemon instance tacacs 3 | Documentation=man:tac_plus(8) man:tac_plus.conf(5) 4 | After=network.target 5 | 6 | [Service] 7 | Type=simple 8 | ExecStartPre=/usr/local/sbin/tac_plus -P -C /etc/tacacs/tac_plus.config 9 | ExecStart=/usr/local/sbin/tac_plus -G -C /etc/tacacs/tac_plus.config -d 8 -d 16 -l /var/log/tac_plus.log 10 | ExecReload=/bin/sh -c "/usr/local/sbin/tac_plus -P -C /etc/tacacs/tac_plus.config >/dev/null 2>&1" && /bin/kill -HUP $MAINPID 11 | Restart=always 12 | 13 | [Install] 14 | WantedBy=multi-user.target -------------------------------------------------------------------------------- /console-access.md: -------------------------------------------------------------------------------- 1 | # Connect to Switch Console 2 | Every network lab needs a way to console into network devices, it is just inevitable. The Raspberry Pi can make a great terminal/console server for your network lab. Some of the larger units have 4 USB ports, which would allow you to connect up to 4 different devices simultaneously. 3 | 4 | There are many programs you can use for managing connections, but I've always found the basic `screen` application meets the needs I have in my network lab. The Raspberry Pi doesn't have it installed by default, but you can easily fix that. 5 | 6 | 1. Install `screen` application 7 | 8 | ```bash 9 | sudo apt-get install screen 10 | ``` 11 | 12 | 1. Connect the USB serial cable to your RPi and network device. 13 | 14 | 1. Find the serial connection in the `/dev/` directory. Looking in this directory will show you MANY devices, and it can be a bit tricky to recognize the name of the serial connection to your devices. For this example, I'm connecting to a Cisco Catalyst 3650 switch (WS-C3650-24TS-S). Sometimes searching in the manual for the equipment will tell you what to look for. But I've found the "fastest" way to find the name of the device is to compare the contents of the `/dev` directory before I plug in the USB cable to after. Then the one that is "new" is my device. 15 | 16 | ```bash 17 | ls -l /dev/*ACM* 18 | ``` 19 | 20 | > Many (but not all) of the Cisco USB console ports use the `ttyACM` base for the name. This is a good one to remember and look for. 21 | 22 | 1. With the device identified, you can connect to device using screen. 23 | 24 | ```bash 25 | screen /dev/ttyACM0 9600 26 | ``` 27 | 28 | > If your device is configured for a different console speed, just change the 9600 in the command. 29 | 30 | 1. After you are done interacting with the device, disconnect from device cleanly by pressing "Cntl-a" followed by typeing `:quit`. This will quit screen and return you to the Linux shell. 31 | 32 | ```bash 33 | # Press Ctrl-a 34 | :quit 35 | ``` -------------------------------------------------------------------------------- /dhcp-server.md: -------------------------------------------------------------------------------- 1 | # Using a Raspberry Pi as a DHCP Server 2 | * [What DHCP Server Software to Use? dnsmasq vs isc-dhcp](#what-dhcp-server-software-to-use--dnsmasq-vs-isc-dhcp) 3 | * [Installing ISC DHCP Server on Raspberry Pi](#installing-isc-dhcp-server-on-raspberry-pi) 4 | * [Configuring ISC DHCP Server on Raspberry Pi](#configuring-isc-dhcp-server-on-raspberry-pi) 5 | * [Getting an IP address from the server](#getting-an-ip-address-from-the-server) 6 | * [Configuring a Cisco IOS Device as DHCP Client](#configuring-a-cisco-ios-device-as-dhcp-client) 7 | * [Advanced Configuration: Dynamic DNS Updates from ISC DHCP Server -> Bind](#advanced-configuration--dynamic-dns-updates-from-isc-dhcp-server----bind) 8 | * [Final Thoughts](#final-thoughts) 9 | 10 | Table of contents generated with markdown-toc 11 | 12 | One of the most fundamental parts of any network is the allocation of IP addresses. DHCP is key to the automatic, scalable allocation of IPs in a network. DHCP initially shows up on the [CCNA certification](https://learningnetwork.cisco.com/s/ccna-exam-topics) where candidates must understand its role in the network as well as configure client and relay services. You'll find DHCP on professional and expert level certifications as well. 13 | 14 | There are many options for hosting a DHCP server in your network lab, and I have probably tried them all. Some of them include: 15 | 16 | * Many network devices can act as a DHCP server, including Cisco switches and routers 17 | * Consumer grade all-in-one firewall/router/wireless devices provide DHCP services 18 | * Add a server to your lab and run an enterprise DHCP server such as Microsoft DHCP Server or ICS-DHCP on Linux 19 | 20 | Each of the above have pros and cons, and depending on your needs in the lab at a given time one might make more sense than the others. I've always been a fan of the last option, running a "real" DHCP server because that is what most closely lines up with with what I need to work with on the job. However, the cost, overhead, and complexity of setting up a server in the lab is often a challenge. The fan noise alone can get to you eventually. 21 | 22 | That's where the Raspberry Pi comes in as a great option. As a low cost computer, RPis are inexpensive to add to a lab. And because it runs Linux, you can install and use the same DHCP server that you might run across in the office. 23 | 24 | 25 | 26 | ## What DHCP Server Software to Use? dnsmasq vs isc-dhcp 27 | If you do some searching for "DHCP Server for Raspberry Pi", you'll find lots of documentation, blog posts, and forum discussions. I know because I did it. Most of them seem to suggest using [dnsmasq](https://thekelleys.org.uk/dnsmasq/doc.html). This was a bit of a surprise to me, as I've long used [ISC DHCP](https://www.isc.org/dhcp/) as the DHCP server on Linux systems. 28 | 29 | > Note: The ISC DHCP server is often just called `dhcpd`. 30 | 31 | I asked myself, "Why all the love for dnsmasq?" I'd heard of dnsmasq before, but I hadn't really used it. Not wanting to just go with what I've always done, I did some digging to see if I could learn more. What I found broke down to three main reasons: 32 | 33 | 1. dnsmasq provides both DHCP and DNS services in a single package 34 | 1. dnsmasq is simpler to configure (according to opinions I read, not sure of accuracy here) 35 | 1. dnsmasq has a lower cpu and memory footprint than the ISC options of DHCP Server and Bind9 (DNS) 36 | 37 | So which do we use for our network lab? 38 | 39 | In the end, it's up to you. The reasons above are compelling, however I decided to stick with ISC DHCP for my lab. The main reason for this choice was that I'm much more likely to use ISC DHCP in work environments than dnsmasq, and I'd rather lab what I'm going to use in work. 40 | 41 | > There's a secondary reason that most of the examples and documentation written for DHCP related content like ZTP, phones, etc provide ISC DHCP examples. 42 | 43 | ## Installing ISC DHCP Server on Raspberry Pi 44 | The ISC DHCP Server is available in the standard packages for Raspberry Pi, so installation is like any other Linux server. 45 | 46 | 47 | ```bash 48 | sudo apt-get install isc-dhcp-server 49 | 50 | Reading package lists... Done 51 | Building dependency tree... Done 52 | Reading state information... Done 53 | The following additional packages will be installed: 54 | libirs-export161 libisccfg-export163 policycoreutils selinux-utils 55 | Suggested packages: 56 | isc-dhcp-server-ldap 57 | The following NEW packages will be installed: 58 | isc-dhcp-server libirs-export161 libisccfg-export163 policycoreutils selinux-utils 59 | 0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded. 60 | Need to get 1,666 kB of archives. 61 | After this operation, 6,698 kB of additional disk space will be used. 62 | Do you want to continue? [Y/n] y 63 | . 64 | . 65 | . 66 | Setting up isc-dhcp-server (4.4.1-2.3) ... 67 | Generating /etc/default/isc-dhcp-server... 68 | Job for isc-dhcp-server.service failed because the control process exited with error code. 69 | See "systemctl status isc-dhcp-server.service" and "journalctl -xe" for details. 70 | invoke-rc.d: initscript isc-dhcp-server, action "start" failed. 71 | ● isc-dhcp-server.service - LSB: DHCP server 72 | Loaded: loaded (/etc/init.d/isc-dhcp-server; generated) 73 | Active: failed (Result: exit-code) since Sat 2022-02-26 14:30:22 EST; 28ms ago 74 | Docs: man:systemd-sysv-generator(8) 75 | Process: 2132 ExecStart=/etc/init.d/isc-dhcp-server start (code=exited, status=1/FAILURE) 76 | CPU: 123ms 77 | 78 | Feb 26 14:30:20 lab-server dhcpd[2147]: before submitting a bug. These pages explain the proper 79 | Feb 26 14:30:20 lab-server dhcpd[2147]: process and the information we find helpful for debugging. 80 | Feb 26 14:30:20 lab-server dhcpd[2147]: 81 | Feb 26 14:30:20 lab-server dhcpd[2147]: exiting. 82 | Feb 26 14:30:22 lab-server isc-dhcp-server[2132]: Starting ISC DHCPv4 server: dhcpdcheck syslog for diagnostics. ... 83 | Feb 26 14:30:22 lab-server isc-dhcp-server[2160]: failed! 84 | Feb 26 14:30:22 lab-server isc-dhcp-server[2161]: failed! 85 | Feb 26 14:30:22 lab-server systemd[1]: isc-dhcp-server.service: Control process exited, code=exited, status=1/FAILURE 86 | Feb 26 14:30:22 lab-server systemd[1]: isc-dhcp-server.service: Failed with result 'exit-code'. 87 | Feb 26 14:30:22 lab-server systemd[1]: Failed to start LSB: DHCP server. 88 | Processing triggers for libc-bin (2.31-13+rpt2+rpi1+deb11u2) ... 89 | Processing triggers for man-db (2.9.4-2) ... 90 | ``` 91 | 92 | The installation process includes setting up a default configuration file and trying to start the server. This fails on my device because the default configuration file won't work. The output suggests looking at a couple of commands for more detail. The command `journalctl -xe` is one of my favorite troubleshooting commands for Linux. It lets you look at the systemd journal, basically all the logs for what is going on. This will provide the full error messages and logs when a service doesn't start. 93 | 94 | Using this command indicates the problem pretty quickly: 95 | 96 |
Output: journalctl -xe 97 | 98 | ``` 99 | Feb 26 14:39:02 lab-server systemd[1]: Starting LSB: DHCP server... 100 | ░░ Subject: A start job for unit isc-dhcp-server.service has begun execution 101 | ░░ Defined-By: systemd 102 | ░░ Support: https://www.debian.org/support 103 | ░░ 104 | ░░ A start job for unit isc-dhcp-server.service has begun execution. 105 | ░░ 106 | ░░ The job identifier is 776. 107 | Feb 26 14:39:02 lab-server isc-dhcp-server[3037]: Launching both IPv4 and IPv6 servers (please configure INTER> 108 | Feb 26 14:39:02 lab-server dhcpd[3052]: Wrote 0 leases to leases file. 109 | Feb 26 14:39:02 lab-server dhcpd[3052]: 110 | Feb 26 14:39:02 lab-server dhcpd[3052]: No subnet declaration for wlan0 (10.192.81.123). 111 | Feb 26 14:39:02 lab-server dhcpd[3052]: ** Ignoring requests on wlan0. If this is not what 112 | Feb 26 14:39:02 lab-server dhcpd[3052]: you want, please write a subnet declaration 113 | Feb 26 14:39:02 lab-server dhcpd[3052]: in your dhcpd.conf file for the network segment 114 | Feb 26 14:39:02 lab-server dhcpd[3052]: to which interface wlan0 is attached. ** 115 | Feb 26 14:39:02 lab-server dhcpd[3052]: 116 | Feb 26 14:39:02 lab-server dhcpd[3052]: No subnet declaration for eth0 (192.168.192.11). 117 | Feb 26 14:39:02 lab-server dhcpd[3052]: ** Ignoring requests on eth0. If this is not what 118 | Feb 26 14:39:02 lab-server dhcpd[3052]: you want, please write a subnet declaration 119 | Feb 26 14:39:02 lab-server dhcpd[3052]: in your dhcpd.conf file for the network segment 120 | Feb 26 14:39:02 lab-server dhcpd[3052]: to which interface eth0 is attached. ** 121 | Feb 26 14:39:02 lab-server dhcpd[3052]: 122 | Feb 26 14:39:02 lab-server dhcpd[3052]: 123 | Feb 26 14:39:02 lab-server dhcpd[3052]: Not configured to listen on any interfaces! 124 | Feb 26 14:39:02 lab-server dhcpd[3052]: 125 | Feb 26 14:39:02 lab-server dhcpd[3052]: If you think you have received this message due to a bug rather 126 | Feb 26 14:39:02 lab-server dhcpd[3052]: than a configuration issue please read the section on submitting 127 | Feb 26 14:39:02 lab-server dhcpd[3052]: bugs on either our web page at www.isc.org or in the README file 128 | Feb 26 14:39:02 lab-server dhcpd[3052]: before submitting a bug. These pages explain the proper 129 | Feb 26 14:39:02 lab-server dhcpd[3052]: process and the information we find helpful for debugging. 130 | Feb 26 14:39:02 lab-server dhcpd[3052]: 131 | Feb 26 14:39:02 lab-server dhcpd[3052]: exiting. 132 | Feb 26 14:39:04 lab-server isc-dhcp-server[3037]: Starting ISC DHCPv4 server: dhcpdcheck syslog for diagnostic> 133 | Feb 26 14:39:04 lab-server isc-dhcp-server[3057]: failed! 134 | Feb 26 14:39:04 lab-server isc-dhcp-server[3058]: failed! 135 | Feb 26 14:39:04 lab-server systemd[1]: isc-dhcp-server.service: Control process exited, code=exited, status=1/> 136 | ░░ Subject: Unit process exited 137 | ░░ Defined-By: systemd 138 | ░░ Support: https://www.debian.org/support 139 | ░░ 140 | ░░ An ExecStart= process belonging to unit isc-dhcp-server.service has exited. 141 | ░░ 142 | ░░ The process' exit code is 'exited' and its exit status is 1. 143 | Feb 26 14:39:04 lab-server systemd[1]: isc-dhcp-server.service: Failed with result 'exit-code'. 144 | ░░ Subject: Unit failed 145 | ░░ Defined-By: systemd 146 | ░░ Support: https://www.debian.org/support 147 | ░░ 148 | ░░ The unit isc-dhcp-server.service has entered the 'failed' state with result 'exit-code'. 149 | Feb 26 14:39:04 lab-server systemd[1]: Failed to start LSB: DHCP server. 150 | ░░ Subject: A start job for unit isc-dhcp-server.service has failed 151 | ░░ Defined-By: systemd 152 | ░░ Support: https://www.debian.org/support 153 | ░░ 154 | ░░ A start job for unit isc-dhcp-server.service has finished with a failure. 155 | ░░ 156 | ░░ The job identifier is 776 and the job result is failed. 157 | ``` 158 | 159 |
160 | 161 | The issue is that there are no subnet declarations for the configured networks found on the server and no interfaces are configured to listen for requests. 162 | 163 | ## Configuring ISC DHCP Server on Raspberry Pi 164 | The odds are that you already have a DHCP server running on your home network. So you need to be careful to NOT add a second DHCP server and cause problems for the rest of your network. I can attest to the fact that breaking access to video streaming services, social media, and video games for the other people who share your home doesn't go over well. 165 | 166 | With this in mind, I want to setup DHCP on my lab network: 167 | 168 | * Only on the `eth0` interface that is connected to my lab 169 | * Only on the lab subnet 170 | 171 | > For the full configuration guide for ISC DHCP go [here](https://kb.isc.org/docs/isc-dhcp-44-manual-pages-dhcpdconf). What follows is a basic example configuration for a network lab. 172 | 173 | > ISC DHCP is often referred to as `dhcpd`. This will be used going forward. 174 | 175 | 1. First up, let's backup the default configuration file that is installed with `dhcpd`. This file is a great resource for seeing example configurations for common setups. 176 | 177 | ```bash 178 | sudo mv /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.backup 179 | ``` 180 | 181 | 1. Now create a new file with your desired configuration. 182 | 183 | ```bash 184 | # dhcpd.conf 185 | 186 | # DNS Configuration for the network lab 187 | option domain-name "lab.example"; 188 | option domain-name-servers 192.168.192.11; 189 | 190 | # Setting the default lease time to 2 minutes and max to 1 hour 191 | default-lease-time 120; 192 | max-lease-time 3600; 193 | 194 | # This is the subnet on my home network. No configuration is 195 | # provided because I don't want to listen/reply to requests 196 | # but adding it avoids errors/warnings from the service 197 | subnet 10.192.81.0 netmask 255.255.255.128 { 198 | } 199 | 200 | # This is my network lab segment configured on eth0 201 | # A range of IPs to assign is provided, as well as the 202 | # default gateway/router 203 | subnet 192.168.192.0 netmask 255.255.255.0 { 204 | range 192.168.192.101 192.168.192.120; 205 | option routers 192.168.192.1; 206 | } 207 | 208 | # This assigns a static IP address to a lab client device 209 | host lab-client { 210 | hardware ethernet b8:27:eb:d3:22:e7; 211 | fixed-address 192.168.192.12; 212 | } 213 | ``` 214 | 215 | 1. In addition to the configuration file you need to indicate the interface on which you want the ISC DHCP server to listen. This is done in the `/etc/default/isc-dhcp-server` file. Just add `eth0` to the `INTERFACESv4` list. 216 | 217 | > If you are setting up DHCPv6 ad well, add the interface in that line as well. 218 | 219 | ```bash 220 | # On what interfaces should the DHCP server (dhcpd) serve DHCP requests? 221 | # Separate multiple interfaces with spaces, e.g. "eth0 eth1". 222 | INTERFACESv4="eth0" 223 | INTERFACESv6="" 224 | ``` 225 | 226 | 1. Now restart the `dhcpd` service to apply the configuration. 227 | 228 | ``` 229 | sudo systemctl restart isc-dhcp-server 230 | ``` 231 | 232 | > If the service reports errors after making the configuration changes and trying to start the service, you may need to restart the RPi (`sudo shutdown -r now`). I had this happen in one of my tests. Likely some service interaction/conflict on startup was causing issues. 233 | 234 | 1. Check the status of the server. 235 | 236 | ``` 237 | systemctl status isc-dhcp-server.service 238 | ● isc-dhcp-server.service - LSB: DHCP server 239 | Loaded: loaded (/etc/init.d/isc-dhcp-server; generated) 240 | Active: active (running) since Sat 2022-02-26 15:31:40 EST; 17s ago 241 | Docs: man:systemd-sysv-generator(8) 242 | Process: 813 ExecStart=/etc/init.d/isc-dhcp-server start (code=exited, status=0/SUCCESS) 243 | Tasks: 4 (limit: 780) 244 | CPU: 154ms 245 | CGroup: /system.slice/isc-dhcp-server.service 246 | └─828 /usr/sbin/dhcpd -4 -q -cf /etc/dhcp/dhcpd.conf eth0 247 | 248 | Feb 26 15:31:37 lab-server systemd[1]: Starting LSB: DHCP server... 249 | Feb 26 15:31:37 lab-server isc-dhcp-server[813]: Launching IPv4 server only. 250 | Feb 26 15:31:37 lab-server dhcpd[828]: Wrote 0 deleted host decls to leases file. 251 | Feb 26 15:31:37 lab-server dhcpd[828]: Wrote 0 new dynamic host decls to leases file. 252 | Feb 26 15:31:37 lab-server dhcpd[828]: Wrote 0 leases to leases file. 253 | Feb 26 15:31:37 lab-server dhcpd[828]: Server starting service. 254 | Feb 26 15:31:40 lab-server isc-dhcp-server[813]: Starting ISC DHCPv4 server: dhcpd. 255 | Feb 26 15:31:40 lab-server systemd[1]: Started LSB: DHCP server. 256 | ``` 257 | 258 | ## Getting an IP address from the server 259 | Now that we have the DHCP Server running on one RPi, let's try to get an IP address assigned to our `lab-client` RPi. 260 | 261 | 1. I had configured my `lab-client` RPi for static IP address on its `eth0` interface so my first step was to comment out the static IP configuration in `/etc/dhcpcd.conf` 262 | 263 | ```bash 264 | # Home Network Lab Setup 265 | #interface eth0 266 | #static ip_address=192.168.192.12/24 267 | #static domain_name_servers=192.168.192.11 268 | ``` 269 | 270 | 1. To apply the changes to `dhcpcd`, just restart the service. 271 | 272 | ```bash 273 | sudo systemctl restart dhcpcd 274 | ``` 275 | 276 | 1. After a few seconds, you can check to see if you have an address on the interface. 277 | 278 | ```bash 279 | ip address show dev eth0 280 | 281 | # Output 282 | 2: eth0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 283 | link/ether b8:27:eb:d3:22:e7 brd ff:ff:ff:ff:ff:ff 284 | inet 192.168.192.12/24 brd 192.168.192.255 scope global dynamic noprefixroute eth0 285 | valid_lft 229sec preferred_lft 191sec 286 | inet6 fe80::1f14:692e:59db:d878/64 scope link 287 | valid_lft forever preferred_lft forever 288 | ``` 289 | 290 | 1. Even better, check the logs/journaly for the dhcpcd client. 291 | 292 | ```bash 293 | journalctl -u dhcpcd | grep eth0 294 | Feb 26 15:35:25 lab-client dhcpcd[4513]: eth0: removing interface 295 | Feb 26 15:35:26 lab-client dhcpcd[11433]: eth0: IAID eb:d3:22:e7 296 | Feb 26 15:35:26 lab-client dhcpcd[11433]: eth0: soliciting a DHCP lease 297 | Feb 26 15:35:26 lab-client dhcpcd[11433]: eth0: offered 192.168.192.12 from 192.168.192.11 298 | Feb 26 15:35:26 lab-client dhcpcd[11433]: eth0: leased 192.168.192.12 for 300 seconds 299 | Feb 26 15:35:26 lab-client dhcpcd[11433]: eth0: adding route to 192.168.192.0/24 300 | Feb 26 15:35:26 lab-client dhcpcd[11433]: eth0: adding default route via 192.168.192.1 301 | Feb 26 15:35:27 lab-client dhcpcd[11533]: eth0: soliciting an IPv6 router 302 | Feb 26 15:36:11 lab-client dhcpcd[11533]: eth0: no IPv6 Routers available 303 | ``` 304 | 305 | > `-u dhcpcd` limits the messages from the journal just to the DHCP Client. And by `grep eth0` we can limit to just messages related to the interface we are interested in. 306 | 307 | 1. Over on `lab-server` that is the DHCP Server, we can check the logs to see the view from the server side. 308 | 309 | ```bash 310 | journalctl -u isc-dhcp-server -n 20 311 | 312 | # Output 313 | -- Journal begins at Thu 2022-01-27 22:15:01 EST, ends at Sat 2022-02-26 15:51:25 EST. -- 314 | Feb 26 15:31:37 lab-server dhcpd[828]: Wrote 0 leases to leases file. 315 | Feb 26 15:31:37 lab-server dhcpd[828]: Server starting service. 316 | Feb 26 15:31:40 lab-server isc-dhcp-server[813]: Starting ISC DHCPv4 server: dhcpd. 317 | Feb 26 15:31:40 lab-server systemd[1]: Started LSB: DHCP server. 318 | Feb 26 15:35:26 lab-server dhcpd[828]: DHCPDISCOVER from b8:27:eb:d3:22:e7 via eth0 319 | Feb 26 15:35:26 lab-server dhcpd[828]: DHCPOFFER on 192.168.192.12 to b8:27:eb:d3:22:e7 via eth0 320 | Feb 26 15:35:26 lab-server dhcpd[828]: DHCPREQUEST for 192.168.192.12 (192.168.192.11) from b8:27:eb:d3:22:e7 > 321 | Feb 26 15:35:26 lab-server dhcpd[828]: DHCPACK on 192.168.192.12 to b8:27:eb:d3:22:e7 via eth0 322 | Feb 26 15:37:56 lab-server dhcpd[828]: DHCPREQUEST for 192.168.192.12 from b8:27:eb:d3:22:e7 via eth0 323 | Feb 26 15:37:56 lab-server dhcpd[828]: DHCPACK on 192.168.192.12 to b8:27:eb:d3:22:e7 via eth0 324 | Feb 26 15:40:26 lab-server dhcpd[828]: DHCPREQUEST for 192.168.192.12 from b8:27:eb:d3:22:e7 via eth0 325 | Feb 26 15:40:26 lab-server dhcpd[828]: DHCPACK on 192.168.192.12 to b8:27:eb:d3:22:e7 via eth0 326 | Feb 26 15:42:56 lab-server dhcpd[828]: DHCPREQUEST for 192.168.192.12 from b8:27:eb:d3:22:e7 via eth0 327 | Feb 26 15:42:56 lab-server dhcpd[828]: DHCPACK on 192.168.192.12 to b8:27:eb:d3:22:e7 via eth0 328 | Feb 26 15:45:26 lab-server dhcpd[828]: DHCPREQUEST for 192.168.192.12 from b8:27:eb:d3:22:e7 via eth0 329 | Feb 26 15:45:26 lab-server dhcpd[828]: DHCPACK on 192.168.192.12 to b8:27:eb:d3:22:e7 via eth0 330 | Feb 26 15:50:26 lab-server dhcpd[828]: DHCPREQUEST for 192.168.192.12 from b8:27:eb:d3:22:e7 via eth0 331 | Feb 26 15:50:26 lab-server dhcpd[828]: DHCPACK on 192.168.192.12 to b8:27:eb:d3:22:e7 via eth0 332 | Feb 26 15:52:56 lab-server dhcpd[828]: DHCPREQUEST for 192.168.192.12 from b8:27:eb:d3:22:e7 via eth0 333 | Feb 26 15:52:56 lab-server dhcpd[828]: DHCPACK on 192.168.192.12 to b8:27:eb:d3:22:e7 via eth0 334 | ``` 335 | 336 | > `-n 20` limits to just the most recent 20 lines. This avoids seeing all the messages about service startup. And notice that the `DHCPREQUEST` / `DHCPACK` are coming in every 2 minutes. This is from the shorter lease time we configured. 337 | 338 | > Tip: You can also add a `-f` to the `journalctl` command to "follow" and get updates as they come in. 339 | 340 | ## Configuring a Cisco IOS Device as DHCP Client 341 | This is a networking lab discussion, let's configure an interface on a network device to recieve an IP address from the DHCP server. 342 | 343 | > For this example I am using a Cisco Catalyst 3650 switch (WS-C3650-24TS-S). The lab network is `vlan 192`. 344 | 345 | 1. Configure the interface for dhcp 346 | 347 | ``` 348 | lab-switch#conf t 349 | Enter configuration commands, one per line. End with CNTL/Z. 350 | lab-switch(config)#interface vlan 192 351 | lab-switch(config-if)#ip address dhcp 352 | ``` 353 | 354 | 1. After a few seconds the following console output was logged 355 | 356 | ``` 357 | *Feb 26 20:33:00.206: %DHCP-6-ADDRESS_ASSIGN: Interface Vlan192 assigned DHCP address 192.168.192.101, mask 255.255.255.0, hostname lab-switch 358 | ``` 359 | 360 | 1. And checking the logs/journal on the DHCP server shows the full `DISCOVER > OFFER > REQUEST > ACK` process. 361 | 362 | ``` 363 | Feb 26 16:00:05 lab-server dhcpd[828]: DHCPDISCOVER from a0:ec:f9:ab:39:d3 via eth0 364 | Feb 26 16:00:06 lab-server dhcpd[828]: DHCPOFFER on 192.168.192.101 to a0:ec:f9:ab:39:d3 (lab-switch) via eth0 365 | Feb 26 16:00:06 lab-server dhcpd[828]: DHCPREQUEST for 192.168.192.101 (192.168.192.11) from a0:ec:f9:ab:39:d3 (lab-switch) via eth0 366 | Feb 26 16:00:06 lab-server dhcpd[828]: DHCPACK on 192.168.192.101 to a0:ec:f9:ab:39:d3 (lab-switch) via eth0 367 | ``` 368 | 369 | ## Advanced Configuration: Dynamic DNS Updates from ISC DHCP Server -> Bind 370 | If you are truly going to get the benefits of DHCP and DNS in your lab, you'll likely want DNS to work for clients who receive IP addresses via DHCP as well. 371 | 372 | Checkout the [Dynamic DNS - dhcpd to bind](dynamic-dns.md) guide for details on that setup. 373 | 374 | ## Final Thoughts 375 | Now we have a full featured DHCP server running in our lab. This doc just scratched the surface of DHCP configuration and exploration you might do. From here somethings you can explore include: 376 | 377 | * DHCP Relay configuration from other VLANs/networks to the server 378 | * PXE or ZTP configuration using dhcp options 379 | * IP Phone configuration of settings like TFTP server 380 | * DHCPv6 configuration 381 | * DHCP debugging -------------------------------------------------------------------------------- /dns-server.md: -------------------------------------------------------------------------------- 1 | # Using a Raspberry Pi as a DNS Server 2 | * [What DNS Server Software to Use? dnsmasq vs Bind](#what-dns-server-software-to-use--dnsmasq-vs-bind) 3 | * [Installing Bind9 on Raspberry Pi](#installing-bind9-on-raspberry-pi) 4 | * [Testing DNS Resolution](#testing-dns-resolution) 5 | * [Configuring the `lab-server` to use itself for DNS lookups](#configuring-the--lab-server--to-use-itself-for-dns-lookups) 6 | * [Configuring Bind9 on Raspberry Pi](#configuring-bind9-on-raspberry-pi) 7 | * [Verifying DNS Lookups on Lab Clients](#verifying-dns-lookups-on-lab-clients) 8 | + [Testing on an RPi `lab-client`](#testing-on-an-rpi--lab-client-) 9 | + [Testing from a Network Device](#testing-from-a-network-device) 10 | * [Advanced Configuration: Dynamic DNS Updates from ISC DHCP Server -> Bind](#advanced-configuration--dynamic-dns-updates-from-isc-dhcp-server----bind) 11 | * [Final Thoughts](#final-thoughts) 12 | 13 | Table of contents generated with markdown-toc 14 | 15 | 16 | Right up there with DHCP, DNS is a fundamental part of any network. Few people other than network engineers actually LIKE to remember and refer to servers, applications, etc by their IP address. Nope... people like to use names. And that's where DNS comes in. Also like DHCP, DNS shows up on the [CCNA certification](https://learningnetwork.cisco.com/s/ccna-exam-topics) as well as popping up in many other professional, specialist, and expert certifications. 17 | 18 | There are options for hosting a DNS server in your network lab, the most common I've seen include: 19 | 20 | * Some network devices can act as a DNS server 21 | * Add a server to your lab and run an enterprise DNS server such as Microsoft DNS Server or Bind on Linux 22 | 23 | The option of using [configuring a network router](https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/ipaddr_dns/configuration/15-sy/dns-15-sy-book/Configuring-DNS.html#GUID-B35BAE29-08A7-4ACE-94FE-7950A4422202) to act as a DNS server is something I have done in many labs. And while it works, it's really not a good solution. For one, it is something you'll likely never see actually used in a real network. And secondly, the DNS server in most network devices is very limited and doesn't support many of the DNS features needed in modern networks. 24 | 25 | So the best option is the second, and that's where the Raspberry Pi comes in as a great option. As a low cost computer, RPis are inexpensive to add to a lab. And because it runs Linux, you can install and use the same DNS server that you might run across in the office. 26 | 27 | ## What DNS Server Software to Use? dnsmasq vs Bind 28 | If you do some searching for "DNS Server for Raspberry Pi", you'll find lots of documentation, blog 29 | posts, and forum discussions. I know because I did it. Most of them seem to suggest using [dnsmasq](https://thekelleys.org.uk/dnsmasq/doc.html). This was a bit of a surprise to me, as I've long used [Bind](https://www.isc.org/bind/) as the DNS server on Linux systems. 30 | 31 | > Note: Today "Bind" is really "Bind9". 32 | 33 | I asked myself, "Why all the love for dnsmasq?" I'd heard of dnsmasq before, but I hadn't really used it. Not wanting to just go with what I've always done, I did some digging to see if I could learn more. What I found broke down to three main reasons: 34 | 35 | 1. dnsmasq provides both DHCP and DNS services in a single package 36 | 1. dnsmasq is simpler to configure (according to opinions I read, not sure of accuracy here) 37 | 1. dnsmasq has a lower cpu and memory footprint than the ISC options of DHCP Server and Bind9 (DNS) 38 | 39 | So which do we use for our network lab? 40 | 41 | In the end, it's up to you. The reasons above are compelling, however I decided to stick with Bind9 for my lab. The main reason for this choice was that I'm much more likely to use Bind9 in work environments than dnsmasq, and I'd rather lab what I'm going to use in work. 42 | 43 | > Note: There are other DNS servers for Linux that could be used. And some are used regularly in enterprise environment. Bind9 continues to be popular, and is the one I'm most familar with, so that's what I used ;-) 44 | 45 | ## Installing Bind9 on Raspberry Pi 46 | Bind9 is available in the standard packages for Raspberry Pi, so installation is like any other Linux server. 47 | 48 | ```bash 49 | sudo apt-get install bind9 bind9utils dnsutils 50 | ``` 51 | 52 | > Note: In addition to bind9, I'm also installing very useful utilities for DNS. The `dnsutils` is a great package to also include on your `lab-client` devices to allow lookups using tools like `dig`. 53 | 54 |
Output: Installation Command 55 | 56 | ``` 57 | # Output 58 | Reading package lists... Done 59 | Building dependency tree... Done 60 | Reading state information... Done 61 | The following additional packages will be installed: 62 | bind9-dnsutils bind9-utils dns-root-data python3-ply 63 | Suggested packages: 64 | bind-doc ufw python-ply-doc 65 | The following NEW packages will be installed: 66 | bind9 bind9-dnsutils bind9-utils bind9utils dns-root-data dnsutils python3-ply 67 | 0 upgraded, 7 newly installed, 0 to remove and 0 not upgraded. 68 | Need to get 1,873 kB of archives. 69 | After this operation, 3,494 kB of additional disk space will be used. 70 | Do you want to continue? [Y/n] y 71 | Get:1 http://deb.debian.org/debian bullseye/main arm64 python3-ply all 3.11-4 [65.5 kB] 72 | Get:2 http://deb.debian.org/debian bullseye/main arm64 bind9-utils arm64 1:9.16.22-1~deb11u1 [421 kB] 73 | Get:3 http://deb.debian.org/debian bullseye/main arm64 dns-root-data all 2021011101 [5,524 B] 74 | Get:4 http://deb.debian.org/debian bullseye/main arm64 bind9 arm64 1:9.16.22-1~deb11u1 [472 kB] 75 | Get:5 http://deb.debian.org/debian bullseye/main arm64 bind9-dnsutils arm64 1:9.16.22-1~deb11u1 [390 kB] 76 | Get:6 http://deb.debian.org/debian bullseye/main arm64 bind9utils all 1:9.16.22-1~deb11u1 [260 kB] 77 | Get:7 http://deb.debian.org/debian bullseye/main arm64 dnsutils all 1:9.16.22-1~deb11u1 [260 kB] 78 | Fetched 1,873 kB in 1s (1,603 kB/s) 79 | Selecting previously unselected package python3-ply. 80 | (Reading database ... 35899 files and directories currently installed.) 81 | Preparing to unpack .../0-python3-ply_3.11-4_all.deb ... 82 | Unpacking python3-ply (3.11-4) ... 83 | Selecting previously unselected package bind9-utils. 84 | Preparing to unpack .../1-bind9-utils_1%3a9.16.22-1~deb11u1_arm64.deb ... 85 | Unpacking bind9-utils (1:9.16.22-1~deb11u1) ... 86 | Selecting previously unselected package dns-root-data. 87 | Preparing to unpack .../2-dns-root-data_2021011101_all.deb ... 88 | Unpacking dns-root-data (2021011101) ... 89 | Selecting previously unselected package bind9. 90 | Preparing to unpack .../3-bind9_1%3a9.16.22-1~deb11u1_arm64.deb ... 91 | Unpacking bind9 (1:9.16.22-1~deb11u1) ... 92 | Selecting previously unselected package bind9-dnsutils. 93 | Preparing to unpack .../4-bind9-dnsutils_1%3a9.16.22-1~deb11u1_arm64.deb ... 94 | Unpacking bind9-dnsutils (1:9.16.22-1~deb11u1) ... 95 | Selecting previously unselected package bind9utils. 96 | Preparing to unpack .../5-bind9utils_1%3a9.16.22-1~deb11u1_all.deb ... 97 | Unpacking bind9utils (1:9.16.22-1~deb11u1) ... 98 | Selecting previously unselected package dnsutils. 99 | Preparing to unpack .../6-dnsutils_1%3a9.16.22-1~deb11u1_all.deb ... 100 | Unpacking dnsutils (1:9.16.22-1~deb11u1) ... 101 | Setting up python3-ply (3.11-4) ... 102 | Setting up dns-root-data (2021011101) ... 103 | Setting up bind9-utils (1:9.16.22-1~deb11u1) ... 104 | Setting up bind9 (1:9.16.22-1~deb11u1) ... 105 | Adding group `bind' (GID 114) ... 106 | Done. 107 | Adding system user `bind' (UID 109) ... 108 | Adding new user `bind' (UID 109) with group `bind' ... 109 | Not creating home directory `/var/cache/bind'. 110 | wrote key file "/etc/bind/rndc.key" 111 | named-resolvconf.service is a disabled or a static unit, not starting it. 112 | Created symlink /etc/systemd/system/bind9.service → /lib/systemd/system/named.service. 113 | Created symlink /etc/systemd/system/multi-user.target.wants/named.service → /lib/systemd/system/named.service. 114 | Setting up bind9utils (1:9.16.22-1~deb11u1) ... 115 | Setting up bind9-dnsutils (1:9.16.22-1~deb11u1) ... 116 | Setting up dnsutils (1:9.16.22-1~deb11u1) ... 117 | Processing triggers for man-db (2.9.4-2) ... 118 | ``` 119 | 120 |
121 | 122 | ## Testing DNS Resolution 123 | By default the Bind9 server will startup and support DNS lookups, including recursive lookups for public domain names. We can test that it working from the server with the `dig` command. 124 | 125 | ```bash 126 | # Lookup the address for the Cisco Learning Network using the local server 127 | dig learningnetwork.cisco.com @localhost 128 | ``` 129 | 130 | > If you do NOT include @localhost in the command, dig will use the configured DNS servers for the RPi. This is likely whatever the DNS servers in your home network and were provided by the DHCP server to the wlan0 network. We'll update the RPi `lab-server` to use itself for DNS resolution shortly. 131 | 132 |
Output: dig command 133 | 134 | ``` 135 | # Output 136 | ; <<>> DiG 9.16.22-Debian <<>> learningnetwork.cisco.com @localhost 137 | ;; global options: +cmd 138 | ;; Got answer: 139 | ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10418 140 | ;; flags: qr rd ra; QUERY: 1, ANSWER: 7, AUTHORITY: 0, ADDITIONAL: 1 141 | 142 | ;; OPT PSEUDOSECTION: 143 | ; EDNS: version: 0, flags:; udp: 1232 144 | ; COOKIE: 77bdbc1b157f3b4401000000621aa0fce0f01d6c29267348 (good) 145 | ;; QUESTION SECTION: 146 | ;learningnetwork.cisco.com. IN A 147 | 148 | ;; ANSWER SECTION: 149 | learningnetwork.cisco.com. 60 IN CNAME learningnetwork.cisco.com.00d3i000000uddneai.live.siteforce.com. 150 | learningnetwork.cisco.com.00d3i000000uddneai.live.siteforce.com. 300 IN CNAME n.edge2.salesforce.com. 151 | n.edge2.salesforce.com. 60 IN CNAME iad-dfw.edge2.salesforce.com. 152 | iad-dfw.edge2.salesforce.com. 60 IN CNAME dfw.edge2.salesforce.com. 153 | dfw.edge2.salesforce.com. 60 IN A 13.110.28.14 154 | dfw.edge2.salesforce.com. 60 IN A 13.110.28.9 155 | dfw.edge2.salesforce.com. 60 IN A 13.110.28.13 156 | 157 | ;; Query time: 163 msec 158 | ;; SERVER: 127.0.0.1#53(127.0.0.1) 159 | ;; WHEN: Sat Feb 26 16:51:56 EST 2022 160 | ;; MSG SIZE rcvd: 283 161 | ``` 162 | 163 |
164 | 165 | *In the output you can see that a successful reply for the lookup was provided. A `CNAME` and then the related `A` records all are shown.* 166 | 167 | ## Configuring the `lab-server` to use itself for DNS lookups 168 | Update the static IP configuration for the `eth0` lab interface to include a static DNS server. This is done in `/etc/dhcpcd.conf`. 169 | 170 | > More details on network configuration for a RPi is provided in [network-interface-config.md](network-interface-config.md) 171 | 172 | ```bash 173 | # Home Network Lab Setup 174 | interface eth0 175 | static ip_address=192.168.192.11/24 176 | static domain_name_servers=192.168.192.11 177 | ``` 178 | 179 | If you make changes to the `dhcpcd.conf` file, you need to restart the service to apply changes. 180 | 181 | ```bash 182 | sudo systemctl restart dhcpcd 183 | ``` 184 | 185 | And then you can check the contents of `/etc/resolv.conf` to verify the server has been added. 186 | 187 | ```bash 188 | # Generated by resolvconf 189 | nameserver 192.168.192.11 190 | nameserver 208.67.222.222 191 | nameserver 208.67.220.220 192 | ``` 193 | 194 | If you re-do the `dig` command, leaving off `@localhost` this time, you can verify lookups are first trying the local server. 195 | 196 | ```bash 197 | dig learningnetwork.cisco.com 198 | ``` 199 | 200 |
Output: dig command 201 | 202 | ``` 203 | ; <<>> DiG 9.16.22-Debian <<>> learningnetwork.cisco.com 204 | ;; global options: +cmd 205 | ;; Got answer: 206 | ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64206 207 | ;; flags: qr rd ra; QUERY: 1, ANSWER: 7, AUTHORITY: 0, ADDITIONAL: 1 208 | 209 | ;; OPT PSEUDOSECTION: 210 | ; EDNS: version: 0, flags:; udp: 1232 211 | ; COOKIE: 3db5e61f030092be01000000621aa313c684b16ffb476d46 (good) 212 | ;; QUESTION SECTION: 213 | ;learningnetwork.cisco.com. IN A 214 | 215 | ;; ANSWER SECTION: 216 | learningnetwork.cisco.com. 60 IN CNAME learningnetwork.cisco.com.00d3i000000uddneai.live.siteforce.com. 217 | learningnetwork.cisco.com.00d3i000000uddneai.live.siteforce.com. 300 IN CNAME n.edge2.salesforce.com. 218 | n.edge2.salesforce.com. 60 IN CNAME iad-dfw.edge2.salesforce.com. 219 | iad-dfw.edge2.salesforce.com. 60 IN CNAME iad.edge2.salesforce.com. 220 | iad.edge2.salesforce.com. 60 IN A 13.110.24.13 221 | iad.edge2.salesforce.com. 60 IN A 13.110.24.10 222 | iad.edge2.salesforce.com. 60 IN A 13.110.24.11 223 | 224 | ;; Query time: 499 msec 225 | ;; SERVER: 192.168.192.11#53(192.168.192.11) 226 | ;; WHEN: Sat Feb 26 17:00:51 EST 2022 227 | ;; MSG SIZE rcvd: 283 228 | ``` 229 | 230 |
231 | 232 | *Notice the new local address listed in the line `;; SERVER: 192.168.192.11#53(192.168.192.11)`* 233 | 234 | ## Configuring Bind9 on Raspberry Pi 235 | Being able to do public internet lookups using our own DNS server is nice, but the real reason to add a DNS server to your lab is to create DNS entries for your lab gear. Here we will setup a basic configuration for the domain `lab.example` including a few `A` and `CNAME` records for our lab devices and `PTR` records for IP addresses. 236 | 237 | > For the full configuration guide for Bind9 go [here](https://bind9.readthedocs.io/en/latest/). What follows is a basic configuration for a network lab. 238 | 239 | 1. Begin by defining the forward and reverse zones for your lab. This is done by adding the configuration to the file `/etc/bind/named.conf.local`. 240 | > A "forward zone" translates names -> ip addresses. A "reverse zone" translates ip addresses -> names 241 | 242 | ``` 243 | // Forward lookup zone for lab.example 244 | zone "lab.example" IN { 245 | type master; 246 | file "/etc/bind/db.lab.example"; 247 | }; 248 | 249 | // Reverse lookup zone for the network 192.168.192.0 250 | // Note: Reverse lookup zones are named with the first 251 | // 3 octets of an IPv4 address written in reverse. 252 | // Our example network has the same first and third 253 | // octet, so it may look like the zone name is 254 | // ordered 1st, 2nd, 3rd octets. It is actually 255 | // 3rd, 2nd, 1st. 256 | zone "192.168.192.in-addr.arpa" { 257 | type master; 258 | file "/etc/bind/db.rev.192.168.192.in-addr.arpa"; 259 | }; 260 | ``` 261 | 262 | 1. Next we will configure the forward lookup zone for `lab.example`. This is done in the "database" file listed in the zone configuration. Specifically `/etc/bind/db.lab.example`. 263 | 264 | ``` 265 | $TTL 1H 266 | 267 | ; Start of Authority (SOA) for the domain with short timers 268 | ; Note: The value of "serial" must be incremented with each update 269 | lab.example. IN SOA ns1.lab.example. lab-server.lab.example. ( 270 | 11 ; serial 271 | 2H ; refresh 272 | 1H ; retry 273 | 1W ; expire 274 | 1D ; minimum 275 | ) 276 | 277 | ; NS or name server records for the DNS server itself 278 | IN NS ns1.lab.example. 279 | 280 | ; Name Server A Records 281 | ns1 IN A 192.168.192.11 282 | 283 | ; A Record for the lab-server 284 | lab-server IN A 192.168.192.11 285 | 286 | ; A CNAME for files.lab.example -> lab-server.lab.example 287 | files IN CNAME lab-server.lab.example. 288 | ``` 289 | 290 | 1. And now the reverse lookup zone. This will be in the database file `/etc/bind/db.rev.192.168.192.in-addr.arpa` 291 | 292 | ``` 293 | $TTL 1H 294 | 295 | @ IN SOA ns1.lab.example. lab-server.lab.example. ( 296 | 11 ; serial 297 | 2H ; refresh 298 | 1H ; retry 299 | 1W ; expire 300 | 1D ; minimum 301 | ) 302 | ; NS record 303 | IN NS ns1.lab.example. 304 | 305 | ; PTR record for the lab-server 306 | 11 IN PTR lab-server.lab.example. 307 | ``` 308 | 309 | 1. Creating a bind configuration can be challenging. The format is particular, and placement of `.`'s in the right places can be troublesome. Luckly we can use the following commands to check our files for errors. 310 | 311 | ```bash 312 | # Check the forward lookup zone 313 | sudo named-checkzone lab.example db.lab.example 314 | 315 | # Output 316 | zone lab.example/IN: loaded serial 11 317 | OK 318 | 319 | # Check the reverse lookup zone 320 | sudo named-checkzone 192.168.192.in-addr.arpa db.rev.192.168.192.in-addr.arpa 321 | 322 | # Output 323 | zone 192.168.192.in-addr.arpa/IN: loaded serial 11 324 | OK 325 | ``` 326 | 327 | > Note: Don't feel too bad if you have errors the first time you run the command. I had several that I needed to fix before I got the correct configs shown above ;-) 328 | 329 | 1. Now restart bind9 to apply the configuration. 330 | 331 | ```bash 332 | sudo systemctl restart bind9 333 | ``` 334 | 335 | > If you get any errors, look for messages poiting to the possible problem with commands like `systemctl status bind9`, `journalctl -xe`, `journalctl -u named` 336 | 337 | ## Verifying DNS Lookups on Lab Clients 338 | Here we will verify that we can use the `lab-server` dns on the `lab-client` RPi and configure DNS on a network switch to use our new server. 339 | 340 | ### Testing on an RPi `lab-client` 341 | 1. First, make sure your `lab-client` is configured to use the `lab-server` as a DNS server. This could be done with a [static-ip configuration](network-interface-config.md), or through a [DHCP provided configuration](dhcp-server.md). 342 | 1. If you haven't already, install `apt-get install dnsutils` on your `lab-client`. 343 | 1. Try a lookup of the `files.lab.example` CNAME that was configured. 344 | 345 | ```bash 346 | dig files.lab.example 347 | ``` 348 | 349 |
Output: dig lookup 350 | 351 | ``` 352 | ; <<>> DiG 9.16.22-Debian <<>> files.lab.example 353 | ;; global options: +cmd 354 | ;; Got answer: 355 | ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39862 356 | ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 357 | 358 | ;; OPT PSEUDOSECTION: 359 | ; EDNS: version: 0, flags:; udp: 1232 360 | ; COOKIE: 26963ac0e9e70cdf01000000621abda0c8d5501dda5953fa (good) 361 | ;; QUESTION SECTION: 362 | ;files.lab.example. IN A 363 | 364 | ;; ANSWER SECTION: 365 | files.lab.example. 3600 IN CNAME lab-server.lab.example. 366 | lab-server.lab.example. 3600 IN A 192.168.192.11 367 | 368 | ;; Query time: 3 msec 369 | ;; SERVER: 192.168.192.11#53(192.168.192.11) 370 | ;; WHEN: Sat Feb 26 18:54:08 EST 2022 371 | ;; MSG SIZE rcvd: 115 372 | ``` 373 | 374 |
375 | 376 | * The key part is the `ANSWER SECTION`. You can see we got the replies we'd expect. 377 | 378 | ``` 379 | ;; ANSWER SECTION: 380 | files.lab.example. 3600 IN CNAME lab-server.lab.example. 381 | lab-server.lab.example. 3600 IN A 192.168.192.11 382 | ``` 383 | 384 | ### Testing from a Network Device 385 | This is a networking lab discussion, let's configure our lab network device to receive use our new DNS server. 386 | 387 | > For this example I am using a Cisco Catalyst 3650 switch (WS-C3650-24TS-S). 388 | 389 | 1. Configure the `name-server` on the switch. 390 | 391 | ``` 392 | lab-switch#conf t 393 | lab-switch(config)#ip name-server 192.168.192.11 394 | lab-switch(config)#end 395 | ``` 396 | 397 | 1. Attempt to ping the `lab-server` by name. 398 | 399 | ``` 400 | lab-switch#ping files.lab.example 401 | Type escape sequence to abort. 402 | Sending 5, 100-byte ICMP Echos to 192.168.192.11, timeout is 2 seconds: 403 | !!!!! 404 | ``` 405 | 406 | ## Advanced Configuration: Dynamic DNS Updates from ISC DHCP Server -> Bind 407 | If you are truly going to get the benefits of DHCP and DNS in your lab, you'll likely want DNS to work for clients who receive IP addresses via DHCP as well. 408 | 409 | Checkout the [Dynamic DNS - dhcpd to bind](dynamic-dns.md) guide for details on that setup. 410 | 411 | ## Final Thoughts 412 | Now we have a full featured DNS server running in our lab. This doc just scratched the surface of all the possible DNS configurations you might want to explore and use in your setup. A few things you could explore more include: 413 | 414 | * IPv6 DNS records 415 | * DNSSEC for secure DNS 416 | * DNS configuration for collaboration applications and email 417 | * DNS lookup/response traffic flow 418 | * DNS over TCP -------------------------------------------------------------------------------- /dynamic-dns.md: -------------------------------------------------------------------------------- 1 | # Dynamic DNS - Maintaining accurate A and PTR records for DHCP leases 2 | * [Creating a secure key for authenticating updates](#creating-a-secure-key-for-authenticating-updates) 3 | * [Updating the ISC DHCP Server Configuration](#updating-the-isc-dhcp-server-configuration) 4 | * [Updating the Bind Configuration](#updating-the-bind-configuration) 5 | * [Applying changes](#applying-changes) 6 | * [Monitoring for Dynamic DNS Updates](#monitoring-for-dynamic-dns-updates) 7 | * [Final Thoughts](#final-thoughts) 8 | 9 | Table of contents generated with markdown-toc 10 | 11 | 12 | In [Using a Raspberry Pi as a DHCP Server](dhcp-server.md) we learned how to setup the ISC DHCP Server on the RPi to issue IP addresses dynamically. And in [Using a Raspberry Pi as a DNS Server](dns-server.md) we learned how to setup Bind9 on RPi to provide DNS resolution. But what about DNS resolution for dynamically assigned addresses? This is where Dynamic DNS, sometimes called DDNS, comes in. 13 | 14 | What needs to happen is that the DHCP server must send updates to the DNS server for each lease that is issued, and again when they expire. In this document we'll look at how we can update the configurations for both ISC DHCP Server and Bind9 to allow DDNS. 15 | 16 | > Note: This document is going to cover a basic setup and configuration. For full details on DDNS setup consult the documentation for ISC DHCP server and Bind9. 17 | 18 | ## Creating a secure key for authenticating updates 19 | It wouldn't be very good security to allow just ANYONE to update the DNS servers records. It is important that updates are sent from trusted and approved clients. Authentication of DDNS is done with a "key" that is known by both the DHCP server and the DNS server. 20 | 21 | 1. We will use the `ddns-confgen` utility that was installed with bind/bind-utils to generate the key file contents. 22 | > The argument `-k ddns-key` allows us to configure the "key-name" that we want to use. If we don't provide one a default key-name is used. 23 | 24 | ```bash 25 | ddns-confgen -k ddns-key 26 | 27 | # Output 28 | 29 | # To activate this key, place the following in named.conf, and 30 | # in a separate keyfile on the system or systems from which nsupdate 31 | # will be run: 32 | key "ddns-key" { 33 | algorithm hmac-sha256; 34 | secret "rxL46YrXMAiSOeUkLP4DugwoyuOohhn9VeNzunlYxWs="; 35 | }; 36 | 37 | # Then, in the "zone" statement for each zone you wish to dynamically 38 | # update, place an "update-policy" statement granting update permission 39 | # to this key. For example, the following statement grants this key 40 | # permission to update any name within the zone: 41 | update-policy { 42 | grant ddns-key zonesub ANY; 43 | }; 44 | 45 | # After the keyfile has been placed, the following command will 46 | # execute nsupdate using this key: 47 | nsupdate -k 48 | ``` 49 | 50 | * The output of the command provides three things: 51 | 1. The contents of the keyfile that will be `included` by both the dns and dhcp servers 52 | 1. An example configuration to include in the bind zone file that allows the updating of `ANY` data 53 | 1. An example `nsupdate` command to perform dynamic DNS updating using the file. This could be done from a client rather than the DHCP server. 54 | 55 | 1. Using the output from `ddns-confgen` create the key file. It could be placed anywhere, but I'm placing it in the bind configuration directory. 56 | 57 | ```bash 58 | cat /etc/bind/ddns-keyfile.key 59 | 60 | # Output 61 | key "ddns-key" { 62 | algorithm hmac-sha256; 63 | secret "rxL46YrXMAiSOeUkLP4DugwoyuOohhn9VeNzunlYxWs="; 64 | }; 65 | 66 | ``` 67 | 68 | ## Updating the ISC DHCP Server Configuration 69 | With the keyfile created, we can now update the configuration of our DHCP server to send dynamic updates to the DNS server. 70 | 71 | 1. Add the following configuration to the `/etc/dhcp/dhcpd.conf` file 72 | 73 | ```bash 74 | # Include the Dynamic DNS Keyfile 75 | include "/etc/bind/ddns-keyfile.key"; 76 | 77 | # Dynamic DNS Update Configuration 78 | ddns-update-style standard; 79 | ddns-rev-domainname "in-addr.arpa."; 80 | deny client-updates; 81 | do-forward-updates on; 82 | update-optimization off; # Turn this off to always send DDNS updates. Good for lab, bad for prod 83 | update-conflict-detection off; # I turn this off in the lab to always update DNS even if a host changes IPs/interfaces 84 | 85 | # Include the Dynamic DNS Keyfile 86 | include "/etc/bind/ddns-keyfile.key"; 87 | 88 | zone lab.example. { # name of your forward DNS zone 89 | primary 192.168.192.11; # DNS server IP address here 90 | key ddns-key; # Must reference the name of the "key" in the keyfile 91 | } 92 | 93 | zone 192.168.192.in-addr.arpa. { # name of your reverse DNS zone 94 | primary 192.168.192.11; # DNS server IP address here 95 | key ddns-key; # Must reference the name of the "key" in the keyfile 96 | } 97 | ``` 98 | 99 | ## Updating the Bind Configuration 100 | In order to accept the dynamic updates from the DHCP server, Bind must be configured to allow them. 101 | 102 | 1. Update the configuration in the file `/etc/bind/named.conf.local` to: 103 | * `include` the key file 104 | * set the `update-policy` for both the forward and reverse zones 105 | 106 | ```php 107 | // 108 | // Do any local configuration here 109 | // 110 | 111 | // Consider adding the 1918 zones here, if they are not used in your 112 | // organization 113 | //include "/etc/bind/zones.rfc1918"; 114 | 115 | // Include the Dynamic DNS Keyfile 116 | include "/etc/bind/ddns-keyfile.key"; 117 | 118 | // Forward lookup zone for lab.example 119 | zone "lab.example" IN { 120 | type master; 121 | file "/etc/bind/db.lab.example"; 122 | 123 | // Dynamic DNS Update Configuration 124 | update-policy { 125 | grant ddns-key zonesub A TXT DHCID; 126 | }; 127 | }; 128 | 129 | // Reverse lookup zone for the network 192.168.192.0 130 | // Note: Reverse lookup zones are named with the first 131 | // 3 octets of an IPv4 address written in reverse. 132 | // Our example network has the same first and third 133 | // octet, so it may look like the zone name is 134 | // ordered 1st, 2nd, 3rd octets. It is actually 135 | // 3rd, 2nd, 1st. 136 | zone "192.168.192.in-addr.arpa" { 137 | type master; 138 | file "/etc/bind/db.rev.192.168.192.in-addr.arpa"; 139 | 140 | // Dynamic DNS Update Configuration 141 | update-policy { 142 | grant ddns-key zonesub PTR TXT DHCID; 143 | }; 144 | }; 145 | ``` 146 | 147 | 1. As DDNS updates come into the DNS server, bind creates a journal file to track the updates and create the dynamic DNS entries. In order for this to succeed, the `bind` user needs write permissions to the `/etc/bind` directory. The default installation only provides read permissions by setting the `group` to `bind`, but the `owner` to `root`. Change the owner of the `/etc/bind` directory to the `bind` user to allow the creation and management of the journal files. 148 | 149 | ```bash 150 | sudo chown bind:bind /etc/bind 151 | ``` 152 | 153 | ## Applying changes 154 | To apply the changes, simply restart both the dns and dhcp server services. 155 | 156 | ```bash 157 | sudo systemctl restart bind 158 | sudo systemctl restart isc-dhcp-server 159 | ``` 160 | 161 | > Note: if any errors in restarting the services are noted, check the configuration files and look for details on the error in the system journal (`journalctl -xe`) 162 | 163 | ## Monitoring for Dynamic DNS Updates 164 | The easiest way to see if the configuration is working correctly, you can monitor the system journal on the RPi server. 165 | 166 | ```bash 167 | journalctl -xef -u named -u isc-dhcp-server 168 | ``` 169 | 170 | You can wait for a DHCP client to send a renew message, or you can restart the DHCP client service on the `lab-client` to force an update `sudo systemctl restart dhcpcd`. 171 | 172 | When an update happens, you will see messages like this in the journal. I have added comments within to identify the steps involved. 173 | 174 | ```bash 175 | # The DHCP Client attempts to renew its ip address by sending a DHCPREQUEST. The server replies with a DHCPACK 176 | Feb 27 11:18:15 lab-server dhcpd[77080]: DHCPREQUEST for 192.168.192.102 from b8:27:eb:d3:22:e7 (lab-client) via eth0 177 | Feb 27 11:18:15 lab-server dhcpd[77080]: DHCPACK on 192.168.192.102 to b8:27:eb:d3:22:e7 (lab-client) via eth0 178 | 179 | # Bind checks if a DNS entry already exists, there isn't one 180 | Feb 27 11:18:15 lab-server named[75396]: client @0x7f6804de28 192.168.192.11#47183/key ddns-key: updating zone 'lab.example/IN': update unsuccessful: lab-client.lab.example: 'name not in use' prerequisite not satisfied (YXDOMAIN) 181 | # Bind deletes and readds the DHCID (DHCP Client ID info) 182 | Feb 27 11:18:15 lab-server named[75396]: client @0x7f797ba8a8 192.168.192.11#37505/key ddns-key: updating zone 'lab.example/IN': deleting rrset at 'lab-client.lab.example' DHCID 183 | Feb 27 11:18:15 lab-server named[75396]: client @0x7f797ba8a8 192.168.192.11#37505/key ddns-key: updating zone 'lab.example/IN': adding an RR at 'lab-client.lab.example' DHCID AAEBN40H7hrfLp1E6YojFr2meGSWZs75Bv3n0GSKLK9TFzg= 184 | # Bind deletes and readds the A record for the clients DHCP address 185 | Feb 27 11:18:15 lab-server named[75396]: client @0x7f797ba8a8 192.168.192.11#37505/key ddns-key: updating zone 'lab.example/IN': deleting rrset at 'lab-client.lab.example' A 186 | Feb 27 11:18:15 lab-server named[75396]: client @0x7f797ba8a8 192.168.192.11#37505/key ddns-key: updating zone 'lab.example/IN': adding an RR at 'lab-client.lab.example' A 192.168.192.102 187 | 188 | # The DHCP server logs teh successful creation of the forward mapping 189 | Feb 27 11:18:15 lab-server dhcpd[77080]: Added new forward map from lab-client.lab.example to 192.168.192.102 190 | 191 | # Bind deletes and readds the PTR record 192 | Feb 27 11:18:15 lab-server named[75396]: client @0x7f797ba8a8 192.168.192.11#40925/key ddns-key: updating zone '192.168.192.in-addr.arpa/IN': deleting rrset at '102.192.168.192.in-addr.arpa' PTR 193 | Feb 27 11:18:15 lab-server named[75396]: client @0x7f797ba8a8 192.168.192.11#40925/key ddns-key: updating zone '192.168.192.in-addr.arpa/IN': adding an RR at '102.192.168.192.in-addr.arpa' PTR lab-client.lab.example. 194 | 195 | # The DHCP server logs the successful creation of the reverse mapping 196 | Feb 27 11:18:15 lab-server dhcpd[77080]: Added reverse map from 102.192.168.192.in-addr.arpa. to lab-client.lab.example 197 | ``` 198 | 199 | > Note: If you have host reservations configured for lab devices in your `dhcpd.conf` file you will ***NOT*** get dynamic dns updates created. This took me by a bit of surprise, and after some looking into it this seems to be by design of the ISC DHCP Server (and might happen with other DHCP servers as well). The reason is that by default `host` reservations are NOT recorded as `leases` by the server, and therefore do NOT follow the same process as true dynamic address assignment. There are some configuration options that can be done to get DDNS for reserved IPs, but the general advice is to manually create the DNS entries for reserved addresses. Afterall, DDNS is meant for names/ips that are changing, and reservations don't change. 200 | > 201 | > To make this a bit easier, you can configure the `fixed-address` in a host configuration to use a DNS name rather than IP address. For example 202 | > ```bash 203 | > host lab-client { 204 | > hardware ethernet b8:27:eb:d3:22:e7; 205 | > fixed-address lab-client.lab.example; 206 | > } 207 | > ``` 208 | 209 | ## Final Thoughts 210 | Alright, with dynamic dns configured our lab dns and dhcp are setup in a robust fashion that will support nearly any type of scenario we might need to explore with these protocols. Furthermore, it is setup in a way that mimics how many enterprise networks are configured. -------------------------------------------------------------------------------- /images/rasp-config-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hpreston/rpi-networklab/d666ab4967a23fbfdffdec4ef41b8e3e515b9172/images/rasp-config-01.png -------------------------------------------------------------------------------- /network-interface-config.md: -------------------------------------------------------------------------------- 1 | # TL:DR for Configuring Network Interfaces on Raspberry Pi 2 | Every time I work with a new Linux distribution it seems I need to learn a new way to manage network interface configuration. The Raspberry Pi is no different in this case. This page is mostly as a reminder/pointer for the key parts of network configuration on RPis and not intended to be comprehensive. For the comprehensive details on network configuration for a Raspberry Pi, check out the [official documentation](https://www.raspberrypi.com/documentation/computers/configuration.html#configuring-networking). 3 | 4 | > Note: There are MANY versions of Raspberry Pis, and not all have the same physical network interfaces included. Be sure to keep your individual RPi in mind when reviewing this document. 5 | 6 | ## Use `rasp-config` 7 | The simplest way to setup wireless on a RPi is to use the `rasp-config` CLI utility. Under the "1 System Options", you'll find "S1 Wireless LAN". This will walk you through connecting to a wireless network. 8 | 9 | ![](images/rasp-config-01.png) 10 | 11 | ## Configuring Wireless Manually 12 | The RPi uses the relatively common utility "wpa-supplicant" for managing wireless networks. You can manually configure the wireless network to join by editing the file `/etc/wpa_supplicant/wpa_supplicant.conf` 13 | 14 | ``` 15 | network={ 16 | ssid="Your Awesome SSID" 17 | psk=psk=e8c5342ce8bb79c9693ae9ec805a00b60500915d338021202a8c7df76d105dd7 18 | } 19 | ``` 20 | 21 | The `psk` value above is an encrypted value for the passphrase. This is easily created by using the `wpa_passphrase` utility. It even provides the configuration to place into the file for the SSID. 22 | 23 | ```bash 24 | wpa_passphrase "Your Awesome SSID" "YourAwesomePassphrase" 25 | 26 | # Output 27 | network={ 28 | ssid="Your Awesome SSID" 29 | #psk="YourAwesomePassphrase" 30 | psk=e8c5342ce8bb79c9693ae9ec805a00b60500915d338021202a8c7df76d105dd7 31 | } 32 | ``` 33 | 34 | > Note: You can also add the `psk` in clear text. That isn't recommended... 35 | 36 | ## Configuring Static IPs using the DHCP Client Configuration 37 | The RPi defaults to having a DHCP Client running. The simplest way to configure static IP addresses is by adding it to the `/etc/dhcpcd.conf` file. 38 | 39 | > The DHCP client is `dhcpcd` - details can be found with `man dhcpcd` 40 | 41 | Within the default `dhcpcd.conf` file you will find examples of how to configure a static ip address for an interface. 42 | 43 | In the example below I am configuring a static IP address for the `eth0` interface on my Rpi. 44 | 45 | > This is the wired network interface I connect into my lab network. The wireless network connects to my home network and it allows me to connect to the Rpi with SSH. 46 | 47 | ```bash 48 | # Home Network Lab Setup 49 | interface eth0 50 | static ip_address=192.168.192.12/24 51 | static routers=192.168.192.1 52 | 53 | # I am running DNS on another RPi in my lab 54 | static domain_name_servers=192.168.192.11 55 | 56 | # By default ethernet interfaces are given a metric 57 | # 200 + interface index. This would make the eth0 58 | # routes preferred over wlan0. But I need wlan0 to 59 | # be preferred to allow internet access. So I set 60 | # the metric for the eth0 interface to 500 61 | metric 500 62 | 63 | # If you want IPv6 address 64 | # static ip6_address=fd51:42f8:caae:d92e::ff/64 65 | ``` 66 | 67 | ## Configuring Static Routes 68 | Use the `ip route` command to add new static routes on a RPi just like any other Linux system. 69 | 70 | ```bash 71 | # Add route to 192.168.0.0/16 network through 192.168.192.1 on eth0 72 | sudo ip route add 192.168.0.0/16 via 192.168.192.1 dev eth0 73 | ``` 74 | 75 | If you want to make the route persistent across reboots, add the command to the file `/etc/dhcpcd.exit-hook` which is called as part of the DHCP Client operation. 76 | 77 | ``` 78 | cat /etc/dhcpcd.exit-hook 79 | 80 | # Output 81 | ip route add 192.168.0.0/16 via 192.168.192.1 dev eth0 82 | ``` 83 | 84 | > Note: The file `/etc/dhcpcd.exit-hook` isn't created by default. Just create it and add commands needed. -------------------------------------------------------------------------------- /tacacs-server.md: -------------------------------------------------------------------------------- 1 | # Using a Raspberry Pi as a TACACS Server 2 | * [Installing TACACS+ on Raspberry Pi](#installing-tacacs--on-raspberry-pi) 3 | * [Create a TACACS+ configuration file](#create-a-tacacs--configuration-file) 4 | * [Configure a network device for TACACS](#configure-a-network-device-for-tacacs) 5 | * [Setting `tac_plus` up as a systemd service](#setting--tac-plus--up-as-a-systemd-service) 6 | * [Final Thoughts](#final-thoughts) 7 | 8 | Table of contents generated with markdown-toc 9 | 10 | An important part of becoming a network engineer is understanding and becoming comfortable with AAA services to ensure only the right people connect to and interact with your network. TACACS is a commonly used device administration protocol for Authentication, Authorization, and Accounting. 11 | 12 | In an enterprise network, you'll likely see solutions like Cisco Identity Services Engine (ISE) used, however an ISE server can be a bit overkill for a basic networking lab. Luckily Cisco provided the basic TACACS functionality in the form of a developer's kit at no cost. And using it, the open source program tacacs+ (or `tac_plus`) was developed and is a great option for networking labs like ours. 13 | 14 | ## Installing TACACS+ on Raspberry Pi 15 | TACACS+ (or tac_plus) is available for installation for many Linux distrubitons and platforms through package management tools like `apt` or `yum`. And `tacacs+` was available for Raspberry Pi several years ago, however as of the writing of this doc it no longer is available for a simple `apt-get install tacacs+`. 16 | 17 | This means we will need to do a manual installation. But don't fear, this isn't complicated and this guide will walk you through. 18 | 19 | > Note: This guide doesn't go into depth on installation from source concepts. 20 | 21 | 1. Install pre-reqs for compiling tacacs+ 22 | 23 | ```bash 24 | sudo apt-get install bison flex libwrap0-dev 25 | ``` 26 | 27 | 1. Download tacacs+ source from [Shubbery Network](https://shrubbery.net/tac_plus/) download [site](https://shrubbery.net/pub/tac_plus/). 28 | > The tacacs+ server is not updated regularly. The "latest" version is 4.0.4.28 and is downloaded in this example. 29 | 30 | ```bash 31 | # Create a "downloads" directory and move there 32 | mkdir ~/downloads 33 | cd ~/downloads 34 | 35 | # Download the tacacs+ code 36 | wget https://shrubbery.net/pub/tac_plus/tacacs-F4.0.4.28.tar.gz 37 | 38 | # Untar the file and move into the directory 39 | tar -xzf tacacs-F4.0.4.28.tar.gz 40 | cd tacacs-F4.0.4.28 41 | ``` 42 | 43 | 1. Configure and install tacacs+ 44 | 45 | ```bash 46 | ./configure 47 | ``` 48 | 49 |
Output ./configure 50 | 51 | ``` 52 | checking for a BSD-compatible install... /usr/bin/install -c 53 | checking whether build environment is sane... yes 54 | checking for a thread-safe mkdir -p... /usr/bin/mkdir -p 55 | checking for gawk... no 56 | checking for mawk... mawk 57 | checking whether make sets $(MAKE)... yes 58 | checking whether make supports nested variables... yes 59 | checking whether to enable maintainer-specific portions of Makefiles... no 60 | checking build system type... aarch64-unknown-linux-gnu 61 | checking host system type... aarch64-unknown-linux-gnu 62 | checking for gmake... /usr/bin/gmake 63 | checking whether /usr/bin/gmake sets $(MAKE)... yes 64 | checking whether to enable maintainer-specific portions of Makefiles... no 65 | checking how to print strings... printf 66 | checking for style of include used by /usr/bin/gmake... GNU 67 | checking for gcc... gcc 68 | checking whether the C compiler works... yes 69 | checking for C compiler default output file name... a.out 70 | checking for suffix of executables... 71 | checking whether we are cross compiling... no 72 | checking for suffix of object files... o 73 | checking whether we are using the GNU C compiler... yes 74 | checking whether gcc accepts -g... yes 75 | checking for gcc option to accept ISO C89... none needed 76 | checking whether gcc understands -c and -o together... yes 77 | checking dependency style of gcc... gcc3 78 | checking for a sed that does not truncate output... /usr/bin/sed 79 | checking for grep that handles long lines and -e... /usr/bin/grep 80 | checking for egrep... /usr/bin/grep -E 81 | checking for fgrep... /usr/bin/grep -F 82 | checking for ld used by gcc... /usr/bin/ld 83 | checking if the linker (/usr/bin/ld) is GNU ld... yes 84 | checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm -B 85 | checking the name lister (/usr/bin/nm -B) interface... BSD nm 86 | checking whether ln -s works... yes 87 | checking the maximum length of command line arguments... 1572864 88 | checking whether the shell understands some XSI constructs... yes 89 | checking whether the shell understands "+="... yes 90 | checking how to convert aarch64-unknown-linux-gnu file names to aarch64-unknown-linux-gnu format... func_convert_file_noop 91 | checking how to convert aarch64-unknown-linux-gnu file names to toolchain format... func_convert_file_noop 92 | checking for /usr/bin/ld option to reload object files... -r 93 | checking for objdump... objdump 94 | checking how to recognize dependent libraries... pass_all 95 | checking for dlltool... no 96 | checking how to associate runtime and link libraries... printf %s\n 97 | checking for ar... ar 98 | checking for archiver @FILE support... @ 99 | checking for strip... strip 100 | checking for ranlib... ranlib 101 | checking command to parse /usr/bin/nm -B output from gcc object... ok 102 | checking for sysroot... no 103 | checking for mt... mt 104 | checking if mt is a manifest tool... no 105 | checking how to run the C preprocessor... gcc -E 106 | checking for ANSI C header files... yes 107 | checking for sys/types.h... yes 108 | checking for sys/stat.h... yes 109 | checking for stdlib.h... yes 110 | checking for string.h... yes 111 | checking for memory.h... yes 112 | checking for strings.h... yes 113 | checking for inttypes.h... yes 114 | checking for stdint.h... yes 115 | checking for unistd.h... yes 116 | checking for dlfcn.h... yes 117 | checking for objdir... .libs 118 | checking if gcc supports -fno-rtti -fno-exceptions... no 119 | checking for gcc option to produce PIC... -fPIC -DPIC 120 | checking if gcc PIC flag -fPIC -DPIC works... yes 121 | checking if gcc static flag -static works... yes 122 | checking if gcc supports -c -o file.o... yes 123 | checking if gcc supports -c -o file.o... (cached) yes 124 | checking whether the gcc linker (/usr/bin/ld) supports shared libraries... yes 125 | checking whether -lc should be explicitly linked in... no 126 | checking dynamic linker characteristics... GNU/Linux ld.so 127 | checking how to hardcode library paths into programs... immediate 128 | checking for shl_load... no 129 | checking for shl_load in -ldld... no 130 | checking for dlopen... no 131 | checking for dlopen in -ldl... yes 132 | checking whether a program can dlopen itself... yes 133 | checking whether a statically linked program can dlopen itself... no 134 | checking whether stripping libraries is possible... yes 135 | checking if libtool supports shared libraries... yes 136 | checking whether to build shared libraries... yes 137 | checking whether to build static libraries... yes 138 | checking for the pthreads library -lpthreads... no 139 | checking whether pthreads work without any flags... no 140 | checking whether pthreads work with -Kthread... no 141 | checking whether pthreads work with -kthread... no 142 | checking for the pthreads library -llthread... no 143 | checking whether pthreads work with -pthread... yes 144 | checking for joinable pthread attribute... PTHREAD_CREATE_JOINABLE 145 | checking if more special flags are required for pthreads... no 146 | checking for gcc... (cached) gcc 147 | checking whether we are using the GNU C compiler... (cached) yes 148 | checking whether gcc accepts -g... (cached) yes 149 | checking for gcc option to accept ISO C89... (cached) none needed 150 | checking whether gcc understands -c and -o together... (cached) yes 151 | checking dependency style of gcc... (cached) gcc3 152 | checking how to run the C preprocessor... gcc -E 153 | checking for an ANSI C-conforming const... yes 154 | checking for inline... inline 155 | checking for preprocessor stringizing operator... yes 156 | checking for flex... flex 157 | checking lex output file root... lex.yy 158 | checking lex library... -lfl 159 | checking whether yytext is a pointer... yes 160 | checking for bison... bison -y 161 | checking whether yacc is bison in disguise... yes 162 | checking whether byte ordering is bigendian... no 163 | checking size of long int... 8 164 | checking whether to include symbols... no 165 | checking whether to set gcc warnings... no 166 | checking whether to use libwrap... yes 167 | checking whether to include skey support... no 168 | checking whether to include RSA SecurID support... no 169 | checking whether to setuid()... no 170 | checking whether to setgid()... no 171 | checking whether to include ACL support... yes 172 | checking whether to include user-enable support... yes 173 | checking whether to include maximum sessions (maxsess) support... no 174 | checking whether to include maxsess finger support... no 175 | checking whether to include ARAP DES support... no 176 | checking whether to include MSCHAP support... no 177 | checking whether to include MSCHAP DES support... no 178 | checking for alt pid file FQPN... /var/run/tac_plus.pid 179 | checking for alt accounting file FQPN... /var/log/tac_plus.acct 180 | checking for alt log file FQPN... /var/log/tac_plus.log 181 | checking for alt wholog file FQPN... /var/log/tacwho.log 182 | checking whether to profile... no 183 | checking for pam_start in -lpam... no 184 | checking for ANSI C header files... (cached) yes 185 | checking whether time.h and sys/time.h may both be included... yes 186 | checking crypt.h usability... yes 187 | checking crypt.h presence... yes 188 | checking for crypt.h... yes 189 | checking ctype.h usability... yes 190 | checking ctype.h presence... yes 191 | checking for ctype.h... yes 192 | checking errno.h usability... yes 193 | checking errno.h presence... yes 194 | checking for errno.h... yes 195 | checking fcntl.h usability... yes 196 | checking fcntl.h presence... yes 197 | checking for fcntl.h... yes 198 | checking malloc.h usability... yes 199 | checking malloc.h presence... yes 200 | checking for malloc.h... yes 201 | checking shadow.h usability... yes 202 | checking shadow.h presence... yes 203 | checking for shadow.h... yes 204 | checking for stdlib.h... (cached) yes 205 | checking for stdint.h... (cached) yes 206 | checking for string.h... (cached) yes 207 | checking for strings.h... (cached) yes 208 | checking sys/resource.h usability... yes 209 | checking sys/resource.h presence... yes 210 | checking for sys/resource.h... yes 211 | checking sys/socket.h usability... yes 212 | checking sys/socket.h presence... yes 213 | checking for sys/socket.h... yes 214 | checking for sys/types.h... (cached) yes 215 | checking sys/wait.h usability... yes 216 | checking sys/wait.h presence... yes 217 | checking for sys/wait.h... yes 218 | checking sysexits.h usability... yes 219 | checking sysexits.h presence... yes 220 | checking for sysexits.h... yes 221 | checking syslog.h usability... yes 222 | checking syslog.h presence... yes 223 | checking for syslog.h... yes 224 | checking termios.h usability... yes 225 | checking termios.h presence... yes 226 | checking for termios.h... yes 227 | checking for unistd.h... (cached) yes 228 | checking utmp.h usability... yes 229 | checking utmp.h presence... yes 230 | checking for utmp.h... yes 231 | checking utmpx.h usability... yes 232 | checking utmpx.h presence... yes 233 | checking for utmpx.h... yes 234 | checking wait.h usability... yes 235 | checking wait.h presence... yes 236 | checking for wait.h... yes 237 | checking return type of signal handlers... void 238 | checking for socklen_t... yes 239 | checking for pid_t... yes 240 | checking for getdtablesize... yes 241 | checking for memcpy... yes 242 | checking for memset... yes 243 | checking for random... yes 244 | checking for strchr... yes 245 | checking for strcspn... yes 246 | checking for strerror... yes 247 | checking for strrchr... yes 248 | checking for wait3... yes 249 | checking for wait4... yes 250 | checking for waitpid... yes 251 | checking whether setpgrp takes no argument... yes 252 | checking if waitpid takes a union wait... no 253 | checking if signals need to be re-armed... no 254 | checking if children need to be reaped... yes 255 | checking if children need to be reaped with SIG_IGN... yes 256 | checking for gnutar... no 257 | checking for gtar... no 258 | checking for tar... tar 259 | checking for perl5... no 260 | checking for perl... /usr/bin/perl 261 | checking that generated files are newer than configure... done 262 | configure: creating ./config.status 263 | config.status: creating Makefile 264 | config.status: creating version.h 265 | config.status: creating pathsl.h 266 | config.status: creating tac_plus.8 267 | config.status: creating tac_plus.conf.5 268 | config.status: creating config.h 269 | config.status: executing depfiles commands 270 | config.status: executing libtool commands 271 | ``` 272 | 273 |
274 | 275 | ```bash 276 | make install 277 | ``` 278 | 279 |
Output: make install 280 | 281 | ``` 282 | /usr/bin/gmake install-am 283 | gmake[1]: Entering directory '/home/pi/downloads/tacacs-F4.0.4.28' 284 | /bin/bash ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-fdes.lo -MD -MP -MF .deps/libtacacs_la-fdes.Tpo -c -o libtacacs_la-fdes.lo `test -f 'fdes.c' || echo './'`fdes.c 285 | libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-fdes.lo -MD -MP -MF .deps/libtacacs_la-fdes.Tpo -c fdes.c -fPIC -DPIC -o .libs/libtacacs_la-fdes.o 286 | libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-fdes.lo -MD -MP -MF .deps/libtacacs_la-fdes.Tpo -c fdes.c -o libtacacs_la-fdes.o >/dev/null 2>&1 287 | mv -f .deps/libtacacs_la-fdes.Tpo .deps/libtacacs_la-fdes.Plo 288 | /bin/bash ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-maxsess.lo -MD -MP -MF .deps/libtacacs_la-maxsess.Tpo -c -o libtacacs_la-maxsess.lo `test -f 'maxsess.c' || echo './'`maxsess.c 289 | libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-maxsess.lo -MD -MP -MF .deps/libtacacs_la-maxsess.Tpo -c maxsess.c -fPIC -DPIC -o .libs/libtacacs_la-maxsess.o 290 | libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-maxsess.lo -MD -MP -MF .deps/libtacacs_la-maxsess.Tpo -c maxsess.c -o libtacacs_la-maxsess.o >/dev/null 2>&1 291 | mv -f .deps/libtacacs_la-maxsess.Tpo .deps/libtacacs_la-maxsess.Plo 292 | /bin/bash ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-md4.lo -MD -MP -MF .deps/libtacacs_la-md4.Tpo -c -o libtacacs_la-md4.lo `test -f 'md4.c' || echo './'`md4.c 293 | libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-md4.lo -MD -MP -MF .deps/libtacacs_la-md4.Tpo -c md4.c -fPIC -DPIC -o .libs/libtacacs_la-md4.o 294 | libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-md4.lo -MD -MP -MF .deps/libtacacs_la-md4.Tpo -c md4.c -o libtacacs_la-md4.o >/dev/null 2>&1 295 | mv -f .deps/libtacacs_la-md4.Tpo .deps/libtacacs_la-md4.Plo 296 | /bin/bash ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-md5.lo -MD -MP -MF .deps/libtacacs_la-md5.Tpo -c -o libtacacs_la-md5.lo `test -f 'md5.c' || echo './'`md5.c 297 | libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-md5.lo -MD -MP -MF .deps/libtacacs_la-md5.Tpo -c md5.c -fPIC -DPIC -o .libs/libtacacs_la-md5.o 298 | libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-md5.lo -MD -MP -MF .deps/libtacacs_la-md5.Tpo -c md5.c -o libtacacs_la-md5.o >/dev/null 2>&1 299 | mv -f .deps/libtacacs_la-md5.Tpo .deps/libtacacs_la-md5.Plo 300 | /bin/bash ./libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-packet.lo -MD -MP -MF .deps/libtacacs_la-packet.Tpo -c -o libtacacs_la-packet.lo `test -f 'packet.c' || echo './'`packet.c 301 | libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-packet.lo -MD -MP -MF .deps/libtacacs_la-packet.Tpo -c packet.c -fPIC -DPIC -o .libs/libtacacs_la-packet.o 302 | libtool: compile: gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -g -O2 -pthread -MT libtacacs_la-packet.lo -MD -MP -MF .deps/libtacacs_la-packet.Tpo -c packet.c -o libtacacs_la-packet.o >/dev/null 2>&1 303 | mv -f .deps/libtacacs_la-packet.Tpo .deps/libtacacs_la-packet.Plo 304 | /bin/bash ./libtool --tag=CC --mode=link gcc -g -O2 -pthread -g -O2 -pthread -version-info 1:0:0 -version-number 1:0:0 -L/usr/local/lib -L/lib -L/usr/local/lib -L/lib -o libtacacs.la -rpath /usr/local/lib libtacacs_la-fdes.lo libtacacs_la-maxsess.lo libtacacs_la-md4.lo libtacacs_la-md5.lo libtacacs_la-packet.lo -lnsl -lcrypt 305 | libtool: link: gcc -shared -fPIC -DPIC .libs/libtacacs_la-fdes.o .libs/libtacacs_la-maxsess.o .libs/libtacacs_la-md4.o .libs/libtacacs_la-md5.o .libs/libtacacs_la-packet.o -L/usr/local/lib -L/lib -lnsl -lcrypt -O2 -pthread -O2 -pthread -pthread -Wl,-soname -Wl,libtacacs.so.1 -o .libs/libtacacs.so.1.0.0 306 | libtool: link: (cd ".libs" && rm -f "libtacacs.so.1" && ln -s "libtacacs.so.1.0.0" "libtacacs.so.1") 307 | libtool: link: (cd ".libs" && rm -f "libtacacs.so" && ln -s "libtacacs.so.1.0.0" "libtacacs.so") 308 | libtool: link: ar cru .libs/libtacacs.a libtacacs_la-fdes.o libtacacs_la-maxsess.o libtacacs_la-md4.o libtacacs_la-md5.o libtacacs_la-packet.o 309 | ar: `u' modifier ignored since `D' is the default (see `U') 310 | libtool: link: ranlib .libs/libtacacs.a 311 | libtool: link: ( cd ".libs" && rm -f "libtacacs.la" && ln -s "../libtacacs.la" "libtacacs.la" ) 312 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT tac_pwd.o -MD -MP -MF .deps/tac_pwd.Tpo -c -o tac_pwd.o tac_pwd.c 313 | mv -f .deps/tac_pwd.Tpo .deps/tac_pwd.Po 314 | /bin/bash ./libtool --tag=CC --mode=link gcc -g -O2 -pthread -L/usr/local/lib -L/lib -o tac_pwd tac_pwd.o -lnsl -lcrypt 315 | libtool: link: gcc -g -O2 -pthread -o tac_pwd tac_pwd.o -L/usr/local/lib -L/lib -lnsl -lcrypt -pthread 316 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT acct.o -MD -MP -MF .deps/acct.Tpo -c -o acct.o acct.c 317 | mv -f .deps/acct.Tpo .deps/acct.Po 318 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT authen.o -MD -MP -MF .deps/authen.Tpo -c -o authen.o authen.c 319 | mv -f .deps/authen.Tpo .deps/authen.Po 320 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT author.o -MD -MP -MF .deps/author.Tpo -c -o author.o author.c 321 | mv -f .deps/author.Tpo .deps/author.Po 322 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT choose_authen.o -MD -MP -MF .deps/choose_authen.Tpo -c -o choose_authen.o choose_authen.c 323 | mv -f .deps/choose_authen.Tpo .deps/choose_authen.Po 324 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT config.o -MD -MP -MF .deps/config.Tpo -c -o config.o config.c 325 | mv -f .deps/config.Tpo .deps/config.Po 326 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT default_fn.o -MD -MP -MF .deps/default_fn.Tpo -c -o default_fn.o default_fn.c 327 | mv -f .deps/default_fn.Tpo .deps/default_fn.Po 328 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT default_v0_fn.o -MD -MP -MF .deps/default_v0_fn.Tpo -c -o default_v0_fn.o default_v0_fn.c 329 | mv -f .deps/default_v0_fn.Tpo .deps/default_v0_fn.Po 330 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT do_acct.o -MD -MP -MF .deps/do_acct.Tpo -c -o do_acct.o do_acct.c 331 | do_acct.c: In function ‘do_acct_syslog’: 332 | do_acct.c:184:6: warning: ‘strncat’ specified bound 4 equals source length [-Wstringop-overflow=] 333 | 184 | strncat(cmdbuf, " ", 4); 334 | | ^~~~~~~~~~~~~~~~~~~~~~~~~~ 335 | mv -f .deps/do_acct.Tpo .deps/do_acct.Po 336 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT do_author.o -MD -MP -MF .deps/do_author.Tpo -c -o do_author.o do_author.c 337 | mv -f .deps/do_author.Tpo .deps/do_author.Po 338 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT dump.o -MD -MP -MF .deps/dump.Tpo -c -o dump.o dump.c 339 | mv -f .deps/dump.Tpo .deps/dump.Po 340 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT enable.o -MD -MP -MF .deps/enable.Tpo -c -o enable.o enable.c 341 | mv -f .deps/enable.Tpo .deps/enable.Po 342 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT encrypt.o -MD -MP -MF .deps/encrypt.Tpo -c -o encrypt.o encrypt.c 343 | mv -f .deps/encrypt.Tpo .deps/encrypt.Po 344 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT expire.o -MD -MP -MF .deps/expire.Tpo -c -o expire.o expire.c 345 | mv -f .deps/expire.Tpo .deps/expire.Po 346 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT hash.o -MD -MP -MF .deps/hash.Tpo -c -o hash.o hash.c 347 | mv -f .deps/hash.Tpo .deps/hash.Po 348 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT maxsessint.o -MD -MP -MF .deps/maxsessint.Tpo -c -o maxsessint.o maxsessint.c 349 | mv -f .deps/maxsessint.Tpo .deps/maxsessint.Po 350 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT parse.o -MD -MP -MF .deps/parse.Tpo -c -o parse.o parse.c 351 | mv -f .deps/parse.Tpo .deps/parse.Po 352 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT programs.o -MD -MP -MF .deps/programs.Tpo -c -o programs.o programs.c 353 | mv -f .deps/programs.Tpo .deps/programs.Po 354 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT pw.o -MD -MP -MF .deps/pw.Tpo -c -o pw.o pw.c 355 | mv -f .deps/pw.Tpo .deps/pw.Po 356 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT pwlib.o -MD -MP -MF .deps/pwlib.Tpo -c -o pwlib.o pwlib.c 357 | mv -f .deps/pwlib.Tpo .deps/pwlib.Po 358 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT report.o -MD -MP -MF .deps/report.Tpo -c -o report.o report.c 359 | mv -f .deps/report.Tpo .deps/report.Po 360 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT sendauth.o -MD -MP -MF .deps/sendauth.Tpo -c -o sendauth.o sendauth.c 361 | mv -f .deps/sendauth.Tpo .deps/sendauth.Po 362 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT sendpass.o -MD -MP -MF .deps/sendpass.Tpo -c -o sendpass.o sendpass.c 363 | mv -f .deps/sendpass.Tpo .deps/sendpass.Po 364 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT tac_plus.o -MD -MP -MF .deps/tac_plus.Tpo -c -o tac_plus.o tac_plus.c 365 | mv -f .deps/tac_plus.Tpo .deps/tac_plus.Po 366 | gcc -DHAVE_CONFIG_H -I. -I/usr/local/include -g -O2 -pthread -MT utils.o -MD -MP -MF .deps/utils.Tpo -c -o utils.o utils.c 367 | mv -f .deps/utils.Tpo .deps/utils.Po 368 | /bin/bash ./libtool --tag=CC --mode=link gcc -g -O2 -pthread -L. -L/usr/local/lib -L/lib -o tac_plus acct.o authen.o author.o choose_authen.o config.o default_fn.o default_v0_fn.o do_acct.o do_author.o dump.o enable.o encrypt.o expire.o hash.o maxsessint.o parse.o programs.o pw.o pwlib.o report.o sendauth.o sendpass.o tac_plus.o utils.o -lwrap -ltacacs -lnsl -lcrypt 369 | libtool: link: gcc -g -O2 -pthread -o .libs/tac_plus acct.o authen.o author.o choose_authen.o config.o default_fn.o default_v0_fn.o do_acct.o do_author.o dump.o enable.o encrypt.o expire.o hash.o maxsessint.o parse.o programs.o pw.o pwlib.o report.o sendauth.o sendpass.o tac_plus.o utils.o -L. -L/usr/local/lib -L/lib -lwrap /home/pi/downloads/tacacs-F4.0.4.28/.libs/libtacacs.so -lnsl -lcrypt -pthread 370 | gmake[2]: Entering directory '/home/pi/downloads/tacacs-F4.0.4.28' 371 | /usr/bin/mkdir -p '/usr/local/lib' 372 | /bin/bash ./libtool --mode=install /usr/bin/install -c libtacacs.la '/usr/local/lib' 373 | libtool: install: /usr/bin/install -c .libs/libtacacs.so.1.0.0 /usr/local/lib/libtacacs.so.1.0.0 374 | libtool: install: (cd /usr/local/lib && { ln -s -f libtacacs.so.1.0.0 libtacacs.so.1 || { rm -f libtacacs.so.1 && ln -s libtacacs.so.1.0.0 libtacacs.so.1; }; }) 375 | libtool: install: (cd /usr/local/lib && { ln -s -f libtacacs.so.1.0.0 libtacacs.so || { rm -f libtacacs.so && ln -s libtacacs.so.1.0.0 libtacacs.so; }; }) 376 | libtool: install: /usr/bin/install -c .libs/libtacacs.lai /usr/local/lib/libtacacs.la 377 | libtool: install: /usr/bin/install -c .libs/libtacacs.a /usr/local/lib/libtacacs.a 378 | libtool: install: chmod 644 /usr/local/lib/libtacacs.a 379 | libtool: install: ranlib /usr/local/lib/libtacacs.a 380 | libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/sbin" ldconfig -n /usr/local/lib 381 | ---------------------------------------------------------------------- 382 | Libraries have been installed in: 383 | /usr/local/lib 384 | 385 | If you ever happen to want to link against installed libraries 386 | in a given directory, LIBDIR, you must either use libtool, and 387 | specify the full pathname of the library, or use the `-LLIBDIR' 388 | flag during linking and do at least one of the following: 389 | - add LIBDIR to the `LD_LIBRARY_PATH' environment variable 390 | during execution 391 | - add LIBDIR to the `LD_RUN_PATH' environment variable 392 | during linking 393 | - use the `-Wl,-rpath -Wl,LIBDIR' linker flag 394 | - have your system administrator add LIBDIR to `/etc/ld.so.conf' 395 | 396 | See any operating system documentation about shared libraries for 397 | more information, such as the ld(1) and ld.so(8) manual pages. 398 | ---------------------------------------------------------------------- 399 | /usr/bin/mkdir -p '/usr/local/bin' 400 | /bin/bash ./libtool --mode=install /usr/bin/install -c tac_pwd '/usr/local/bin' 401 | libtool: install: /usr/bin/install -c tac_pwd /usr/local/bin/tac_pwd 402 | /usr/bin/mkdir -p '/usr/local/sbin' 403 | /bin/bash ./libtool --mode=install /usr/bin/install -c tac_plus '/usr/local/sbin' 404 | libtool: install: /usr/bin/install -c .libs/tac_plus /usr/local/sbin/tac_plus 405 | /usr/bin/mkdir -p '/usr/local/include' 406 | /usr/bin/install -c -m 644 tacacs.h '/usr/local/include' 407 | /usr/bin/mkdir -p '/usr/local/share/man/man5' 408 | /usr/bin/install -c -m 644 tac_plus.conf.5 '/usr/local/share/man/man5' 409 | /usr/bin/mkdir -p '/usr/local/share/man/man8' 410 | /usr/bin/install -c -m 644 tac_plus.8 tac_pwd.8 '/usr/local/share/man/man8' 411 | /usr/bin/mkdir -p '/usr/local/share/tacacs' 412 | /usr/bin/install -c -m 644 do_auth.py users_guide '/usr/local/share/tacacs' 413 | /usr/bin/mkdir -p '/usr/local/share/tacacs' 414 | /usr/bin/install -c tac_convert '/usr/local/share/tacacs' 415 | gmake[2]: Leaving directory '/home/pi/downloads/tacacs-F4.0.4.28' 416 | gmake[1]: Leaving directory '/home/pi/downloads/tacacs-F4.0.4.28' 417 | ``` 418 | 419 |
420 | 421 | 1. As a last step, rerun the dynamic library linker to pickup the new tacacs libraries. 422 | 423 | ```bash 424 | sudo ldconfig -v 425 | ``` 426 | 427 | ## Create a TACACS+ configuration file 428 | Before we can start our TACACS+ server (known from here on as `tac_plus` the name of the executable) we need to build the configuration file that will be used to receive and respond to all TACACS interactions from our network devices. 429 | 430 | > The configuration file shown here is a very basic one, that simply creates a single admin user. For full details on configuring a robust TACACS policy, consult the manual page for `tac_plus` that was installed along with it. 431 | > 432 | > ```bash 433 | > man tac_plus 434 | > man tac_plus.conf 435 | > ``` 436 | 437 | 1. Create the folder `/etc/tacacs` to hold all configuration details for `tac_plus` 438 | 439 | ```bash 440 | sudo mkdir /etc/tacacs 441 | ``` 442 | 443 | 1. Name your configuration file `/etc/tacacs/tac_plus.conf` and start with this basic configuration. 444 | 445 | ```bash 446 | # The TACASC shared-secret 447 | key = labtacacskey 448 | 449 | # A full admin user called 'tacacsadmin' 450 | user = tacacsadmin { 451 | default service = permit 452 | 453 | # Create a des encrypted password with the `tac_pwd` command 454 | login = des Oy6FGC2LNE6ao 455 | 456 | # Set priv 15 for user 457 | service = exec { 458 | priv-lvl = 15 459 | } 460 | } 461 | ``` 462 | 463 | 1. Check the configuration file for errors by parsing. If everything is good, you should just see your configuration file printed back out to you. 464 | 465 | ```bash 466 | tac_plus -C /etc/tacacs/tac_plus.conf -P 467 | ``` 468 | 469 |
Output from config parsing 470 | 471 | ``` 472 | # The TACASC shared-secret 473 | key = labtacacskey 474 | 475 | # A full admin user called 'tacacsadmin' 476 | user = tacacsadmin { 477 | default service = permit 478 | 479 | # Create a des encrypted password with the `tac_pwd` command 480 | login = des Oy6FGC2LNE6ao 481 | 482 | # Set priv 15 for user 483 | service = exec { 484 | priv-lvl = 15 485 | } 486 | } 487 | ``` 488 | 489 |
490 | 491 | 1. Start-up `tac_plus` on the server. In this command we provide the configuration file as well as enable debugging of all authorization and authentication messages to the log file `/var/log/tac_plus.log`. This will make it easier to monitor status of TACACS interactions to the server. 492 | 493 | ```bash 494 | sudo tac_plus -C /etc/tacacs/tac_plus.conf \ 495 | -d 8 \ 496 | -d 16 \ 497 | -l /var/log/tac_plus.log 498 | ``` 499 | 500 |
tac_plus debug options 501 | 502 | Here are the options available for debugging. Just add another `-d` option with each type of debugging you want. 503 | 504 | ``` 505 | Value Meaning 506 | 2 configuration parsing debugging 507 | 4 fork(1) debugging 508 | 8 authorization debugging 509 | 16 authentication debugging 510 | 32 password file processing debugging 511 | 64 accounting debugging 512 | 128 config file parsing & lookup 513 | 256 packet transmission/reception 514 | 512 encryption/decryption 515 | 1024 MD5 hash algorithm debugging 516 | 2048 very low level encryption/decryption 517 | 32768 max session debugging 518 | 65536 lock debugging 519 | ``` 520 | 521 |
522 | 523 | 1. If/when you want to stop `tac_plus` when started like this, use `sudo killall tac_plus` 524 | 525 | ## Configure a network device for TACACS 526 | With our TACACS+ server up and operational, let's configure a newtork device to use it for authentication and authorization. 527 | 528 | > For this example I am using a Cisco Catalyst 3650 switch (WS-C3650-24TS-S). 529 | 530 | 1. Before we setup TACACS authentication, let's make sure we keep the console without login in case something goes wrong. 531 | 532 | ``` 533 | aaa new-model 534 | ! 535 | aaa authentication login CONSOLE none 536 | ! 537 | line con 0 538 | login authentication CONSOLE 539 | ``` 540 | 541 | 1. Next we'll configure the tacacs server, as well as the interface on our device to send the tacacs messages from. 542 | > Configuring the source interface isn't strictly required, but I always like to be explicit 543 | 544 | ``` 545 | ip tacacs source-interface Vlan192 546 | 547 | ! Providing the TACACS server address by DNS name is supported, 548 | ! but IOS XE replaces the name with an IP before applying config 549 | tacacs server lab-server 550 | address ipv4 lab-server.lab.example 551 | key labtacacskey 552 | ``` 553 | 554 | 1. We can test and verify that tacacs is working before configuring the switch to use it with this enable mode command. 555 | 556 | ``` 557 | ! The test command for user 'tacacsadmin' and password 'password' 558 | test aaa group tacacs+ tacacsadmin password legacy 559 | 560 | ! Output 561 | Attempting authentication test to server-group tacacs+ using tacacs+ 562 | User was successfully authenticated. 563 | ``` 564 | 565 | > Success! 566 | 567 | 1. If you tail the tac_plus.log on `lab-server` you should see the messages coming in. 568 | 569 | ```bash 570 | tail -f /var/log/tac_plus.log 571 | 572 | # Ouput 573 | Sun Feb 27 19:42:43 2022 [116628]: connect from 192.168.192.101 [192.168.192.101] 574 | Sun Feb 27 19:42:44 2022 [116628]: login query for 'tacacsadmin' port unknown-port from 192.168.192.101 accepted 575 | ``` 576 | 577 | 1. Next up, let's enable the `aaa authentication` and `aaa authorization` on the switch. 578 | 579 | ``` 580 | aaa authentication login default group tacacs+ local 581 | aaa authorization exec default group tacacs+ local 582 | ``` 583 | 584 | > Because we configure `default`, we don't need to explicitly change set the `aaa group` on the `line` config 585 | 586 | 1. An attempt to ssh to the switch prompts for credentials. Providing the TACACS username works. 587 | 588 | ``` 589 | ssh tacacsadmin@192.168.192.101 590 | Password: ************ 591 | 592 | lab-switch# 593 | ``` 594 | 595 | 1. And the log on `lab-server` shows the full AAA communication process including both the authentication and authorization happening. 596 | 597 | ``` 598 | Sun Feb 27 19:47:57 2022 [116906]: connect from 192.168.192.101 [192.168.192.101] 599 | Sun Feb 27 19:47:59 2022 [116906]: login query for 'tacacsadmin' port tty2 from 192.168.192.101 accepted 600 | Sun Feb 27 19:47:59 2022 [116907]: connect from 192.168.192.101 [192.168.192.101] 601 | Sun Feb 27 19:47:59 2022 [116907]: Start authorization request 602 | Sun Feb 27 19:47:59 2022 [116907]: do_author: user='tacacsadmin' 603 | Sun Feb 27 19:47:59 2022 [116907]: user 'tacacsadmin' found 604 | Sun Feb 27 19:47:59 2022 [116907]: exec authorization request for tacacsadmin 605 | Sun Feb 27 19:47:59 2022 [116907]: exec is explicitly permitted by line 12 606 | Sun Feb 27 19:47:59 2022 [116907]: nas:service=shell (passed thru) 607 | Sun Feb 27 19:47:59 2022 [116907]: nas:cmd* (passed thru) 608 | Sun Feb 27 19:47:59 2022 [116907]: nas:absent, server:priv-lvl=15 -> add priv-lvl=15 (k) 609 | Sun Feb 27 19:47:59 2022 [116907]: added 1 args 610 | Sun Feb 27 19:47:59 2022 [116907]: out_args[0] = service=shell input copy discarded 611 | Sun Feb 27 19:47:59 2022 [116907]: out_args[1] = cmd* input copy discarded 612 | Sun Feb 27 19:47:59 2022 [116907]: out_args[2] = priv-lvl=15 compacted to out_args[0] 613 | Sun Feb 27 19:47:59 2022 [116907]: 1 output args 614 | Sun Feb 27 19:47:59 2022 [116907]: authorization query for 'tacacsadmin' tty2 from 192.168.192.101 accepted 615 | ``` 616 | 617 | ## Setting `tac_plus` up as a systemd service 618 | Manually starting and stopping `tac_plus` isn't that complicated, but wouldn't it be great if it acted like the DNS and DHCP servers? Starting with the RPi automatically, and using `systemctl` commands to manage it? We can set that up by creating an systemd service file tac_plus. 619 | 620 | > A full discussion of systemd and services is beyond this guide. 621 | 622 | 1. Create a file called `tac_plus.service` in the directory `/etc/systemd/system` with this contents. 623 | 624 | ``` 625 | [Unit] 626 | Description=TACACS+ Server 627 | Documentation=man:tac_plus(8) man:tac_plus.conf(5) 628 | After=network.target 629 | 630 | [Service] 631 | Type=simple 632 | ExecStartPre=/usr/local/sbin/tac_plus -P -C /etc/tacacs/tac_plus.conf 633 | ExecStart=/usr/local/sbin/tac_plus -G -C /etc/tacacs/tac_plus.conf -d 8 -d 16 -l /var/log/tac_plus.log 634 | ExecReload=/bin/sh -c "/usr/local/sbin/tac_plus -P -C /etc/tacacs/tac_plus.conf >/dev/null 2>&1" && /bin/kill -HUP $MAINPID 635 | Restart=always 636 | 637 | [Install] 638 | WantedBy=multi-user.target 639 | ``` 640 | 641 | 1. After you create the file, make sure systemd takes note of the changes by reloading. 642 | 643 | ```bash 644 | sudo systemctl daemon-reload 645 | ``` 646 | 647 | 1. Before trying to start the service, make sure that there isn't an instance running already. 648 | 649 | ```bash 650 | sudo killall tac_plus 651 | ``` 652 | 653 | 1. Now startup the service. 654 | 655 | ```bash 656 | sudo systemctl start tac_plus.service 657 | ``` 658 | 659 | > You can check status of the service with `systemctl status tac_plus.service` 660 | 661 | 1. If you want to configure the new `tac_plus.service` to start automatically when the RPi starts. 662 | 663 | ```bash 664 | sudo systemctl enable tac_plus 665 | ``` 666 | 667 | 1. The log file is still created and maintained, but you can also use the journal to montior status. 668 | 669 | ```bash 670 | journalctl -xef -u tac_plus 671 | ``` 672 | 673 | ## Final Thoughts 674 | Now that we've got a TACACS server up and running in our lab, we can begin to explore all the ways TACACS can be used to secure access to our network devices. You can create read-only users, custom command lists, and setup accounting for each command. The details in the `tac_plus.conf` man page will show you how all this is setup, or a bit of searching online will find lots of examples from other engineers using `tac_plus` in their setups. 675 | 676 | And a bonus I learned after using `tac_plus` for awhile, I found I had a much better understanding of how TACACS worked than when I used one of the more polished commercial TACACS servers like Cisco ISE. Not that I would want to give those up in the production networks. -------------------------------------------------------------------------------- /traffic-analysis.md: -------------------------------------------------------------------------------- 1 | # Traffic Analysis and Capture 2 | - [tcpdump - The basic network packet analyzer](#tcpdump---the-basic-network-packet-analyzer) 3 | * [Installing tcpdump](#installing-tcpdump) 4 | * [Viewing "normal" traffic to/from the RPi](#viewing--normal--traffic-to-from-the-rpi) 5 | * [`tcpdump` "verbosity"](#-tcpdump---verbosity-) 6 | - [Span / Monitor Sessions on a Switch](#span---monitor-sessions-on-a-switch) 7 | * [Configuring the Monitor Session](#configuring-the-monitor-session) 8 | * [Capture Example 1: DNS Resolution](#capture-example-1--dns-resolution) 9 | * [Capture Example 2: Telnet](#capture-example-2--telnet) 10 | * [Capture Example 3: Creating a PCAP file](#capture-example-3--creating-a-pcap-file) 11 | - [Final Thoughts](#final-thoughts) 12 | * [What about Wireshark?](#what-about-wireshark-) 13 | 14 | Table of contents generated with markdown-toc 15 | 16 | 17 | An often repeated comment in network engineering is "packets don't lie", or maybe the request to "show me the pcap". There is nothing quite like looking at the packets as they flow across the network to help you understand how things work. And a great place to begin explore this side of network engineering is in your home lab. 18 | 19 | As an inexpensive computer, a Raspberry Pi makes a great network sensor. In this guide we'll look at how we can get started quickly with this exploration. 20 | 21 | > Note: Entire courses, books, videos, etc exist on the topic of packet analysis. This short guide is not meant to replace them, but rather show a quick example of how to get started on your Raspberry Pi. 22 | 23 | # tcpdump - The basic network packet analyzer 24 | tcpdump is a command line packet analyzer that is great for packet analysis work because it is small, lightweight, and available nearly anywhere Linux exists. With tcpdump you can monitor the traffic seen by your computer with powerful filters to drill in and view only the data you want. Filtering is important because network, particularly production networks, are VERY busy. And even a lightly used lab network may shock you with how much traffic is happening. 25 | 26 | Some examples of ways filters can be useful include: 27 | 28 | * Capturing traffic with specific source or destination IP addresses or MAC addresses 29 | * Capturing traffic from certain TCP or UDP ports 30 | * Capture traffic based on network/mask matching 31 | * Capturing all broadcast or multicast traffic 32 | * Capturing packets of a certain size 33 | 34 | ## Installing tcpdump 35 | tcpdump can be installed like most other Linux programs, using `apt-get`. 36 | 37 | ```bash 38 | sudo apt-get install tcpdump 39 | ``` 40 | 41 |
Output: Install tcpdump 42 | 43 | ``` 44 | Reading package lists... Done 45 | Building dependency tree... Done 46 | Reading state information... Done 47 | The following additional packages will be installed: 48 | libpcap0.8 49 | Suggested packages: 50 | apparmor 51 | The following NEW packages will be installed: 52 | libpcap0.8 tcpdump 53 | 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded. 54 | Need to get 588 kB of archives. 55 | After this operation, 1,740 kB of additional disk space will be used. 56 | Do you want to continue? [Y/n] y 57 | Get:1 http://deb.debian.org/debian bullseye/main arm64 libpcap0.8 arm64 1.10.0-2 [151 kB] 58 | Get:2 http://deb.debian.org/debian bullseye/main arm64 tcpdump arm64 4.99.0-2 [437 kB] 59 | Fetched 588 kB in 1s (762 kB/s) 60 | Selecting previously unselected package libpcap0.8:arm64. 61 | (Reading database ... 35664 files and directories currently installed.) 62 | Preparing to unpack .../libpcap0.8_1.10.0-2_arm64.deb ... 63 | Unpacking libpcap0.8:arm64 (1.10.0-2) ... 64 | Selecting previously unselected package tcpdump. 65 | Preparing to unpack .../tcpdump_4.99.0-2_arm64.deb ... 66 | Unpacking tcpdump (4.99.0-2) ... 67 | Setting up libpcap0.8:arm64 (1.10.0-2) ... 68 | Setting up tcpdump (4.99.0-2) ... 69 | Processing triggers for man-db (2.9.4-2) ... 70 | Processing triggers for libc-bin (2.31-13+rpt2+rpi1+deb11u2) ... 71 | ``` 72 | 73 |
74 | 75 | Once installed, you can check the version and basic help info for the command. 76 | 77 | ```bash 78 | tcpdump --help 79 | 80 | # Output 81 | tcpdump version 4.99.0 82 | libpcap version 1.10.0 (with TPACKET_V3) 83 | OpenSSL 1.1.1k 25 Mar 2021 84 | Usage: tcpdump [-AbdDefhHIJKlLnNOpqStuUvxX#] [ -B size ] [ -c count ] [--count] 85 | [ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ] 86 | [ -i interface ] [ --immediate-mode ] [ -j tstamptype ] 87 | [ -M secret ] [ --number ] [ --print ] [ -Q in|out|inout ] 88 | [ -r file ] [ -s snaplen ] [ -T type ] [ --version ] 89 | [ -V file ] [ -w file ] [ -W filecount ] [ -y datalinktype ] 90 | [ --time-stamp-precision precision ] [ --micro ] [ --nano ] 91 | [ -z postrotate-command ] [ -Z user ] [ expression ] 92 | ``` 93 | 94 | > For full details on using tcpdump, you can explore `man tcpdump`, or search online for one of many great Introductions/Tutorials on tcpdump 95 | > 96 | > There are are also many "tcpdump cheatsheets" like [this one by Jeremy Stretch (of NetBox fame)](https://packetlife.net/media/library/12/tcpdump.pdf) 97 | 98 | ## Viewing "normal" traffic to/from the RPi 99 | For our first examples, we will look at traffic reaching the RPi without any special network configuration on the switch. This is simply what is being sent to the RPi as a regular host on the network. 100 | 101 | First up, you will often want to limit tcpdump to specific interfaces on the computer. Let's see what interfaces are available to tcpdump. 102 | 103 | ```bash 104 | tcpdump -D 105 | 106 | # Output 107 | 1.eth0 [Up, Running, Connected] 108 | 2.wlan0 [Up, Running, Wireless] 109 | 3.any (Pseudo-device that captures on all interfaces) [Up, Running] 110 | 4.lo [Up, Running, Loopback] 111 | 5.bluetooth0 (Bluetooth adapter number 0) [Wireless, Association status unknown] 112 | 6.bluetooth-monitor (Bluetooth Linux Monitor) [Wireless] 113 | 7.nflog (Linux netfilter log (NFLOG) interface) [none] 114 | 8.nfqueue (Linux netfilter queue (NFQUEUE) interface) [none] 115 | 9.dbus-system (D-Bus system bus) [none] 116 | 10.dbus-session (D-Bus session bus) [none] 117 | ``` 118 | 119 | See anything surprising? The `eth0` and `wlan0` interfaces are probably expected, but look at all those other options you can explore later. 120 | 121 | We'll stick with `eth0` for our exploration as that is the one connected to the network-lab. 122 | 123 | We'll start simple listen command. 124 | 125 | ```bash 126 | tcpdump -i eth0 127 | 128 | # Output 129 | tcpdump: eth0: You do not have permission to capture on that device 130 | (socket: Operation not permitted) 131 | ``` 132 | 133 | ***Important: Capturing traffic from a network interface requires admin rights. So you'll need to `sudo` it.*** 134 | 135 | ```bash 136 | sudo tcpdump -i eth0 137 | ``` 138 | 139 | > Note: Stop the capture by pressing `Cntl-c` 140 | 141 | ***Output*** 142 | 143 | ```text 144 | tcpdump: verbose output suppressed, use -v[v]... for full protocol decode 145 | listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes 146 | 20:29:18.374804 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 147 | 20:29:20.375247 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 148 | 20:29:20.792884 Loopback, skipCount 0, Reply, receipt number 0, data (40 octets) 149 | 20:29:22.376125 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 150 | 20:29:24.377202 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 151 | 20:29:26.378899 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 152 | 20:29:28.380114 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 153 | 20:29:30.381316 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 154 | 20:29:30.795250 Loopback, skipCount 0, Reply, receipt number 0, data (40 octets) 155 | 20:29:32.381832 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 156 | 20:29:34.382630 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 157 | 20:29:36.385373 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 158 | 20:29:38.385190 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 159 | 20:29:40.385632 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 160 | 20:29:40.794914 Loopback, skipCount 0, Reply, receipt number 0, data (40 octets) 161 | 20:29:42.386416 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 162 | 20:29:44.386368 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 163 | 20:29:45.337471 IP 192.168.192.11 > 192.168.192.102: ICMP echo request, id 1, seq 1, length 64 164 | 20:29:45.337589 IP 192.168.192.102 > 192.168.192.11: ICMP echo reply, id 1, seq 1, length 64 165 | 20:29:46.338820 IP 192.168.192.11 > 192.168.192.102: ICMP echo request, id 1, seq 2, length 64 166 | 20:29:46.338915 IP 192.168.192.102 > 192.168.192.11: ICMP echo reply, id 1, seq 2, length 64 167 | 20:29:46.386796 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 168 | 20:29:48.388350 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 169 | 20:29:50.387681 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 170 | 20:29:50.546748 ARP, Request who-has 192.168.192.102 tell 192.168.192.11, length 46 171 | 20:29:50.546810 ARP, Reply 192.168.192.102 is-at b8:27:eb:d3:22:e7 (oui Unknown), length 28 172 | 20:29:50.556861 ARP, Request who-has 192.168.192.11 tell 192.168.192.102, length 28 173 | 20:29:50.557542 ARP, Reply 192.168.192.11 is-at b8:27:eb:18:a6:8c (oui Unknown), length 46 174 | 20:29:50.792716 Loopback, skipCount 0, Reply, receipt number 0, data (40 octets) 175 | 20:29:52.389203 STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 80c0.a0:ec:f9:ab:39:80.800b, length 36 176 | ^C 177 | 30 packets captured 178 | 30 packets received by filter 179 | 0 packets dropped by kernel 180 | ``` 181 | 182 | Check that out! What can we see in the output 183 | 184 | 1. Spanning-tree BPDU's from the network switch every 2 seconds 185 | 1. Some loopback messages {shrug} 186 | 1. ICMP echo requests and replys 187 | * While the capture was running I sent 2 `pings` from the other RPi in the lab to generate some traffic 188 | 1. ARP traffic from the other RPi requesting MAC address for this RPi's IP address 189 | 190 | Not to bad for a first capture. But you might be wondering... "is that all that is on the network"? The answer is no. 191 | 192 | ## `tcpdump` "verbosity" 193 | 194 | By default tcpdump provides only certain details on the "dump line" for each packet. But you can adjust this detail with options. A basic one is the "verbosity option" which is `-v`. It has three levels of increasing verbosity. 195 | 196 | Let's see the difference in output for DHCP traffic to compare. 197 | 198 | > We will use a `port` based filter to select the DHCP traffic. We'll grab any traffic on `port 67 or port 68`. 199 | > 200 | > Filters are referred to as "expressions" and can be crafted to be very specific for the type of traffic you are interested in. 201 | 202 | * Single level of verbosity 203 | 204 |
sudo tcpdump -i eth0 -v port 67 or port 68 205 | 206 | ``` 207 | tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes 208 | 20:46:02.181634 IP (tos 0x0, ttl 64, id 40790, offset 0, flags [DF], proto UDP (17), length 328) 209 | 192.168.192.102.bootpc > 192.168.192.11.bootps: BOOTP/DHCP, Request from b8:27:eb:d3:22:e7 (oui Unknown), length 300, xid 0xde321e7e, secs 65535, Flags [none] 210 | Client-IP 192.168.192.102 211 | Client-Ethernet-Address b8:27:eb:d3:22:e7 (oui Unknown) 212 | Vendor-rfc1048 Extensions 213 | Magic Cookie 0x63825363 214 | DHCP-Message (53), length 1: Request 215 | Client-ID (61), length 7: ether b8:27:eb:d3:22:e7 216 | MSZ (57), length 2: 1472 217 | Hostname (12), length 10: "lab-client" 218 | Unknown (145), length 1: 1 219 | Parameter-Request (55), length 14: 220 | Subnet-Mask (1), Classless-Static-Route (121), Static-Route (33), Default-Gateway (3) 221 | Domain-Name-Server (6), Hostname (12), Domain-Name (15), MTU (26) 222 | BR (28), Lease-Time (51), Server-ID (54), RN (58) 223 | RB (59), Unknown (119) 224 | 20:46:02.194360 IP (tos 0x0, ttl 64, id 39778, offset 0, flags [DF], proto UDP (17), length 328) 225 | 192.168.192.11.bootps > 192.168.192.102.bootpc: BOOTP/DHCP, Reply, length 300, xid 0xde321e7e, secs 65535, Flags [none] 226 | Client-IP 192.168.192.102 227 | Your-IP 192.168.192.102 228 | Client-Ethernet-Address b8:27:eb:d3:22:e7 (oui Unknown) 229 | Vendor-rfc1048 Extensions 230 | Magic Cookie 0x63825363 231 | DHCP-Message (53), length 1: ACK 232 | Server-ID (54), length 4: 192.168.192.11 233 | Lease-Time (51), length 4: 300 234 | Subnet-Mask (1), length 4: 255.255.255.0 235 | Default-Gateway (3), length 4: 192.168.192.1 236 | Domain-Name-Server (6), length 4: 192.168.192.11 237 | Domain-Name (15), length 11: "lab.example" 238 | 239 | ^C 240 | 2 packets captured 241 | 2 packets received by filter 242 | 0 packets dropped by kernel 243 | ``` 244 | 245 |
246 | 247 | * Double level of verbosity 248 | 249 |
sudo tcpdump -i -vv port 67 or port 68 250 | 251 | ``` 252 | tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes 253 | 20:46:58.728952 IP (tos 0x0, ttl 64, id 16856, offset 0, flags [none], proto UDP (17), length 328) 254 | 192.168.192.102.bootpc > 255.255.255.255.bootps: [udp sum ok] BOOTP/DHCP, Request from b8:27:eb:d3:22:e7 (oui Unknown), length 300, xid 0xe4ccbcfa, Flags [none] (0x0000) 255 | Client-Ethernet-Address b8:27:eb:d3:22:e7 (oui Unknown) 256 | Vendor-rfc1048 Extensions 257 | Magic Cookie 0x63825363 258 | DHCP-Message (53), length 1: Request 259 | Client-ID (61), length 7: ether b8:27:eb:d3:22:e7 260 | Requested-IP (50), length 4: 192.168.192.102 261 | MSZ (57), length 2: 1472 262 | Hostname (12), length 10: "lab-client" 263 | Unknown (145), length 1: 1 264 | Parameter-Request (55), length 14: 265 | Subnet-Mask (1), Classless-Static-Route (121), Static-Route (33), Default-Gateway (3) 266 | Domain-Name-Server (6), Hostname (12), Domain-Name (15), MTU (26) 267 | BR (28), Lease-Time (51), Server-ID (54), RN (58) 268 | RB (59), Unknown (119) 269 | 20:46:58.787673 IP (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328) 270 | 192.168.192.11.bootps > 192.168.192.102.bootpc: [udp sum ok] BOOTP/DHCP, Reply, length 300, xid 0xe4ccbcfa, Flags [none] (0x0000) 271 | Your-IP 192.168.192.102 272 | Client-Ethernet-Address b8:27:eb:d3:22:e7 (oui Unknown) 273 | Vendor-rfc1048 Extensions 274 | Magic Cookie 0x63825363 275 | DHCP-Message (53), length 1: ACK 276 | Server-ID (54), length 4: 192.168.192.11 277 | Lease-Time (51), length 4: 300 278 | Subnet-Mask (1), length 4: 255.255.255.0 279 | Default-Gateway (3), length 4: 192.168.192.1 280 | Domain-Name-Server (6), length 4: 192.168.192.11 281 | Domain-Name (15), length 11: "lab.example" 282 | ^C 283 | 2 packets captured 284 | 2 packets received by filter 285 | 0 packets dropped by kernel 286 | ``` 287 | 288 |
289 | 290 | * Triple level of verbosity 291 | 292 |
sudo tcpdump -i eth0 -vvv port 67 or port 68 293 | 294 | ``` 295 | tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes 296 | 20:48:14.780990 IP (tos 0x0, ttl 64, id 48085, offset 0, flags [none], proto UDP (17), length 328) 297 | 192.168.192.102.bootpc > 255.255.255.255.bootps: [udp sum ok] BOOTP/DHCP, Request from b8:27:eb:d3:22:e7 (oui Unknown), length 300, xid 0xaad2fc4c, Flags [none] (0x0000) 298 | Client-Ethernet-Address b8:27:eb:d3:22:e7 (oui Unknown) 299 | Vendor-rfc1048 Extensions 300 | Magic Cookie 0x63825363 301 | DHCP-Message (53), length 1: Request 302 | Client-ID (61), length 7: ether b8:27:eb:d3:22:e7 303 | Requested-IP (50), length 4: 192.168.192.102 304 | MSZ (57), length 2: 1472 305 | Hostname (12), length 10: "lab-client" 306 | Unknown (145), length 1: 1 307 | Parameter-Request (55), length 14: 308 | Subnet-Mask (1), Classless-Static-Route (121), Static-Route (33), Default-Gateway (3) 309 | Domain-Name-Server (6), Hostname (12), Domain-Name (15), MTU (26) 310 | BR (28), Lease-Time (51), Server-ID (54), RN (58) 311 | RB (59), Unknown (119) 312 | END (255), length 0 313 | PAD (0), length 0, occurs 6 314 | 20:48:15.462075 IP (tos 0x10, ttl 128, id 0, offset 0, flags [none], proto UDP (17), length 328) 315 | 192.168.192.11.bootps > 192.168.192.102.bootpc: [udp sum ok] BOOTP/DHCP, Reply, length 300, xid 0xaad2fc4c, Flags [none] (0x0000) 316 | Your-IP 192.168.192.102 317 | Client-Ethernet-Address b8:27:eb:d3:22:e7 (oui Unknown) 318 | Vendor-rfc1048 Extensions 319 | Magic Cookie 0x63825363 320 | DHCP-Message (53), length 1: ACK 321 | Server-ID (54), length 4: 192.168.192.11 322 | Lease-Time (51), length 4: 300 323 | Subnet-Mask (1), length 4: 255.255.255.0 324 | Default-Gateway (3), length 4: 192.168.192.1 325 | Domain-Name-Server (6), length 4: 192.168.192.11 326 | Domain-Name (15), length 11: "lab.example" 327 | END (255), length 0 328 | PAD (0), length 0, occurs 13 329 | 330 | 2 packets captured 331 | 2 packets received by filter 332 | 0 packets dropped by kernel 333 | ``` 334 | 335 |
336 | 337 | If you look at the three example above you might find a few difference, but there aren't a lot. If we look at the man page for the option you'll see there are specific protocols where the different levels matter more. In most cases, a single `-v` is probably enough, but don't be afraid to crank it up. 338 | 339 | ``` 340 | -v When parsing and printing, produce (slightly more) verbose output. For example, the time to 341 | live, identification, total length and options in an IP packet are printed. Also enables ad‐ 342 | ditional packet integrity checks such as verifying the IP and ICMP header checksum. 343 | 344 | -vv Even more verbose output. For example, additional fields are printed from NFS reply packets, 345 | and SMB packets are fully decoded. 346 | 347 | -vvv Even more verbose output. For example, telnet SB ... SE options are printed in full. With 348 | -X Telnet options are printed in hex as well. 349 | ``` 350 | 351 | # Span / Monitor Sessions on a Switch 352 | The real fun of packet analysis is when you monitor traffic sent on the network to hosts other than the one you are running your capture tool on. This is when your RPi becomes a "network sensor" or "tap". Let's setup a span session on the network switch to send all traffic destined to the `lab-server` to the `lab-client` RPi. 353 | 354 | > `lab-server` is another Raspberry Pi that is configured to host DNS, DHCP, and provide other services to the network. 355 | 356 | > For this example I am using a Cisco Catalyst 3650 switch (WS-C3650-24TS-S). 357 | 358 | ## Configuring the Monitor Session 359 | This configuration creates a `monitor session` on my switch that will copy all traffic (`rx` and `tx`) on port `GigabitEthernet 1/0/1` where `lab-server` is connected to `GigabitEthernet 1/0/11` where `lab-client` is connected. 360 | 361 | ``` 362 | monitor session 1 source interface Gi1/0/1 363 | monitor session 1 destination interface Gi1/0/11 364 | ``` 365 | 366 | > Note: When a switch interface is setup as a `monitor destination`, normal operation of the interface is disrupted. In effect the port becomes ***JUST*** a span port for monitoring traffic. Some network devices support forwarding on destination ports as well, but that may require extra configuration and is out of scope for this guide. 367 | 368 | Let's check the configuration. 369 | 370 | ``` 371 | show monitor session 1 372 | 373 | # Output 374 | Session 1 375 | --------- 376 | Type : Local Session 377 | Source Ports : 378 | Both : Gi1/0/1 379 | Destination Ports : Gi1/0/11 380 | Encapsulation : Native 381 | Ingress : Disabled 382 | ``` 383 | 384 | ## Capture Example 1: DNS Resolution 385 | Let's look at the DNS resolution process at the packet level. 386 | 387 | > We filter `port 53` because DNS runs on `tcp/53` and `udp/53` 388 | 389 | ```bash 390 | sudo tcpdump -i eth0 -v port 53 391 | ``` 392 | 393 | Then with this running, I attempt to ping the `lab-switch.lab.example` from another host on the network. This results in a name lookup to `lab-server`. 394 | 395 | ``` 396 | # Output 397 | 21:30:37.250480 IP (tos 0x0, ttl 254, id 0, offset 0, flags [none], proto UDP (17), length 79) 398 | 192.168.192.101.16766 > 192.168.192.11.domain: 28104+ [1au] A? lab-switch.lab.example. (51) 399 | 21:30:37.251467 IP (tos 0x0, ttl 64, id 21124, offset 0, flags [none], proto UDP (17), length 95) 400 | 192.168.192.11.domain > 192.168.192.101.16766: 28104* 1/0/1 lab-switch.lab.example. A 192.168.192.101 (67) 401 | ``` 402 | 403 | Two packets are seen, first for the `request` and then for the `reply`. 404 | 405 | ## Capture Example 2: Telnet 406 | One of my favorite things to look at with packet captures are network applications to show why encryption is so important. In this example we'll monitor telnet traffic to/from the `lab-server` while it logs into the network switch. But to truly understand what is being sent, we'll want to look at the full payload of the traffic. 407 | 408 | ```bash 409 | sudo tcpdump -i eth0 -v -X port 23 410 | ``` 411 | 412 | > The `-X` option will display the frame in both HEX and ASCII format. The ASCII format makes it easier on us humans to recognized data in the packets. 413 | 414 | With this running, I telnet into the switch and login. Here is the captured output from the login process. There is ***ALOT*** of packets because of some important facts about how telnet works for switch CLI. 415 | 416 | 1. Each letter/button you press is sent to the switch, not just when you press "enter". 417 | * So typing the command `show version` will send 12 packets. One for each letter and one for "ENTER". 418 | 1. Telnet is a TCP protocol, so each packet is checked and acknowledged. You can follow that in the packets as well 419 | 420 |
Packets from the Login Process Over Telnet with Comments 421 | 422 | ``` 423 | ### Setting up connection 424 | 425 | 21:45:29.749649 IP (tos 0x10, ttl 64, id 6795, offset 0, flags [DF], proto TCP (6), length 60) 426 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [S], cksum 0x5de6 (correct), seq 1740542972, win 64240, options [mss 1460,sackOK,TS val 1750529267 ecr 0,nop,wscale 7], length 0 427 | 0x0000: 4510 003c 1a8b 4000 4006 1e5f c0a8 c00b E..<..@.@.._.... 428 | 0x0010: c0a8 c065 944a 0017 67be 93fc 0000 0000 ...e.J..g....... 429 | 0x0020: a002 faf0 5de6 0000 0204 05b4 0402 080a ....]........... 430 | 0x0030: 6856 f4f3 0000 0000 0103 0307 hV.......... 431 | 21:45:29.751820 IP (tos 0x10, ttl 254, id 3085, offset 0, flags [none], proto TCP (6), length 44) 432 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [S.], cksum 0xd33e (correct), seq 2262866935, ack 1740542973, win 4128, options [mss 1460], length 0 433 | 0x0000: 4510 002c 0c0d 0000 fe06 aeec c0a8 c065 E..,...........e 434 | 0x0010: c0a8 c00b 0017 944a 86e0 9bf7 67be 93fd .......J....g... 435 | 0x0020: 6012 1020 d33e 0000 0204 05b4 0000 `....>........ 436 | 21:45:29.752258 IP (tos 0x10, ttl 64, id 6796, offset 0, flags [DF], proto TCP (6), length 40) 437 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0x002b (correct), ack 1, win 64240, length 0 438 | 0x0000: 4510 0028 1a8c 4000 4006 1e72 c0a8 c00b E..(..@.@..r.... 439 | 0x0010: c0a8 c065 944a 0017 67be 93fd 86e0 9bf8 ...e.J..g....... 440 | 0x0020: 5010 faf0 002b 0000 0000 0000 0000 P....+........ 441 | 21:45:29.752869 IP (tos 0x10, ttl 64, id 6797, offset 0, flags [DF], proto TCP (6), length 64) 442 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0xa3b9 (correct), seq 1:25, ack 1, win 64240, length 24 [telnet DO SUPPRESS GO AHEAD, WILL TERMINAL TYPE, WILL NAWS, WILL TSPEED, WILL LFLOW, WILL LINEMODE, WILL NEW-ENVIRON, DO STATUS] 443 | 0x0000: 4510 0040 1a8d 4000 4006 1e59 c0a8 c00b E..@..@.@..Y.... 444 | 0x0010: c0a8 c065 944a 0017 67be 93fd 86e0 9bf8 ...e.J..g....... 445 | 0x0020: 5018 faf0 a3b9 0000 fffd 03ff fb18 fffb P............... 446 | 0x0030: 1fff fb20 fffb 21ff fb22 fffb 27ff fd05 ......!.."..'... 447 | 21:45:29.753930 IP (tos 0x0, ttl 254, id 3086, offset 0, flags [none], proto TCP (6), length 40) 448 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [.], cksum 0xeafb (correct), ack 25, win 4104, length 0 449 | 0x0000: 4500 0028 0c0e 0000 fe06 aeff c0a8 c065 E..(...........e 450 | 0x0010: c0a8 c00b 0017 944a 86e0 9bf8 67be 9415 .......J....g... 451 | 0x0020: 5010 1008 eafb 0000 0d0a 80c0 0000 P............. 452 | 21:45:29.755211 IP (tos 0xc0, ttl 254, id 3087, offset 0, flags [none], proto TCP (6), length 52) 453 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0xd7cb (correct), seq 1:13, ack 25, win 4104, length 12 [telnet WILL ECHO, WILL SUPPRESS GO AHEAD, DO TERMINAL TYPE, DO NAWS] 454 | 0x0000: 45c0 0034 0c0f 0000 fe06 ae32 c0a8 c065 E..4.......2...e 455 | 0x0010: c0a8 c00b 0017 944a 86e0 9bf8 67be 9415 .......J....g... 456 | 0x0020: 5018 1008 d7cb 0000 fffb 01ff fb03 fffd P............... 457 | 0x0030: 18ff fd1f .... 458 | 21:45:29.755558 IP (tos 0x10, ttl 64, id 6798, offset 0, flags [DF], proto TCP (6), length 40) 459 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0x0013 (correct), ack 13, win 64228, length 0 460 | 0x0000: 4510 0028 1a8e 4000 4006 1e70 c0a8 c00b E..(..@.@..p.... 461 | 0x0010: c0a8 c065 944a 0017 67be 9415 86e0 9c04 ...e.J..g....... 462 | 0x0020: 5010 fae4 0013 0000 0000 0000 0000 P............. 463 | 21:45:29.755828 IP (tos 0x10, ttl 64, id 6799, offset 0, flags [DF], proto TCP (6), length 52) 464 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x0320 (correct), seq 25:37, ack 13, win 64228, length 12 [telnet DO ECHO, SB NAWS IS 0xb5 0 0x1c SE] 465 | 0x0000: 4510 0034 1a8f 4000 4006 1e63 c0a8 c00b E..4..@.@..c.... 466 | 0x0010: c0a8 c065 944a 0017 67be 9415 86e0 9c04 ...e.J..g....... 467 | 0x0020: 5018 fae4 0320 0000 fffd 01ff fa1f 00b5 P............... 468 | 0x0030: 001c fff0 .... 469 | 470 | 471 | ### Switch sends request for login. 472 | ### It looks like this: 473 | 474 | ############################## 475 | # User Access Verification 476 | # 477 | # Username: 478 | ############################## 479 | 480 | 21:45:29.765599 IP (tos 0xc0, ttl 254, id 3088, offset 0, flags [none], proto TCP (6), length 80) 481 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0x6545 (correct), seq 13:53, ack 37, win 4092, length 40 482 | 0x0000: 45c0 0050 0c10 0000 fe06 ae15 c0a8 c065 E..P...........e 483 | 0x0010: c0a8 c00b 0017 944a 86e0 9c04 67be 9421 .......J....g..! 484 | 0x0020: 5018 0ffc 6545 0000 0d0a 5573 6572 2041 P...eE....User.A 485 | 0x0030: 6363 6573 7320 5665 7269 6669 6361 7469 ccess.Verificati 486 | 0x0040: 6f6e 0d0a 0d0a 5573 6572 6e61 6d65 3a20 on....Username:. 487 | 21:45:29.765825 IP (tos 0xc0, ttl 254, id 3089, offset 0, flags [none], proto TCP (6), length 46) 488 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0xd2cc (correct), seq 53:59, ack 37, win 4092, length 6 [telnet SB TERMINAL TYPE SEND SE] 489 | 0x0000: 45c0 002e 0c11 0000 fe06 ae36 c0a8 c065 E..........6...e 490 | 0x0010: c0a8 c00b 0017 944a 86e0 9c2c 67be 9421 .......J...,g..! 491 | 0x0020: 5018 0ffc d2cc 0000 fffa 1801 fff0 P............. 492 | 21:45:29.766025 IP (tos 0xc0, ttl 254, id 3090, offset 0, flags [none], proto TCP (6), length 43) 493 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0xcab7 (correct), seq 59:62, ack 37, win 4092, length 3 [telnet DONT TSPEED] 494 | 0x0000: 45c0 002b 0c12 0000 fe06 ae38 c0a8 c065 E..+.......8...e 495 | 0x0010: c0a8 c00b 0017 944a 86e0 9c32 67be 9421 .......J...2g..! 496 | 0x0020: 5018 0ffc cab7 0000 fffe 2073 6572 P..........ser 497 | 498 | 499 | ### Note: Several packets related to communication removed from output 500 | 501 | 502 | ### Typing username of "tacacsadmin" begins 503 | 504 | ### Send "t" - seen at end of output 'P.......t.....' 505 | 21:45:31.400501 IP (tos 0x10, ttl 64, id 6808, offset 0, flags [DF], proto TCP (6), length 41) 506 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x8be9 (correct), seq 57:58, ack 74, win 64167, length 1 507 | 0x0000: 4510 0029 1a98 4000 4006 1e65 c0a8 c00b E..)..@.@..e.... 508 | 0x0010: c0a8 c065 944a 0017 67be 9435 86e0 9c41 ...e.J..g..5...A 509 | 0x0020: 5018 faa7 8be9 0000 7400 0000 0000 P.......t..... <---- See the 't' here 510 | 511 | ### Switch sends back "t" to print to screen 512 | 21:45:31.401854 IP (tos 0xc0, ttl 254, id 3096, offset 0, flags [none], proto TCP (6), length 41) 513 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0x76a9 (correct), seq 74:75, ack 58, win 4071, length 1 514 | 0x0000: 45c0 0029 0c18 0000 fe06 ae34 c0a8 c065 E..).......4...e 515 | 0x0010: c0a8 c00b 0017 944a 86e0 9c41 67be 9436 .......J...Ag..6 516 | 0x0020: 5018 0fe7 76a9 0000 7400 80c0 a000 P...v...t..... 517 | 518 | 21:45:31.402246 IP (tos 0x10, ttl 64, id 6809, offset 0, flags [DF], proto TCP (6), length 40) 519 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0xfff1 (correct), ack 75, win 64166, length 0 520 | 0x0000: 4510 0028 1a99 4000 4006 1e65 c0a8 c00b E..(..@.@..e.... 521 | 0x0010: c0a8 c065 944a 0017 67be 9436 86e0 9c42 ...e.J..g..6...B 522 | 0x0020: 5010 faa6 fff1 0000 0000 0000 0000 P............. 523 | 524 | ### Send and show "a" 525 | 21:45:31.548120 IP (tos 0x10, ttl 64, id 6810, offset 0, flags [DF], proto TCP (6), length 41) 526 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x9ee8 (correct), seq 58:59, ack 75, win 64166, length 1 527 | 0x0000: 4510 0029 1a9a 4000 4006 1e63 c0a8 c00b E..)..@.@..c.... 528 | 0x0010: c0a8 c065 944a 0017 67be 9436 86e0 9c42 ...e.J..g..6...B 529 | 0x0020: 5018 faa6 9ee8 0000 6100 0000 0000 P.......a..... <----- See the 'a' here 530 | 531 | 21:45:31.549584 IP (tos 0xc0, ttl 254, id 3097, offset 0, flags [none], proto TCP (6), length 41) 532 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0x89a8 (correct), seq 75:76, ack 59, win 4070, length 1 533 | 0x0000: 45c0 0029 0c19 0000 fe06 ae33 c0a8 c065 E..).......3...e 534 | 0x0010: c0a8 c00b 0017 944a 86e0 9c42 67be 9437 .......J...Bg..7 535 | 0x0020: 5018 0fe6 89a8 0000 6100 80c0 a000 P.......a..... 536 | 21:45:31.549933 IP (tos 0x10, ttl 64, id 6811, offset 0, flags [DF], proto TCP (6), length 40) 537 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0xfff0 (correct), ack 76, win 64165, length 0 538 | 0x0000: 4510 0028 1a9b 4000 4006 1e63 c0a8 c00b E..(..@.@..c.... 539 | 0x0010: c0a8 c065 944a 0017 67be 9437 86e0 9c43 ...e.J..g..7...C 540 | 0x0020: 5010 faa5 fff0 0000 0000 0000 0000 P............. 541 | 542 | ### Send and show the rest of the username 543 | 21:45:31.706842 IP (tos 0x10, ttl 64, id 6812, offset 0, flags [DF], proto TCP (6), length 41) 544 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x9ce7 (correct), seq 59:60, ack 76, win 64165, length 1 545 | 0x0000: 4510 0029 1a9c 4000 4006 1e61 c0a8 c00b E..)..@.@..a.... 546 | 0x0010: c0a8 c065 944a 0017 67be 9437 86e0 9c43 ...e.J..g..7...C 547 | 0x0020: 5018 faa5 9ce7 0000 6300 0000 0000 P.......c..... 548 | 21:45:31.708149 IP (tos 0xc0, ttl 254, id 3098, offset 0, flags [none], proto TCP (6), length 41) 549 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0x87a7 (correct), seq 76:77, ack 60, win 4069, length 1 550 | 0x0000: 45c0 0029 0c1a 0000 fe06 ae32 c0a8 c065 E..).......2...e 551 | 0x0010: c0a8 c00b 0017 944a 86e0 9c43 67be 9438 .......J...Cg..8 552 | 0x0020: 5018 0fe5 87a7 0000 6300 80c0 a000 P.......c..... 553 | 21:45:31.708532 IP (tos 0x10, ttl 64, id 6813, offset 0, flags [DF], proto TCP (6), length 40) 554 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0xffef (correct), ack 77, win 64164, length 0 555 | 0x0000: 4510 0028 1a9d 4000 4006 1e61 c0a8 c00b E..(..@.@..a.... 556 | 0x0010: c0a8 c065 944a 0017 67be 9438 86e0 9c44 ...e.J..g..8...D 557 | 0x0020: 5010 faa4 ffef 0000 0000 0000 0000 P............. 558 | 21:45:31.894636 IP (tos 0x10, ttl 64, id 6814, offset 0, flags [DF], proto TCP (6), length 41) 559 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x9ee6 (correct), seq 60:61, ack 77, win 64164, length 1 560 | 0x0000: 4510 0029 1a9e 4000 4006 1e5f c0a8 c00b E..)..@.@.._.... 561 | 0x0010: c0a8 c065 944a 0017 67be 9438 86e0 9c44 ...e.J..g..8...D 562 | 0x0020: 5018 faa4 9ee6 0000 6100 0000 0000 P.......a..... 563 | 21:45:31.896141 IP (tos 0xc0, ttl 254, id 3099, offset 0, flags [none], proto TCP (6), length 41) 564 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0x89a6 (correct), seq 77:78, ack 61, win 4068, length 1 565 | 0x0000: 45c0 0029 0c1b 0000 fe06 ae31 c0a8 c065 E..).......1...e 566 | 0x0010: c0a8 c00b 0017 944a 86e0 9c44 67be 9439 .......J...Dg..9 567 | 0x0020: 5018 0fe4 89a6 0000 6100 80c0 a000 P.......a..... 568 | 21:45:31.896498 IP (tos 0x10, ttl 64, id 6815, offset 0, flags [DF], proto TCP (6), length 40) 569 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0xffee (correct), ack 78, win 64163, length 0 570 | 0x0000: 4510 0028 1a9f 4000 4006 1e5f c0a8 c00b E..(..@.@.._.... 571 | 0x0010: c0a8 c065 944a 0017 67be 9439 86e0 9c45 ...e.J..g..9...E 572 | 0x0020: 5010 faa3 ffee 0000 0000 0000 0000 P............. 573 | 21:45:32.031195 IP (tos 0x10, ttl 64, id 6816, offset 0, flags [DF], proto TCP (6), length 41) 574 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x9ce5 (correct), seq 61:62, ack 78, win 64163, length 1 575 | 0x0000: 4510 0029 1aa0 4000 4006 1e5d c0a8 c00b E..)..@.@..].... 576 | 0x0010: c0a8 c065 944a 0017 67be 9439 86e0 9c45 ...e.J..g..9...E 577 | 0x0020: 5018 faa3 9ce5 0000 6300 0000 0000 P.......c..... 578 | 21:45:32.033477 IP (tos 0xc0, ttl 254, id 3100, offset 0, flags [none], proto TCP (6), length 41) 579 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0x87a5 (correct), seq 78:79, ack 62, win 4067, length 1 580 | 0x0000: 45c0 0029 0c1c 0000 fe06 ae30 c0a8 c065 E..).......0...e 581 | 0x0010: c0a8 c00b 0017 944a 86e0 9c45 67be 943a .......J...Eg..: 582 | 0x0020: 5018 0fe3 87a5 0000 6300 80c0 a000 P.......c..... 583 | 21:45:32.033831 IP (tos 0x10, ttl 64, id 6817, offset 0, flags [DF], proto TCP (6), length 40) 584 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0xffed (correct), ack 79, win 64162, length 0 585 | 0x0000: 4510 0028 1aa1 4000 4006 1e5d c0a8 c00b E..(..@.@..].... 586 | 0x0010: c0a8 c065 944a 0017 67be 943a 86e0 9c46 ...e.J..g..:...F 587 | 0x0020: 5010 faa2 ffed 0000 0000 0000 0000 P............. 588 | 21:45:32.134829 IP (tos 0x10, ttl 64, id 6818, offset 0, flags [DF], proto TCP (6), length 41) 589 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x8ce4 (correct), seq 62:63, ack 79, win 64162, length 1 590 | 0x0000: 4510 0029 1aa2 4000 4006 1e5b c0a8 c00b E..)..@.@..[.... 591 | 0x0010: c0a8 c065 944a 0017 67be 943a 86e0 9c46 ...e.J..g..:...F 592 | 0x0020: 5018 faa2 8ce4 0000 7300 0000 0000 P.......s..... 593 | 21:45:32.136360 IP (tos 0xc0, ttl 254, id 3101, offset 0, flags [none], proto TCP (6), length 41) 594 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0x77a4 (correct), seq 79:80, ack 63, win 4066, length 1 595 | 0x0000: 45c0 0029 0c1d 0000 fe06 ae2f c0a8 c065 E..)......./...e 596 | 0x0010: c0a8 c00b 0017 944a 86e0 9c46 67be 943b .......J...Fg..; 597 | 0x0020: 5018 0fe2 77a4 0000 7300 80c0 a000 P...w...s..... 598 | 21:45:32.136720 IP (tos 0x10, ttl 64, id 6819, offset 0, flags [DF], proto TCP (6), length 40) 599 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0xffec (correct), ack 80, win 64161, length 0 600 | 0x0000: 4510 0028 1aa3 4000 4006 1e5b c0a8 c00b E..(..@.@..[.... 601 | 0x0010: c0a8 c065 944a 0017 67be 943b 86e0 9c47 ...e.J..g..;...G 602 | 0x0020: 5010 faa1 ffec 0000 0000 0000 0000 P............. 603 | 21:45:32.729758 IP (tos 0x10, ttl 64, id 6820, offset 0, flags [DF], proto TCP (6), length 41) 604 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x9ee3 (correct), seq 63:64, ack 80, win 64161, length 1 605 | 0x0000: 4510 0029 1aa4 4000 4006 1e59 c0a8 c00b E..)..@.@..Y.... 606 | 0x0010: c0a8 c065 944a 0017 67be 943b 86e0 9c47 ...e.J..g..;...G 607 | 0x0020: 5018 faa1 9ee3 0000 6100 0000 0000 P.......a..... 608 | 21:45:32.731192 IP (tos 0xc0, ttl 254, id 3102, offset 0, flags [none], proto TCP (6), length 41) 609 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0x89a3 (correct), seq 80:81, ack 64, win 4065, length 1 610 | 0x0000: 45c0 0029 0c1e 0000 fe06 ae2e c0a8 c065 E..)...........e 611 | 0x0010: c0a8 c00b 0017 944a 86e0 9c47 67be 943c .......J...Gg..< 612 | 0x0020: 5018 0fe1 89a3 0000 6100 80c0 a000 P.......a..... 613 | 21:45:32.731575 IP (tos 0x10, ttl 64, id 6821, offset 0, flags [DF], proto TCP (6), length 40) 614 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0xffeb (correct), ack 81, win 64160, length 0 615 | 0x0000: 4510 0028 1aa5 4000 4006 1e59 c0a8 c00b E..(..@.@..Y.... 616 | 0x0010: c0a8 c065 944a 0017 67be 943c 86e0 9c48 ...e.J..g..<...H 617 | 0x0020: 5010 faa0 ffeb 0000 0000 0000 0000 P............. 618 | 21:45:32.842825 IP (tos 0x10, ttl 64, id 6822, offset 0, flags [DF], proto TCP (6), length 41) 619 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x9be2 (correct), seq 64:65, ack 81, win 64160, length 1 620 | 0x0000: 4510 0029 1aa6 4000 4006 1e57 c0a8 c00b E..)..@.@..W.... 621 | 0x0010: c0a8 c065 944a 0017 67be 943c 86e0 9c48 ...e.J..g..<...H 622 | 0x0020: 5018 faa0 9be2 0000 6400 0000 0000 P.......d..... 623 | 21:45:32.844133 IP (tos 0xc0, ttl 254, id 3103, offset 0, flags [none], proto TCP (6), length 41) 624 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0x86a2 (correct), seq 81:82, ack 65, win 4064, length 1 625 | 0x0000: 45c0 0029 0c1f 0000 fe06 ae2d c0a8 c065 E..).......-...e 626 | 0x0010: c0a8 c00b 0017 944a 86e0 9c48 67be 943d .......J...Hg..= 627 | 0x0020: 5018 0fe0 86a2 0000 6400 80c0 a000 P.......d..... 628 | 21:45:32.844516 IP (tos 0x10, ttl 64, id 6823, offset 0, flags [DF], proto TCP (6), length 40) 629 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0xffea (correct), ack 82, win 64159, length 0 630 | 0x0000: 4510 0028 1aa7 4000 4006 1e57 c0a8 c00b E..(..@.@..W.... 631 | 0x0010: c0a8 c065 944a 0017 67be 943d 86e0 9c49 ...e.J..g..=...I 632 | 0x0020: 5010 fa9f ffea 0000 0000 0000 0000 P............. 633 | 21:45:32.907367 IP (tos 0x10, ttl 64, id 6824, offset 0, flags [DF], proto TCP (6), length 41) 634 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x92e1 (correct), seq 65:66, ack 82, win 64159, length 1 635 | 0x0000: 4510 0029 1aa8 4000 4006 1e55 c0a8 c00b E..)..@.@..U.... 636 | 0x0010: c0a8 c065 944a 0017 67be 943d 86e0 9c49 ...e.J..g..=...I 637 | 0x0020: 5018 fa9f 92e1 0000 6d00 0000 0000 P.......m..... 638 | 21:45:32.908601 IP (tos 0xc0, ttl 254, id 3104, offset 0, flags [none], proto TCP (6), length 41) 639 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0x7da1 (correct), seq 82:83, ack 66, win 4063, length 1 640 | 0x0000: 45c0 0029 0c20 0000 fe06 ae2c c0a8 c065 E..).......,...e 641 | 0x0010: c0a8 c00b 0017 944a 86e0 9c49 67be 943e .......J...Ig..> 642 | 0x0020: 5018 0fdf 7da1 0000 6d00 80c0 a000 P...}...m..... 643 | 21:45:32.908939 IP (tos 0x10, ttl 64, id 6825, offset 0, flags [DF], proto TCP (6), length 40) 644 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0xffe9 (correct), ack 83, win 64158, length 0 645 | 0x0000: 4510 0028 1aa9 4000 4006 1e55 c0a8 c00b E..(..@.@..U.... 646 | 0x0010: c0a8 c065 944a 0017 67be 943e 86e0 9c4a ...e.J..g..>...J 647 | 0x0020: 5010 fa9e ffe9 0000 0000 0000 0000 P............. 648 | 21:45:33.048498 IP (tos 0x10, ttl 64, id 6826, offset 0, flags [DF], proto TCP (6), length 41) 649 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x96e0 (correct), seq 66:67, ack 83, win 64158, length 1 650 | 0x0000: 4510 0029 1aaa 4000 4006 1e53 c0a8 c00b E..)..@.@..S.... 651 | 0x0010: c0a8 c065 944a 0017 67be 943e 86e0 9c4a ...e.J..g..>...J 652 | 0x0020: 5018 fa9e 96e0 0000 6900 0000 0000 P.......i..... 653 | 21:45:33.050415 IP (tos 0xc0, ttl 254, id 3105, offset 0, flags [none], proto TCP (6), length 41) 654 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0x81a0 (correct), seq 83:84, ack 67, win 4062, length 1 655 | 0x0000: 45c0 0029 0c21 0000 fe06 ae2b c0a8 c065 E..).!.....+...e 656 | 0x0010: c0a8 c00b 0017 944a 86e0 9c4a 67be 943f .......J...Jg..? 657 | 0x0020: 5018 0fde 81a0 0000 6900 80c0 a000 P.......i..... 658 | 21:45:33.050794 IP (tos 0x10, ttl 64, id 6827, offset 0, flags [DF], proto TCP (6), length 40) 659 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0xffe8 (correct), ack 84, win 64157, length 0 660 | 0x0000: 4510 0028 1aab 4000 4006 1e53 c0a8 c00b E..(..@.@..S.... 661 | 0x0010: c0a8 c065 944a 0017 67be 943f 86e0 9c4b ...e.J..g..?...K 662 | 0x0020: 5010 fa9d ffe8 0000 0000 0000 0000 P............. 663 | 21:45:33.149953 IP (tos 0x10, ttl 64, id 6828, offset 0, flags [DF], proto TCP (6), length 41) 664 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x91df (correct), seq 67:68, ack 84, win 64157, length 1 665 | 0x0000: 4510 0029 1aac 4000 4006 1e51 c0a8 c00b E..)..@.@..Q.... 666 | 0x0010: c0a8 c065 944a 0017 67be 943f 86e0 9c4b ...e.J..g..?...K 667 | 0x0020: 5018 fa9d 91df 0000 6e00 0000 0000 P.......n..... 668 | 21:45:33.151499 IP (tos 0xc0, ttl 254, id 3106, offset 0, flags [none], proto TCP (6), length 41) 669 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0x7c9f (correct), seq 84:85, ack 68, win 4061, length 1 670 | 0x0000: 45c0 0029 0c22 0000 fe06 ae2a c0a8 c065 E..).".....*...e 671 | 0x0010: c0a8 c00b 0017 944a 86e0 9c4b 67be 9440 .......J...Kg..@ 672 | 0x0020: 5018 0fdd 7c9f 0000 6e00 80c0 a000 P...|...n..... 673 | 21:45:33.151885 IP (tos 0x10, ttl 64, id 6829, offset 0, flags [DF], proto TCP (6), length 40) 674 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0xffe7 (correct), ack 85, win 64156, length 0 675 | 0x0000: 4510 0028 1aad 4000 4006 1e51 c0a8 c00b E..(..@.@..Q.... 676 | 0x0010: c0a8 c065 944a 0017 67be 9440 86e0 9c4c ...e.J..g..@...L 677 | 0x0020: 5010 fa9c ffe7 0000 0000 0000 0000 P............. 678 | 21:45:33.867814 IP (tos 0x10, ttl 64, id 6830, offset 0, flags [DF], proto TCP (6), length 42) 679 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0xf2dd (correct), seq 68:70, ack 85, win 64156, length 2 680 | 0x0000: 4510 002a 1aae 4000 4006 1e4e c0a8 c00b E..*..@.@..N.... 681 | 0x0010: c0a8 c065 944a 0017 67be 9440 86e0 9c4c ...e.J..g..@...L 682 | 0x0020: 5018 fa9c f2dd 0000 0d00 0000 0000 P............. 683 | 684 | ### Username sent. Switch requests password 685 | 686 | 21:45:33.872030 IP (tos 0xc0, ttl 254, id 3107, offset 0, flags [none], proto TCP (6), length 52) 687 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0xf5c0 (correct), seq 85:97, ack 70, win 4059, length 12 688 | 0x0000: 45c0 0034 0c23 0000 fe06 ae1e c0a8 c065 E..4.#.........e 689 | 0x0010: c0a8 c00b 0017 944a 86e0 9c4c 67be 9442 .......J...Lg..B 690 | 0x0020: 5018 0fdb f5c0 0000 0d0a 5061 7373 776f P.........Passwo 691 | 0x0030: 7264 3a20 rd:. 692 | 21:45:33.872420 IP (tos 0x10, ttl 64, id 6831, offset 0, flags [DF], proto TCP (6), length 40) 693 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0xffe5 (correct), ack 97, win 64144, length 0 694 | 0x0000: 4510 0028 1aaf 4000 4006 1e4f c0a8 c00b E..(..@.@..O.... 695 | 0x0010: c0a8 c065 944a 0017 67be 9442 86e0 9c58 ...e.J..g..B...X 696 | 0x0020: 5010 fa90 ffe5 0000 0000 0000 0000 P............. 697 | 698 | 699 | ### Begin typing the password which is "password" 700 | 701 | ### Send "p" 702 | 21:45:36.667308 IP (tos 0x10, ttl 64, id 6832, offset 0, flags [DF], proto TCP (6), length 41) 703 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x8fdc (correct), seq 70:71, ack 97, win 64144, length 1 704 | 0x0000: 4510 0029 1ab0 4000 4006 1e4d c0a8 c00b E..)..@.@..M.... 705 | 0x0010: c0a8 c065 944a 0017 67be 9442 86e0 9c58 ...e.J..g..B...X 706 | 0x0020: 5018 fa90 8fdc 0000 7000 0000 0000 P.......p..... 707 | 21:45:36.868429 IP (tos 0xc0, ttl 254, id 3108, offset 0, flags [none], proto TCP (6), length 40) 708 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [.], cksum 0xea9b (correct), ack 71, win 4058, length 0 709 | 0x0000: 45c0 0028 0c24 0000 fe06 ae29 c0a8 c065 E..(.$.....)...e 710 | 0x0010: c0a8 c00b 0017 944a 86e0 9c58 67be 9443 .......J...Xg..C 711 | 0x0020: 5010 0fda ea9b 0000 0000 80c0 0000 P............. 712 | 713 | ### Send "a" 714 | 21:45:36.868789 IP (tos 0x10, ttl 64, id 6833, offset 0, flags [DF], proto TCP (6), length 41) 715 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x9edb (correct), seq 71:72, ack 97, win 64144, length 1 716 | 0x0000: 4510 0029 1ab1 4000 4006 1e4c c0a8 c00b E..)..@.@..L.... 717 | 0x0010: c0a8 c065 944a 0017 67be 9443 86e0 9c58 ...e.J..g..C...X 718 | 0x0020: 5018 fa90 9edb 0000 6100 0000 0000 P.......a..... 719 | 21:45:37.070726 IP (tos 0xc0, ttl 254, id 3109, offset 0, flags [none], proto TCP (6), length 40) 720 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [.], cksum 0xea9b (correct), ack 72, win 4057, length 0 721 | 0x0000: 45c0 0028 0c25 0000 fe06 ae28 c0a8 c065 E..(.%.....(...e 722 | 0x0010: c0a8 c00b 0017 944a 86e0 9c58 67be 9444 .......J...Xg..D 723 | 0x0020: 5010 0fd9 ea9b 0000 0000 80c0 0000 P............. 724 | 725 | ### Send the rest of the password 726 | 21:45:37.071089 IP (tos 0x10, ttl 64, id 6834, offset 0, flags [DF], proto TCP (6), length 41) 727 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x8cda (correct), seq 72:73, ack 97, win 64144, length 1 728 | 0x0000: 4510 0029 1ab2 4000 4006 1e4b c0a8 c00b E..)..@.@..K.... 729 | 0x0010: c0a8 c065 944a 0017 67be 9444 86e0 9c58 ...e.J..g..D...X 730 | 0x0020: 5018 fa90 8cda 0000 7300 0000 0000 P.......s..... 731 | 21:45:37.272820 IP (tos 0xc0, ttl 254, id 3110, offset 0, flags [none], proto TCP (6), length 40) 732 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [.], cksum 0xea9b (correct), ack 73, win 4056, length 0 733 | 0x0000: 45c0 0028 0c26 0000 fe06 ae27 c0a8 c065 E..(.&.....'...e 734 | 0x0010: c0a8 c00b 0017 944a 86e0 9c58 67be 9445 .......J...Xg..E 735 | 0x0020: 5010 0fd8 ea9b 0000 0000 80c0 0000 P............. 736 | 21:45:37.273166 IP (tos 0x10, ttl 64, id 6835, offset 0, flags [DF], proto TCP (6), length 41) 737 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x8cd9 (correct), seq 73:74, ack 97, win 64144, length 1 738 | 0x0000: 4510 0029 1ab3 4000 4006 1e4a c0a8 c00b E..)..@.@..J.... 739 | 0x0010: c0a8 c065 944a 0017 67be 9445 86e0 9c58 ...e.J..g..E...X 740 | 0x0020: 5018 fa90 8cd9 0000 7300 0000 0000 P.......s..... 741 | 21:45:37.474825 IP (tos 0xc0, ttl 254, id 3111, offset 0, flags [none], proto TCP (6), length 40) 742 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [.], cksum 0xea9b (correct), ack 74, win 4055, length 0 743 | 0x0000: 45c0 0028 0c27 0000 fe06 ae26 c0a8 c065 E..(.'.....&...e 744 | 0x0010: c0a8 c00b 0017 944a 86e0 9c58 67be 9446 .......J...Xg..F 745 | 0x0020: 5010 0fd7 ea9b 0000 0000 80c0 0000 P............. 746 | 21:45:37.475156 IP (tos 0x10, ttl 64, id 6836, offset 0, flags [DF], proto TCP (6), length 41) 747 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x88d8 (correct), seq 74:75, ack 97, win 64144, length 1 748 | 0x0000: 4510 0029 1ab4 4000 4006 1e49 c0a8 c00b E..)..@.@..I.... 749 | 0x0010: c0a8 c065 944a 0017 67be 9446 86e0 9c58 ...e.J..g..F...X 750 | 0x0020: 5018 fa90 88d8 0000 7700 0000 0000 P.......w..... 751 | 21:45:37.676871 IP (tos 0xc0, ttl 254, id 3112, offset 0, flags [none], proto TCP (6), length 40) 752 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [.], cksum 0xea9b (correct), ack 75, win 4054, length 0 753 | 0x0000: 45c0 0028 0c28 0000 fe06 ae25 c0a8 c065 E..(.(.....%...e 754 | 0x0010: c0a8 c00b 0017 944a 86e0 9c58 67be 9447 .......J...Xg..G 755 | 0x0020: 5010 0fd6 ea9b 0000 0000 80c0 0000 P............. 756 | 21:45:37.677223 IP (tos 0x10, ttl 64, id 6837, offset 0, flags [DF], proto TCP (6), length 43) 757 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0x2c63 (correct), seq 75:78, ack 97, win 64144, length 3 758 | 0x0000: 4510 002b 1ab5 4000 4006 1e46 c0a8 c00b E..+..@.@..F.... 759 | 0x0010: c0a8 c065 944a 0017 67be 9447 86e0 9c58 ...e.J..g..G...X 760 | 0x0020: 5018 fa90 2c63 0000 6f72 6400 0000 P...,c..ord... 761 | 21:45:37.878672 IP (tos 0xc0, ttl 254, id 3113, offset 0, flags [none], proto TCP (6), length 40) 762 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [.], cksum 0xea9b (correct), ack 78, win 4051, length 0 763 | 0x0000: 45c0 0028 0c29 0000 fe06 ae24 c0a8 c065 E..(.).....$...e 764 | 0x0010: c0a8 c00b 0017 944a 86e0 9c58 67be 944a .......J...Xg..J 765 | 0x0020: 5010 0fd3 ea9b 0000 0000 80c0 0000 P............. 766 | 21:45:39.058780 IP (tos 0x10, ttl 64, id 6838, offset 0, flags [DF], proto TCP (6), length 42) 767 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [P.], cksum 0xf2d3 (correct), seq 78:80, ack 97, win 64144, length 2 768 | 0x0000: 4510 002a 1ab6 4000 4006 1e46 c0a8 c00b E..*..@.@..F.... 769 | 0x0010: c0a8 c065 944a 0017 67be 944a 86e0 9c58 ...e.J..g..J...X 770 | 0x0020: 5018 fa90 f2d3 0000 0d00 0000 0000 P............. 771 | 772 | ### Password submitted 773 | 774 | ### Switch sends prompt 775 | 776 | 21:45:39.080470 IP (tos 0xc0, ttl 254, id 3114, offset 0, flags [none], proto TCP (6), length 55) 777 | 192.168.192.101.telnet > 192.168.192.11.37962: Flags [P.], cksum 0x9e8d (correct), seq 97:112, ack 80, win 4049, length 15 778 | 0x0000: 45c0 0037 0c2a 0000 fe06 ae14 c0a8 c065 E..7.*.........e 779 | 0x0010: c0a8 c00b 0017 944a 86e0 9c58 67be 944c .......J...Xg..L 780 | 0x0020: 5018 0fd1 9e8d 0000 0d0a 0d0a 6c61 622d P...........lab- 781 | 0x0030: 7377 6974 6368 23 switch# 782 | 21:45:39.080904 IP (tos 0x10, ttl 64, id 6839, offset 0, flags [DF], proto TCP (6), length 40) 783 | 192.168.192.11.37962 > 192.168.192.101.telnet: Flags [.], cksum 0xffdb (correct), ack 112, win 64129, length 0 784 | 0x0000: 4510 0028 1ab7 4000 4006 1e47 c0a8 c00b E..(..@.@..G.... 785 | 0x0010: c0a8 c065 944a 0017 67be 944c 86e0 9c67 ...e.J..g..L...g 786 | 0x0020: 5010 fa81 ffdb 0000 0000 0000 0000 P............. 787 | ``` 788 | 789 |
790 | 791 | ## Capture Example 3: Creating a PCAP file 792 | Displaying packets as you capture them onscreen is great. But often in troubleshooting you can't analyze them onscreen while they come in. It is just too much data. Rather you capture packets to a file to be processed later. Maybe using a GUI tool like Wireshark installed on your primary workstation. 793 | 794 | In this example, we will once again capture the telnet traffic, but rather than display onscreen, we will create a capture file. 795 | 796 | ```bash 797 | sudo tcpdump -i eth0 -v -w telnet-capture.cap port 23 798 | ``` 799 | 800 | > `-w telnet-capture.cap` will "write" the capture to a file. 801 | > 802 | > `-v` for a "write" capture will display the packet count to the screen. 803 | 804 | ***Output*** 805 | 806 | ``` 807 | tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes 808 | 76 packets captured 809 | ^C 810 | 76 packets received by filter 811 | 0 packets dropped by kernel 812 | 813 | ls -l 814 | total 8 815 | -rw-r--r-- 1 tcpdump tcpdump 5909 Mar 3 22:06 telnet-capture.cap 816 | ``` 817 | 818 | With the file captured, you could "read" it in for processing with `tcpdump -r telnet-capture.cap` 819 | 820 | ***Partial Output*** 821 | 822 | ``` 823 | reading from file telnet-capture.cap, link-type EN10MB (Ethernet), snapshot length 262144 824 | 22:06:33.957161 IP 192.168.192.11.37964 > 192.168.192.101.telnet: Flags [S], seq 2106082144, win 64240, options [mss 1460,sackOK,TS val 1751793461 ecr 0,nop,wscale 7], length 0 825 | 22:06:33.959364 IP 192.168.192.101.telnet > 192.168.192.11.37964: Flags [S.], seq 1143027395, ack 2106082145, win 4128, options [mss 1460], length 0 826 | 22:06:33.959801 IP 192.168.192.11.37964 > 192.168.192.101.telnet: Flags [.], ack 1, win 64240, length 0 827 | 22:06:33.960492 IP 192.168.192.11.37964 > 192.168.192.101.telnet: Flags [P.], seq 1:25, ack 1, win 64240, length 24 [telnet DO SUPPRESS GO AHEAD, WILL TERMINAL TYPE, WILL NAWS, WILL TSPEED, WILL LFLOW, WILL LINEMODE, WILL NEW-ENVIRON, DO STATUS] 828 | 22:06:33.962086 IP 192.168.192.101.telnet > 192.168.192.11.37964: Flags [.], ack 25, win 4104, length 0 829 | 22:06:33.962375 IP 192.168.192.101.telnet > 192.168.192.11.37964: Flags [P.], seq 1:13, ack 25, win 4104, length 12 [telnet WILL ECHO, WILL SUPPRESS GO AHEAD, DO TERMINAL TYPE, DO NAWS] 830 | 22:06:33.962691 IP 192.168.192.11.37964 > 192.168.192.101.telnet: Flags [.], ack 13, win 64228, length 0 831 | . 832 | . 833 | . 834 | ``` 835 | 836 | But far more common is copying the file to another workstation for analysis. 837 | 838 | # Final Thoughts 839 | There you go, you are ready to explore packet capture and traffic analysis in your lab using your Raspberry Pi as a network sensor. From here there is so much you can dive into next. 840 | 841 | * Explore all the different filters you can create 842 | * Look at the packets for protocols like CDP or Spanning-tree 843 | * Watch routing protocols exchange updates 844 | * Explore Wifi packet capture for wireless 845 | 846 | ## What about Wireshark? 847 | 848 | Wireshark is another very popular packet capture tool that can be installed and used on your Raspberry Pi. You can do so with `sudo apt-get install wireshark`. 849 | 850 | I am a big fan of Wireshark, but it is a bit "heavy" for running on a small Raspberry Pi. When I checked the installation needs on my device I got this: 851 | 852 | ``` 853 | 0 upgraded, 154 newly installed, 0 to remove and 0 not upgraded. 854 | Need to get 97.0 MB of archives. 855 | After this operation, 424 MB of additional disk space will be used. 856 | ``` 857 | 858 | My approach to Wireshark in the lab is to install it on my laptop/workstation and use `tcpdump` on the Raspberry Pi to create capture files. I then copy the files to my workstation an analyze with Wireshark there. --------------------------------------------------------------------------------