0% found this document useful (0 votes)
10 views174 pages

Network Programmability and Automation Fundamentals

The document is a publication titled 'Network Programmability and Automation Fundamentals' by authors Khaled Abuelenain, Jeff Doyle, Anton Karneliuk, and Vinit Jain, focusing on network programmability and automation. It includes copyright information, disclaimers, and acknowledgments, emphasizing the importance of feedback from readers. The authors are experienced professionals in networking, with various certifications and contributions to the field.

Uploaded by

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

Network Programmability and Automation Fundamentals

The document is a publication titled 'Network Programmability and Automation Fundamentals' by authors Khaled Abuelenain, Jeff Doyle, Anton Karneliuk, and Vinit Jain, focusing on network programmability and automation. It includes copyright information, disclaimers, and acknowledgments, emphasizing the importance of feedback from readers. The authors are experienced professionals in networking, with various certifications and contributions to the field.

Uploaded by

Ajeet Nagdev
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Network Programmability

and Automation
Fundamentals
Khaled Abuelenain, CCIE No. 27401
Jeff Doyle, CCIE No. 1919
Anton Karneliuk, CCIE No. 49412
Vinit Jain, CCIE No. 22854

Cisco Press
Hoboken, New Jersey

9781587145148_print.indb 1 25/03/21 11:42 am


ii Network Programmability and Automation Fundamentals

Network Programmability and Automation


Fundamentals
Copyright© 2021 Cisco Systems, Inc.

Cisco Press logo is a trademark of Cisco Systems, Inc.

Published by:
Cisco Press

All rights reserved. This publication is protected by copyright, and permission must be obtained from the
publisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any form
or by any means, electronic, mechanical, photocopying, recording, or likewise. For information regarding
permissions, request forms, and the appropriate contacts within the Pearson Education Global Rights &
Permissions Department, please visit www.pearson.com/permissions.

No patent liability is assumed with respect to the use of the information contained herein. Although
every precaution has been taken in the preparation of this book, the publisher and author assume no
responsibility for errors or omissions. Nor is any liability assumed for damages resulting from the use of
the information contained herein.

ScoutAutomatedPrintCode

Library of Congress Control Number: 2020922839

ISBN-13: 978-1-58714-514-8
ISBN-10: 1-58714-514-6

Warning and Disclaimer


This book is designed to provide information about network programmability and automation. Every
effort has been made to make this book as complete and as accurate as possible, but no warranty or
fitness is implied.

The information is provided on an “as is” basis. The authors, Cisco Press, and Cisco Systems, Inc. shall
have neither liability nor responsibility to any person or entity with respect to any loss or damages arising
from the information contained in this book or from the use of the discs or programs that may accom-
pany it.

The opinions expressed in this book belong to the author and are not necessarily those of
Cisco Systems, Inc.

Trademark Acknowledgments
All terms mentioned in this book that are known to be trademarks or service marks have been appropri-
ately capitalized. Cisco Press or Cisco Systems, Inc. cannot attest to the accuracy of this information. Use
of a term in this book should not be regarded as affecting the validity of any trademark or service mark.

9781587145148_print.indb 2 25/03/21 11:42 am


iii

Feedback Information
At Cisco Press, our goal is to create in-depth technical books of the highest quality and value. Each book
is crafted with care and precision, undergoing rigorous development that involves the unique expertise of
members from the professional technical community.

Readers’ feedback is a natural continuation of this process. If you have any comments regarding how we
could improve the quality of this book or otherwise alter it to better suit your needs, you can contact us
through email at [email protected]. Please make sure to include the book title and ISBN in your
message.

We greatly appreciate your assistance.

Editor-in-Chief: Mark Taub Technical Editors: Jeff Tantsura, Viktor Osipchuk

Director, ITP Product Management: Brett Bartow Editorial Assistant: Cindy Teeters

Alliances Manager, Cisco Press: Arezou Gol Designer: Chuti Prasertsith

Managing Editor: Sandra Schroeder Composition: codeMantra

Development Editor: Ellie C. Bru Indexer: Ken Johnson

Project Editor: Mandie Frank Proofreader: Abigail Bass

Copy Editor: Kitty Wilson

Americas Headquarters Asia Pacific Headquarters Europe Headquarters


Cisco Systems, Inc. Cisco Systems (USA) Pte. Ltd. Cisco Systems International BV Amsterdam,
San Jose, CA Singapore The Netherlands

Cisco has more than 200 offices worldwide. Addresses, phone numbers, and fax numbers are listed on the Cisco Website at www.cisco.com/go/offices.

Cisco and the Cisco logo are trademarks or registered trademarks of Cisco and/or its affiliates in the U.S. and other countries. To view a list of Cisco trademarks,
go to this URL: www.cisco.com/go/trademarks. Third party trademarks mentioned are the property of their respective owners. The use of the word partner does
not imply a partnership relationship between Cisco and any other company. (1110R)

9781587145148_print.indb 3 25/03/21 11:42 am


iv Network Programmability and Automation Fundamentals

Credits

Figure/Text Selection Attribution/Credit


“HTTP is not designed to be a transport protocol. It is a © Roy Thomas Fielding, 2000
transfer protocol in which the messages reflect the
semantics of the Web architecture by performing actions
on resources through the transfer and manipulation of
representations of those resources [Section 6.5.2]”
“This specification [HTTP/2.0] is an alternative to, but Hypertext Transfer Protocol
does not obsolete, the HTTP/1.1 message syntax. Version 2
HTTP’s existing semantics remain unchanged.”
“a sequence of octets, along with representation metadata Uniform Resource Identifier
describing those octets that constitutes a record of the (URI): Generic Syntax,
state of the resource at the time when the representation Copyright © The Internet
is generated.” Society (2005)
“While RFC 2396, section 1.2, attempts to address the IETF (Internet Engineering Task
distinction between URIs, URLs and URNs, it has not Force). Architectural Principles
been successful in clearing up the confusion.” of Uniform Resource Name
Resolution, ed. K. Sollins. 1998
1. Device state metrics; Shamus McGillicudy,
“A Network Source of Truth
2. Data from shared services such as DDI (DNS, DHCP
Promotes Trust in Network
and IPAM) and Active Directory;
Automation,” Enterprise
3. Network flows from sources such as NetFlow; and management Associates,
May 2020
4. Configuration data normalized into key value pairs.
“Deliver working software frequently, from a couple of ©2020 Agile Alliance
weeks to a couple of months, with a preference to the
shorter timescale”.
“allows client/server applications to communicate over Copyright (c) 2020 IETF
the Internet in a way that is designed to prevent
eavesdropping, tampering, and message forgery.”
“the most important security protocol on the internet” Copyright (c) 2020 IETF
“there was more TLS 1.3 use in the first five months after Copyright (c) 2020 IETF
RFC 8446 was published than in the first five years after
the last version of TLS was published as an RFC”

9781587145148_print.indb 4 25/03/21 11:42 am


Credits v

Figure 1-6 CI/CD ©2021 Red Hat, Inc. www.redhat.com


Figure 6-2 Accessing a Django Application © 2005-2021 Django Software
in a Web Browser Foundation
Figure 7-1 The SupportApache-small.png Image, Copyright © 2020 The Apache
as It Appears in a Web Browser Software Foundation
Figure 7-6 The Postman Interface ©2020 Postman, Inc.
Figure 7-7 A GET Request Using Postman ©2020 Postman, Inc.
Figure 7-8 Viewing the Response Headers in ©2020 Postman, Inc.
Postman
Figure 13-1 GitHub Website with YANG © 2020 GitHub, Inc.
Modules
Figure 17-3 Comparing the Body of the Response Screenshot of Comparing the
in the Developer Sandbox and body of the response in the
Postman Developer Sandbox and Postman
©2020 Postman, Inc.
Figure 18-3 Converting a username:password Screenshot of Converting
Tuple to Base64 Format username:password tuple to
Base64 format © Cisco systems
Figure 18-4 Arista YANG Modules Screenshot of Arista YANG modules
© 2020 GitHub, Inc.
Figure 19-3 Available Ansible Module Categories Copyright © 2020 Red Hat, Inc.

9781587145148_print.indb 5 25/03/21 11:42 am


vi Network Programmability and Automation Fundamentals

About the Authors


Khaled Abuelenain, CCIE No. 27401 (R&S, SP), is currently the Consulting Director at
Acuative, a Cisco Managed Services Master Partner. Khaled has spent the past 18 years
designing, implementing, operating, and automating networks and clouds. He specializes
in service provider technologies, SD-WAN, data center technologies, programmabil-
ity, automation, and cloud architectures. Khaled is especially interested in Linux and
OpenStack.

Khaled is a contributing author of the best-selling Cisco Press book Routing TCP/IP,
Volume II, 2nd edition, by Jeff Doyle. He also blogs frequently on network program-
mability and automation on blogs.cisco.com. Khaled is also a member of the DevNet500
group, being one of the first 500 individuals in the world to become DevNet certified.

Khaled lives in Riyadh, Saudi Arabia, and when not working or writing, he likes to run
marathons and skydive. He can be reached at [email protected], on Twitter at
@kabuelenain or on LinkedIn at linkedin.com/in/kabuelenain.

Jeff Doyle, CCIE No. 1919, is a Member of Technical Staff at Apstra. Specializing in
IP routing protocols, complex BGP policy, SDN/NFV, data center fabrics, IBN, EVPN,
MPLS, and IPv6, Jeff has designed or assisted in the design of large-scale IP and IPv6
service provider networks in 26 countries over 6 continents.

Jeff is the author of CCIE Professional Development: Routing TCP/IP, Volumes I and
II and OSPF and IS-IS: Choosing an IGP for Large-Scale Networks; a co-author of
Software-Defined Networking: Anatomy of OpenFlow; and an editor and contributing
author of Juniper Networks Routers: The Complete Reference. Jeff is currently writ-
ing CCIE Professional Development: Switching TCP/IP. He also writes for Forbes and
blogs for both Network World and Network Computing. Jeff is one of the founders of
the Rocky Mountain IPv6 Task Force, is an IPv6 Forum Fellow, and serves on the execu-
tive board of the Colorado chapter of the Internet Society (ISOC).

Anton Karneliuk, CCIE No. 49412 (R&S, SP), is a Network Engineer and Manager at
THG Hosting, responsible for the development, operation, and automation of networks
in numerous data centers across the globe and the international backbone. Prior to join-
ing THG, Anton was a team lead in Vodafone Group Network Engineering and Delivery,
focusing on introduction of SDN and NFV projects in Germany. Anton has 15 years of
extensive experience in design, rollout, operation, and optimization of large-scale service
providers and converged networks, focusing on IP/MPLS, BGP, network security, and
data center Clos fabrics built using EVPN/VXLAN. He also has several years of full-stack
software development experience for network management and automation.

Anton holds a B.S. in telecommunications and an M.S. in information security from


Belarusian State University of Informatics and Radio Electronics. You can find him
actively blogging about network automation and running online training at Karneliuk.
com. Anton lives with his wife in London.

9781587145148_print.indb 6 25/03/21 11:42 am


About the Authors vii

Vinit Jain, CCIE No. 22854 (R&S, SP, Security & DC), is a Network Development
Engineer at Amazon, managing the Amazon network backbone operations team.
Previously, he worked as a technical leader with the Cisco Technical Assistance Center
(TAC), providing escalation support in routing and data center technologies. Vinit is a
speaker at various networking forums, including Cisco Live! events. He has co-authored
several Cisco Press titles, such as Troubleshooting BGP, and Troubleshooting Cisco
Nexus Switches and NX-OS, LISP Network Deployment and Troubleshooting, and
has authored and co-authored several video courses, including BGP Troubleshooting,
the CCNP DCCOR Complete video course, and the CCNP ENCOR Complete video
course. In addition to his CCIEs, Vinit holds multiple certifications related to program-
ming and databases. Vinit graduated from Delhi University in mathematics and earned a
master’s in information technology from Kuvempu University in India. Vinit can be found
on Twitter as @VinuGenie.

9781587145148_print.indb 7 25/03/21 11:42 am


viii Network Programmability and Automation Fundamentals

About the Technical Reviewers


Jeff Tantsura, CCIE No. 11416 (R&S), has been in the networking space for over 25
years and has authored and contributed to many RFCs and patents and worked in both
service provider and vendor environments.

He is co-chair of IETF Routing Working Group, chartered to work on new network


architectures and technologies, including protocol-independent YANG models and next-
generation routing protocols. He is also the co-chair of the RIFT (Routing in Fat Trees)
Working Group, chartered to work on a new routing protocol that specifically addresses
fat tree topologies typically seen in the data center environment.

Jeff serves on the Internet Architecture Board (IAB). His focus has been on 5G transport
and integration with RAN, IoT, MEC, low-latency networking, and data modeling. He’s
also a board member of San Francisco Bay Area ISOC chapter.

Jeff is Head of Networking Strategy at Apstra, a leader in intent networking, where he


defines networking strategy and technologies.

Jeff also holds the certification Ericsson Certified Expert IP Networking.

Jeff lives in Palo Alto, California, with his wife and youngest child.

Viktor Osipchuk, CCIE No. 38256 (R&S, SP), is a Senior Network Engineer at Google,
focusing on automation and improving one of the largest production networks in the
world. Before joining Google, Viktor spent time at DigitalOcean and Equinix, helping to
architect and run their worldwide infrastructures. Viktor spent many years at Cisco,
supporting customers and focusing on automation, telemetry, data models, and APIs
for large-scale web and service provider deployments. Viktor has around 15 years of
diverse network experience, an M.S. in telecommunications, and associated industry
certifications.

9781587145148_print.indb 8 25/03/21 11:42 am


ix

Dedications
Khaled Abuelenain: To my mother, the dearest person to my heart, who invested all
the years of her life so I can be who I am today. I owe you more than any words can
express. To my father, my role model, who always led by example and showed me the
real meaning of work ethic. Nothing I do or say will ever be enough to thank you both.

And to the love of my life, my soulmate, and my better half, Mai, for letting me work
and write while you take care of, literally, everything else. This book would not have
happened if not for your phenomenal support, patience and love. I will forever be
grateful for the blessing of having you in my life.

Jeff Doyle: I would like to dedicate this book to my large and growing herd of grand-
children: Claire, Samuel, Caroline, Elsie, and Amelia. While they are far too young to
comprehend or care about the contents of this book, perhaps someday they will look at
it and appreciate that Grampa is more than a nice old man and itinerant babysitter.

Anton Karneliuk: I dedicate this book to my family, which has tremendously supported
me during the writing process. First of all, many thanks to my amazing wife, Julia, who
took on the huge burden of sorting out many things for our lives, allowing me to con-
centrate on the book. You acted as a navigation star during this journey, and you are my
beauty. I’d also like to thank my parents and brother for me helping me form the habit
of working hard and completing the tasks I’ve committed to, no matter how badly I want
to drop them.

Vinit Jain: I would like to dedicate this book to the woman who has been a great influ-
ence and inspiration in my life: Sonal Sethia (Sonpari). You are one of the most brilliant,
talented, courageous, and humble people I have ever known. You have always inspired
me to push myself beyond what I thought I was capable of. You have been there for me
during difficult times and believed in me when even I did not. You are my rock. This is
a small token of my appreciation, gratitude, and love for you. I am really glad to have
found my best friend in you and know that I will always be there for you.

9781587145148_print.indb 9 25/03/21 11:42 am


x Network Programmability and Automation Fundamentals

Acknowledgments
Khaled: First and foremost, I would like to thank Jeff Doyle, my co-author, mentor, and
friend, for getting me started with writing, and for his continuous assistance and guid-
ance. Jeff has played a fundamental role in my professional life as well as in the lives of
many other network engineers; he probably doesn’t realize the magnitude of this role!
Despite all that he has done for this industry and the network engineering community,
Jeff remains one of the most humble and amiable human beings I have ever come across.
Thank you, Jeff, I owe you a lot!
I am grateful to Anton and Vinit for agreeing to work with me on this project. It has been
challenging at times, but it has been seriously fun most of the time.
I would also like to thank Jeff Tantsura and Viktor Osipchuk for their thorough technical
reviews and feedback. I bothered Viktor very frequently with discussions and questions
over email, and never once did he fail to reply and add a ton of value!
I especially want to thank Brett Bartow and Eleanor Bru for their immense support and
phenomenal patience. And I’m grateful to Mandie Frank, Kitty Wilson, and everyone else
at Cisco Press who worked hard to get this book out to the light. Such an amazing team.
Jeff Doyle: I would like to express my thanks to my friend Khaled Abuelenain for bring-
ing me into this project, and thanks to Anton and Vinit for letting me be a part of their
excellent work. Thanks also to Brett Bartow and everyone at Pearson, whom I’ve worked
with for many years and continue to tell everyone who will listen that this is the best pub-
lishing team any technical writer could hope to work for. Finally, thanks to my wife Sara
who, as always, puts up with my obsessiveness. When she sees me sitting and staring into
nothingness she knows there’s writing going on in my head.
Anton: Special thanks to Schalk Van Der Merwe, CTO, and Andrew Mutty, CIO, at The
Hut Group for believing in me and giving me freedom and responsibility to implement
my automation ideas in a high-scale data center environment. Thanks to all my brothers-
in-arms from The Hut Group hosting networks for constantly sharing with me ideas
about what use cases to focus on for automation. I want to thank my previous manager
in Vodafone Group, Tamas Almasi, who supported me during my initial steps in network
automation and helped me create an appropriate mindset during numerous testbeds and
proofs of concept. Last but not least, I’m very grateful to Khaled Abuelenain for his invi-
tation to co-author this book and the whole author and technical reviewer team; it was a
pleasure to work with you.
Vinit: A special thanks to Khaled for asking me to co-author this book and for being amaz-
ingly patient and supportive of me as I faced challenges during this project. I would like
to thank Jeff Doyle and Anton Karneliuk for their amazing collaboration on this project. I
learned a lot from all of you guys and look forward to working with all of you in the future.
I would also like to thank our technical reviewers, Jeff Tantsura and Viktor Osipchuk, and
our editor, Eleanor Bru, for your in-depth verification of the content and insightful input
to make this project a successful one.
This project wouldn’t have been possible without the support of Brett Bartow and other
members of the editorial team.

A01_Abuelenain_FM_pi-pxxxvi.indd 10 27/03/21 6:49 pm


xi

Contents at a Glance
Introduction   xxix

Part I Introduction
Chapter 1 The Network Programmability and Automation Ecosystem 1

Part II Linux
Chapter 2 Linux Fundamentals 21

Chapter 3 Linux Storage, Security, and Networks 119

Chapter 4 Linux Scripting 183

Part III Python


Chapter 5 Python Fundamentals 249

Chapter 6 Python Applications 311

Part IV Transport
Chapter 7 HTTP and REST 387

Chapter 8 Advanced HTTP 469

Chapter 9 SSH 509

Part V Encoding
Chapter 10 XML 553

Chapter 11 JSON 591

Chapter 12 YAML 615

Part VI Modeling
Chapter 13 YANG 639

Part VII Protocols


Chapter 14 NETCONF and RESTCONF 689

Chapter 15 gRPC, Protobuf, and gNMI 781

Chapter 16 Service Provider Programmability 819

9781587145148_print.indb 11 25/03/21 11:42 am


xii Network Programmability and Automation Fundamentals

Part VIII Programmability Applications


Chapter 17 Programming Cisco Platforms 881

Chapter 18 Programming Non-Cisco Platforms 957

Chapter 19 Ansible 989

Part IX Looking Ahead


Chapter 20 Looking Ahead 1109

Index   1121

9781587145148_print.indb 12 25/03/21 11:42 am


xiii

Contents
Introduction   xxix

Part I Introduction

Chapter 1 The Network Programmability and Automation Ecosystem   1


First, a Few Definitions   2
Network Management   3
Automation   5
Orchestration   6
Programmability   7
Virtualization and Abstraction   8
Software-Defined Networking   13
Intent-Based Networking   13
Your Network Programmability and Automation Toolbox   14
Python   15
Ansible   15
Linux   16
Virtualization   17
YANG   17
Protocols   18
Encoding the Protocols   18
Transporting the Protocols   18
Software and Network Engineers: The New Era   19

Part II Linux

Chapter 2 Linux Fundamentals   21


The Story of Linux   21
History   21
Linux Today   22
Linux Development   22
Linux Architecture   23
Linux Distributions   26
The Linux Boot Process   26
A Linux Command Shell Primer   28
Finding Help in Linux   31

9781587145148_print.indb 13 25/03/21 11:42 am


xiv Network Programmability and Automation Fundamentals

Files and Directories in Linux   35


The Linux File System   35
File and Directory Operations   38
Navigating Directories   38
Viewing Files   41
File Operations   46
Directory Operations   48
Hard and Soft Links   51
Hard Links   51
Soft Links   55
Input and Output Redirection   57
Archiving Utilities   67
Linux System Maintenance   73
Job, Process, and Service Management   73
Resource Utilization   83
System Information   85
System Logs   91
Installing and Maintaining Software on Linux   94
Manual Compilation and Installation   96
RPM   97
YUM   101
DNF   117
Summary   118

Chapter 3 Linux Storage, Security, and Networks   119


Linux Storage   119
Physical Storage   119
Logical Volume Manager   128
Linux Security   135
User and Group Management   136
File Security Management   143
Access Control Lists   148
Linux System Security   155
Linux Networking   158
The ip Utility   159
The NetworkManager Service   168

9781587145148_print.indb 14 25/03/21 11:42 am


Contents xv

Network Scripts and Configuration Files   174


Network Services: DNS   179
Summary   181

Chapter 4 Linux Scripting   183


Regular Expressions and the grep Utility   184
The AWK Programming Language   193
The sed Utility   196
General Structure of Shell Scripts   203
Output and Input   207
Output   207
Input   211
Variables   215
Integers and Strings   216
Indexed and Associative Arrays   220
Conditional Statements   223
The if-then Construct   224
The case-in Construct   230
Loops   232
The for-do Loop   232
The while-do Loop   236
The until-do Loop   237
Functions   238
Expect   242
Summary   246

Part III Python

Chapter 5 Python Fundamentals   249


Scripting Languages Versus Programming Languages   250
Network Programmability   253
Computer Science Concepts   255
Object-Oriented Programming   256
Algorithms   258
Python Fundamentals   260
Python Installation   260
Python Code Execution   263
Python Data Types   270

9781587145148_print.indb 15 25/03/21 11:42 am


xvi Network Programmability and Automation Fundamentals

Variables   270
Numbers   273
Strings   276
Operators   281
Python Data Structures   286
List   286
Dictionaries   290
Tuples   292
Sets   294
Control Flow   295
if-else Statements   296
for Loops   301
while Loops   304
Functions   306
Summary   309
References 310

Chapter 6 Python Applications   311


Organizing the Development Environment   311
Git   312
Docker   317
The virtualenv Tool   331
Python Modules   333
Python Applications   336
Web/API Development   336
Django   337
Flask   345
Network Automation   353
NAPALM   354
Nornir   359
Templating with Jinja2   363
Orchestration   375
Docker   376
Kubernetes   378
Machine Learning   382
Summary   385

9781587145148_print.indb 16 25/03/21 11:42 am


Contents xvii

Part IV Transport

Chapter 7 HTTP and REST   387


HTTP Overview   387
The REST Framework   392
The HTTP Connection   394
Client/Server Communication   394
HTTP/1.1 Connection Enhancements   395
Persistent Connections   395
Pipelining   396
Compression   396
HTTP Transactions   397
Client Requests   397
GET   398
HEAD   398
POST   399
PUT   402
DELETE   405
CONNECT   407
OPTIONS   407
TRACE   408
Server Status Codes   408
1xx: Informational Status Codes   411
2xx: Successful Status Codes   411
3xx: Redirection Status Codes   412
4xx: Client Error Status Codes   413
5xx: Server Error Status Codes   414
Server Status Codes on Cisco Devices   414
HTTP Messages   415
HTTP General Header Fields   418
Cache Servers: Cache-Control and Pragma   418
Connection   420
Date   420
Upgrade   420
Via   421
Transfer-Encoding   421
Trailer   422
Client Request Header Fields   422

9781587145148_print.indb 17 25/03/21 11:42 am


xviii Network Programmability and Automation Fundamentals

Content Negotiation Header Fields: Accept, Accept-Charset,


Accept-Encoding and Accept-Language   423
Client Authentication Credentials: Authorization,
Proxy-Authorization and Cookie   423
Host   424
Expect   424
Max-Forwards   424
Request Context: From, Referer and User-Agent   424
TE   425
Server Response Header Fields   425
Age   425
Validator Header Fields: ETag and Last-Modified   425
Response Authentication Challenges: X-Authenticate and
Set-Cookie   426
Response Control Header Fields: Location, Retry-After, and Vary   426
Response Context: Server   427
The HTTP Entity Header Fields   427
Control Header Fields: Allow   428
Representation Metadata Header Fields: Content-X   428
Content-Length   430
Expires   430
Resource Identification   431
URI, URL, and URN   431
URI Syntax   432
URI Components   432
Characters   435
Absolute and Relative References   436
Postman   436
Downloading and Installing Postman   438
The Postman Interface   438
Using Postman   441
HTTP and Bash   447
HTTP and Python   455
TCP Over Python: The socket Module   455
The urllib Package   458
The requests Package   464
Summary   467

9781587145148_print.indb 18 25/03/21 11:42 am


Contents xix

Chapter 8 Advanced HTTP   469


HTTP/1.1 Authentication   469
Basic Authentication   472
OAuth and Bearer Tokens   474
Client Registration   476
Authorization Grant   477
Access Token   481
API Call to the Resource Server   483
State Management Using Cookies   483
Transport Layer Security (TLS) and HTTPS   487
Cryptography Primer   488
Key Generation and Exchange   488
Stream and Block Data Encryption   492
Message Integrity and Authenticity   493
Encryption and Message Integrity and Authenticity Combined   495
Digital Signatures and Peer Authentication   496
TLS 1.3 Protocol Operation   498
The TLS Version 1.3 Handshake   500
0-RTT and Early Data   502
The Record Protocol   503
HTTP over TLS (HTTPS)   503
HTTP/2   503
Streams, Messages, and Frames   504
Frame Multiplexing   505
Binary Message Framing   506
Other HTTP/2 Optimizations   507
Summary   508

Chapter 9 SSH   509


SSH Overview   509
SSH1   510
SSH2   512
SSH Transport Layer Protocol   513
SSH Authentication Protocol   514
SSH Connection Protocol   518

9781587145148_print.indb 19 25/03/21 11:42 am


xx Network Programmability and Automation Fundamentals

Setting Up SSH   521


Setting Up SSH on CentOS   521
Enabling SSH on Cisco Devices   526
Configuring and Verifying SSH on Cisco IOS XE   526
Configuring SSH on IOS XR   532
Configuring SSH on NX-OS   537
Secure File Transfer   540
Setting Up SFTP on Cisco Devices   545
Secure Copy Protocol   549
Summary   551
References 551

Part V Encoding

Chapter 10 XML   553


XML Overview, History, and Usage   553
XML Syntax and Components   554
XML Document Building Blocks   554
XML Attributes, Comments, and Namespaces   558
XML Formatting Rules   561
Making XML Valid   562
XML DTD   563
XSD   565
Brief Comparison of XSD and DTD   574
Navigating XML Documents   574
XPath   574
XML Stylesheet Language Transformations (XSLT)   578
Processing XML Files with Python   580
Summary   588

Chapter 11 JSON   591


JavaScript Object Notation (JSON)   591
JSON Data Format and Data Types   592
JSON Schema Definition (JSD)   595
Structure of the JSON Schema   595
Repetitive Objects in the JSON Schema   598
Referencing External JSON Schemas   602
Using JSON Schemas for Data Validation   609
Summary   614

9781587145148_print.indb 20 25/03/21 11:42 am


Contents xxi

Chapter 12 YAML   615


YAML Structure   616
Collections   618
Scalars   620
Tags   621
Anchors   624
YAML Example   625
Handling YAML Data Using Python   626
Summary   637

Part VI Modeling

Chapter 13 YANG   639


A Data Modeling Primer   639
What Is a Data Model?   639
Why Data Modeling Matters   640
YANG Data Models   642
Structure of a YANG Module   644
Data Types in a YANG Module   646
Built-in Data Types   647
Derived Data Types   648
Data Modeling Nodes   649
Leaf Nodes   649
Leaf-List Nodes   651
Container Nodes   652
List Nodes   653
Grouping Nodes   654
Augmentations in YANG Modules   656
Deviations in YANG Modules   658
YANG 1.1   662
Types of YANG Modules   663
The Home of YANG Modules   664
Native (Vendor-Specific) YANG Modules   666
IETF YANG Modules   670
OpenConfig YANG Modules   671
YANG Tools   673
Using pyang   673

9781587145148_print.indb 21 25/03/21 11:42 am


xxii Network Programmability and Automation Fundamentals

Using pyangbind   679


Using pyang to Create JTOX Drivers   683
Summary   688

Part VII Protocols

Chapter 14 NETCONF and RESTCONF   689


NETCONF   689
NETCONF Overview   689
NETCONF Architecture   692
The NETCONF Transport Layer   693
NETCONF Transport Protocol Requirements   693
NETCONF over SSH   694
The NETCONF Messages Layer   695
Hello Messages   696
rpc Messages   698
rpc-reply Messages   699
The NETCONF Operations Layer   701
Retrieving Data: <get> and <get-config>   702
Changing Configuration: <edit-config>, <copy-config>, and
<delete-config>   712
Datastore Operations: <lock> and <unlock>   720
Session Operations: <close-session> and <kill-session>   721
Candidate Configuration Operations: <commit>, <discard-changes>,
and <cancel-commit>   722
Configuration Validation: <validate>   724
The NETCONF Content Layer   725
NETCONF Capabilities   731
The Writable Running Capability   732
The Candidate Configuration Capability   732
The Confirmed Commit Capability   732
The Rollback-on-Error Capability   732
The Validate Capability   733
The Distinct Startup Capability   733
The URL Capability   733
The XPath Capability   735
NETCONF Using Python: ncclient   735
RESTCONF   739
Protocol Overview   739

9781587145148_print.indb 22 25/03/21 11:42 am


Contents xxiii

Protocol Architecture   742


The RESTCONF Transport Layer   743
The RESTCONF Messages Layer   743
Request Messages   743
Response Messages   744
Constructing RESTCONF Messages   745
RESTCONF HTTP Headers   745
RESTCONF Error Reporting   746
Resources   746
The API Resource   747
The Datastore Resource   749
The Schema Resource   750
The Data Resource   753
The Operations Resource   756
The YANG Library Version Resource   758
Methods and the RESTCONF Operations Layer   759
Retrieving Data: OPTIONS, GET, and HEAD   759
Editing Data: POST, PUT, PATCH, and DELETE   763
Query Parameters   771
RESTCONF and Python   777
Summary   779

Chapter 15 gRPC, Protobuf, and gNMI   781


Requirements for Efficient Transport   781
History and Principles of gRPC   782
gRPC as a Transport   784
The Protocol Buffers Data Format   786
Working with gRPC and Protobuf in Python   790
The gNMI Specification   798
The Anatomy of gNMI   799
The Get RPC   801
The Set RPC   807
The Capabilities RPC   810
The Subscribe RPC   811
Managing Network Elements with gNMI/gRPC   814
Summary   818

9781587145148_print.indb 23 25/03/21 11:42 am


xxiv Network Programmability and Automation Fundamentals

Chapter 16 Service Provider Programmability   819


The SDN Framework for Service Providers   819
Requirements for Service Provider Networks of the Future   819
SDN Controllers for Service Provider Networks   821
Segment Routing (SR)   823
Segment Routing Basics   823
Segment Routing Traffic Engineering   832
BGP Link State (BGP-LS)   843
BGP-LS Basics   843
BGP-LS Route Types   850
Node NLRI   854
Link NLRI   856
Prefix NLRI   858
Path Computation Element Protocol (PCEP)   859
Typical PCEP Call Flow   861
PCEP Call Flow with Delegation   865
Configuring PCEP in Cisco IOS XR   867
Summary   880

Part VIII Programmability Applications

Chapter 17 Programming Cisco Platforms   881


API Classification   882
Network Platforms   883
Networking APIs   884
Open NX-OS Programmability   884
IOS XE Programmability   885
IOS XR Programmability   886
Use Cases   887
Use Case 1: Linux Shells   887
Use Case 2: NX-API CLI   893
Use Case 3: NX-API REST   898
Use Case 4: NETCONF   905
Meraki   922
Meraki APIs   922
Meraki Use Case: Dashboard API   923
DNA Center   931
DNA Center APIs   933
Intent API   934

9781587145148_print.indb 24 25/03/21 11:42 am


Contents xxv

Device Management   934


Event Notifications and Webhooks   935
Integration API   935
Use Case: Intent API   936
Collaboration Platforms   942
Cisco’s Collaboration Portfolio   942
Collaboration APIs   944
Cisco Unified Communications Manager (CUCM)   944
Webex Meetings   945
Webex Teams   945
Webex Devices   946
Finesse   946
Use Case: Webex Teams   948
Summary   954

Chapter 18 Programming Non-Cisco Platforms   957


General Approaches to Programming Networks   957
The Vendor/API Matrix   957
Programmability via the CLI   958
Programmability via SNMP   959
Programmability via the Linux Shell   960
Programmability via NETCONF   960
Programmability via RESTCONF and REST APIs   961
Programmability via gRPC/gNMI   961
Implementation Examples   962
Converting the Traditional CLI to a Programmable One   962
Classical Linux-Based Programmability   967
Managing Network Devices with NETCONF/YANG   973
Managing Network Devices with RESTCONF/YANG   978
Summary   987

Chapter 19 Ansible   989


Ansible Basics   989
How Ansible Works   990
Ad Hoc Commands and Playbooks   996
The World of Ansible Modules   1000
Extending Ansible Capabilities   1003
Connection Plugins   1003

9781587145148_print.indb 25 25/03/21 11:42 am


xxvi Network Programmability and Automation Fundamentals

Variables and Facts   1005


Filters   1013
Conditionals   1016
Loops   1024
Jinja2 Templates   1034
The Need for Templates   1034
Variables, Loops, and Conditions   1040
Using Python Functions in Jinja2   1049
The join() Function   1050
The split() Function   1051
The map() Function   1054
Using Ansible for Cisco IOS XE   1055
Operational Data Verification Using the ios_command Module   1058
General Configuration Using the ios_config Module   1061
Configuration Using Various ios_* Modules   1069
Using Ansible for Cisco IOS XR   1073
Operational Data Verification Using the iosxr_command Module   1075
General Configuration Using the iosxr_config Module   1078
Configuration Using Various iosxr_* Modules   1083
Using Ansible for Cisco NX-OS   1084
Operational Data Verification Using the nxos_command Module   1086
General Configuration Using the nxos_config Module   1090
Configuration Using Various nxos_* Modules   1093
Using Ansible in Conjunction with NETCONF   1095
Operational Data Verification Using the netconf_get Module   1098
General Configuration Using the netconf_config Module   1103
Summary   1108

Part IX Looking Ahead

Chapter 20 Looking Ahead   1109


Some Rules of Thumb   1109
Automate the Painful Stuff   1109
Don’t Automate a Broken Process   1110
Clean Up Your Network   1110
Find Your Sources of Truth   1110
Avoid Automation You Can’t Reuse   1111

9781587145148_print.indb 26 25/03/21 11:42 am


Contents xxvii

Document What You Do   1111


Understand What Level of Complexity You’re Willing to Handle   1111
Do a Cost/Benefit Analysis   1112
What Do You Study Next?   1112
Model-Driven Telemetry   1113
Containers: Docker and Kubernetes   1114
Application Hosting   1115
Software Development Methodologies   1116
Miscellaneous Topics   1117
What Does All This Mean for Your Career?   1118

Index   1121

9781587145148_print.indb 27 25/03/21 11:42 am


xxviii Network Programmability and Automation Fundamentals

Icons Used in This Book

Laptop Cisco Carrier Mobile PC with software


Routing System Customer

Router Database

Wireless Wireless Modem/


Switch Cloud Connectivity Wireless Gateway

Server Cisco Nexus 7000 File Server

Command Syntax Conventions


The conventions used to present command syntax in this book are the same conventions
used in Cisco’s Command Reference. The Command Reference describes these conven-
tions as follows:

■■ Boldface indicates commands and keywords that are entered literally as shown. In
actual configuration examples and output (not general command syntax), boldface
indicates commands that are manually input by the user (such as a show command).

■■ Italics indicate arguments for which you supply actual values.

■■ Vertical bars (|) separate alternative, mutually exclusive elements.

■■ Square brackets [ ] indicate optional elements.

■■ Braces { } indicate a required choice.

■■ Braces within brackets [{ }] indicate a required choice within an optional element.

Note This book covers multiple operating systems, and in each example, icons and router
names indicate the OS that is being used. IOS and IOS XE use router names like R1 and R2
and are referenced by the IOS router icon. IOS XR routers use router names like XR1 and
XR2 are referenced by the IOS XR router icon.

9781587145148_print.indb 28 25/03/21 11:42 am


xxix

Introduction
For more than three decades, network management has been entirely based on the
command-line interface (CLI) and legacy protocols such as SNMP. These protocols and
methods are severely limited. The CLI, for example, is vendor specific, lacks a unified
data hierarchy (sometimes even for platforms from the same vendor), and was designed
primarily as a human interface. SNMP suffers major scaling problems, is not fit for writ-
ing configuration to devices, and overall, is very complex to implement and customize.

In essence, automation aims at offloading as much work from humans as possible and
delegating that work to machines. But with the aforementioned legacy interfaces and pro-
tocols, machine-to-machine communication is neither effective nor efficient; and at times,
close to impossible.

Moreover, device configuration and operational data have traditionally lacked a proper
hierarchy and failed to follow a data model. In addition, network management workflows
have always been far from mature, compared to software development workflows in
terms of versioning, collaboration, testing, and automated deployments.

Enter network programmability. Programmability revolves around programmable inter-


faces, commonly referred to as application programming interfaces (APIs). APIs are inter-
faces that are designed primarily to be used for machine-to-machine communication. A
Python program accessing a network router to retrieve or push configuration, without
human intervention, is an example of a machine-to-machine interaction. Contrast this
with the CLI, where a human needs to manually enter commands on a device and then
visually inspect the output.

Network equipment vendors (for both physical and virtual equipment) are placing ever-
increasing emphasis on the importance of managing their equipment using programmable
interfaces, and Cisco is at the forefront of this new world. This new approach to managing
a network provides several benefits over legacy methods, including the following:

■■ Normalizing the interface for interaction with network platforms by abstracting


communication with these platforms and breaking the dependency of this commu-
nication on specific network OS scripting languages (for example, NX-OS, IOS XR,
and Junos OS)

■■ Providing new methods of interacting with network platforms and, in the process,
enabling and aligning with new technologies and architectures, such as SDN, NFV,
and cloud

■■ Harnessing the power of programming to automate manual tasks and perform


repetitive tasks efficiently

■■ Enabling rapid infrastructure and service deployment by using workflows for service
provisioning

■■ Increasing the reliability of the network configuration process by leveraging error


checking, validation, and rollback and minimizing human involvement in the
configuration process

A01_Abuelenain_FM_pi-pxxxvi.indd 29 25/03/21 2:57 pm


xxx Network Programmability and Automation Fundamentals

■■ Using common software development tools and techniques for network configura-
tion management, such as software development methodologies, versioning, staging,
collaboration, testing, and continuous integration/continuous delivery

This book covers all the major programmable interfaces used in the market today for net-
work management. The book discusses the protocols, tools, techniques, and technologies
on which network programmability is based. Programming, operating systems, and APIs
are not new technologies. However, programmable interfaces on network platforms, and
using these programmable interfaces to fully operate and maintain a network, along with
the culture accompanying these new methods and protocols, may be (relatively) new. This
book explains, in detail, all the major components of this new ecosystem.

Goals and Methods of This Book


This is a “fundamentals” book aimed at transitioning network engineers from a legacy
network-based mindset to a software-based (and associated technologies) mindset. A
book covering fundamentals generally struggles to cover as many subjects as possible
with just enough detail. The fine balance between breadth and depth is challenging, but
this book handles this challenge very well.

This book introduces the emerging network programmability and automation ecosystem
based on programmable interfaces. It covers each protocol individually, in some significant
detail, using the relevant RFCs as guiding documents. Protocol workflows, messages, and
other protocol nuances tend to be dry, and at times boring, so to keep things interesting,
practical examples are given wherever possible and relevant. You, the reader, can follow
and implement these examples on your machine, which can be as simple as a Linux virtual
machine with Python Version 3.x installed, and free tools to work with APIs, such as Postman
and cURL. This book makes heavy use of the Cisco DevNet sandboxes, so in the majority of
cases, you do not need a home lab to test and experiment with physical equipment.

A whole section of the book is dedicated to putting the knowledge and skills learned
throughout the book to good use. One chapter covers programming Cisco platforms and
another covers programming non-Cisco platforms. A third chapter in that same section is
dedicated exclusively to Ansible. This book provides an abundance of hands-on practice.

The last chapter provides a way forward, discussing tools and technologies that you
might want to explore after you are done with this book.

Who This Book Is For


This book is meant for the following individuals and roles, among others:

■■ Network architects and engineers who want to integrate programmability into their
network designs

■■ NOC engineers monitoring and operating programmable networks or those who


rely on network management systems that utilize programmability protocols

9781587145148_print.indb 30 25/03/21 11:42 am


Introduction xxxi

■■ Network engineers designing, implementing, and deploying new network services

■■ Software engineers or programmers developing applications for network manage-


ment systems

■■ Network and software engineers working with networks or systems involving SDN,
NFV, or cloud technologies

■■ Network engineers pursuing their Cisco DevNet certifications

Whether you are an expert network engineer with no prior programming experience or
knowledge, or a software engineer looking to utilize your expertise in the network auto-
mation domain, after reading this book, you will fully understand the most commonly
used protocols, tools, technologies, and techniques related to the subject, and you will be
capable of effectively using the newly learned material to design, implement, and operate
full-fledged programmable networks and the associated network automation systems.

How This Book Is Organized


This book covers the information you need to transition from having a focus on net-
working technology to focusing on software and network programmability. This book
covers six main focus areas:

■■ Operating systems: Linux

■■ Software development: Python

■■ Transport: HTTP, REST, and SSH

■■ Encoding: XML, JSON, and YAML

■■ Modeling: YANG

■■ Protocols: NETCONF, RESTCONF, gRPC, and service provider programmability

■■ Practical programmability: Cisco platforms, non-Cisco platforms, and Ansible

Each chapter in this book either explicitly covers one of these focus areas or prepares
you for one of them. Special consideration has been given to the ordering of topics to
minimize forward referencing. Following an introduction to the programmability land-
scape, Linux is covered first because to get anything done in network programmability,
you will almost always find yourself working with Linux. The book next covers Python
because the vast majority of the rest of the book includes coverage of Python in the con-
text of working with various protocols. The following chapters present an organic flow
of topics: transport, encoding, modeling, and the protocols that build on all the previous
sections. For example, understanding NETCONF requires you to understand SSH, XML,
and YANG, and understanding RESTCONF requires that you understand HTTP, XML/
JSON, and YANG. Both NETCONF and RESTCONF require knowledge of Python, most
likely running on a Linux machine.

A01_Abuelenain_FM_pi-pxxxvi.indd 31 25/03/21 2:57 pm


xxxii Network Programmability and Automation Fundamentals

How This Book Is Structured


The book is organized into nine parts, described in the following sections.

PART I, “Introduction”
Chapter 1, “The Network Programmability and Automation Ecosystem”: This chapter
introduces the concepts and defines the terms that are necessary to understand the pro-
tocols and technologies covered in the following chapters. It also introduces the network
programmability stack and explores the different components of the stack that constitute
a typical network programmability and automation toolbox.

PART II, “Linux”


Chapter 2, “Linux Fundamentals”: Linux is the predominant operating system used
for running software for network programmability and automation. Linux is also the
underlying operating system for the vast majority of network device software, such as
IOS XR, NX-OS, and Cumulus Linux. Therefore, to be able to effectively work with pro-
grammable devices, it is of paramount importance to master the fundamentals of Linux.
This chapter introduces Linux, including its architecture and boot process, and covers
the basics of working with Linux through the Bash shell, such as working with files and
directories, redirecting input and output, performing system maintenance, and installing
software.

Chapter 3, “Linux Storage, Security, and Networks”: This chapter builds on Chapter 2
and covers more advanced Linux topics. It starts with storage on Linux systems and the
Linux Logical Volume Manager. It then covers Linux user, group, file, and system secu-
rity. Finally, it explains three different methods to manage networking in Linux; the ip
utility, the NetworkManager service, and network configuration files.

Chapter 4, “Linux Scripting”: This chapter builds on Chapters 2 and 3 and covers Linux
scripting using the Bash shell. The chapter introduces the grep, awk, and sed utilities and
covers the syntax and semantics of Bash scripting. The chapter covers comments, input
and output, variables and arrays, expansion, operations and comparisons, how to execute
system commands from a Bash script, conditional statements, loops, and functions. It also
touches on the Expect programming language.

PART III, “Python”


Chapter 5, “Python Fundamentals”: This chapter assumes no prior knowledge of pro-
gramming and starts with an introduction to programming, covering some very important
software and computer science concepts, including algorithms and object-oriented pro-
gramming. It also discusses why programming is a foundational skill for learning network
programmability and covers the fundamentals of the Python programming language,

9781587145148_print.indb 32 25/03/21 11:42 am


Introduction xxxiii

including installing Python Version 3.x, executing Python programs, input and output,
data types, data structures, operators, conditional statements, loops, and functions.

Chapter 6, “Python Applications”: This chapter builds on Chapter 5 and covers the
application of Python to different domains. The chapter illustrates the use of Python for
creating web applications using Django and Flask, for network programmability using
NAPALM and Nornir, and for orchestration and machine learning. The chapter also cov-
ers some very important tools and protocols used in software development in general,
such as Git, containers, Docker and virtual environments.

PART IV, “Transport”


Chapter 7, “HTTP and REST”: This is one of the most important chapters in this book.
It introduces the HTTP protocol and the REST architectural framework, as well as the
relationship between them. This chapter covers HTTP connections based on TCP. It
also covers the anatomy of HTTP messages and dives into the details of HTTP request
methods and response status codes. It also provides a comprehensive explanation of the
most common header fields. The chapter discusses the syntax rules that govern the use
of URIs and then walks through working with HTTP, using tools such as Postman, cURL,
and Python libraries, such as the requests library.

Chapter 8, “Advanced HTTP”: Building on Chapter 7, this chapter moves to more


advanced HTTP topics, including HTTP authentication and how state can be maintained
over HTTP connections by using cookies. This chapter provides a primer on cryptogra-
phy for engineers who know nothing on the subject and builds on that to cover TLS, and
HTTP over TLS (aka HTTPS). It also provides a glimpse into HTTP/2 and HTTP/3, and
the enhancements introduced by these newer versions of HTTP.

Chapter 9, “SSH”: Despite being a rather traditional protocol, SSH is still an integral
component of the programmability stack. SSH is still one of the most widely used pro-
tocols, and having a firm understanding of the protocol is crucial. This chapter discusses
the three sub-protocols that constitute SSH and cover the lifecycle of an SSH connec-
tion: the SSH Transport Layer Protocol, User Authentication Protocol, and Connection
Protocol. It also discusses how to set up SSH on Linux systems as well as how to work
with SSH on the three major network operating system: IOS XR, IOS XE, and NX-OS.
Finally, it covers SFTP, which is a version of FTP based on SSH.

PART V, “Encoding”
Chapter 10, “XML”: This chapter covers XML, the first of three encoding protocols
covered in this book. XML is the oldest of the three protocols and is probably the most
sophisticated. This chapter describes the general structure of an XML document as well
as XML elements, attributes, comments, and namespaces. It also covers advanced XML
topics such as creating document templates using DTD and XML-based schemas using
XSD, and it compares the two. This chapter also covers XPath, XSLT, and working with
XML using Python.

9781587145148_print.indb 33 25/03/21 11:42 am


xxxiv Network Programmability and Automation Fundamentals

Chapter 11, “JSON”: JSON is less sophisticated, newer, and more human-readable than
XML, and it is therefore a little more popular that XML. This chapter covers JSON data
formats and data types, as well as the general format of a JSON-encoded document.
The chapter also covers JSON Schema Definition (JSD) for data validation and how JSD
coexists with YANG.

Chapter 12, “YAML”: YAML is frequently described as a superset of JSON. YAML is


slightly more human-readable than JSON, but data encoded in YAML tends to be signifi-
cantly lengthier than its JSON-encoded counterpart. YAML is a very popular encoding
format and is required for effective use of tools such as Ansible. This chapter covers the
differences between XML, JSON, and YAML and discusses the structure of a YAML
document. It also explains collections, scalers, tags, and anchors. Finally, the chapter
discusses working with YAML in Python.

PART VI, “Modeling”


Chapter 13, “YANG”: At the heart of the new paradigm of network programmability is
data modeling. This is a very important chapter that covers both generic modeling and
the YANG modeling language. This chapter starts with a data modeling primer, explain-
ing what a data model is and why it is important to have data models. Then it explains
the structure of a data model. This chapter describes the different node types in YANG
and their place in a data model hierarchy. It also delves into more advanced topics, such
as augmentations and deviations in YANG. It describes the difference between open-
standard and vendor-specific YANG models and where to get each type. Finally, the
chapter covers a number of tools for working with YANG modules, including pyang and
pyangbind.

PART VII, “Protocols”


Chapter 14, “NETCONF and RESTCONF”: NETCONF was the first protocol developed
to replace SNMP. RESTCONF was developed later and is commonly referred to as the
RESTful version of NETCONF. Building on earlier chapters, this chapter takes a deep
dive into both NETCONF and RESTCONF. The chapter covers the protocol architecture
as well as the transport, message, operations, and content layers of each of the two
protocols. It also covers working with these protocols using Python.

Chapter 15, “gRPC, Protobuf, and gNMI”: The gRPC protocol was initially developed
by Google for network programmability that borrows its operational concepts from the
communications models of distributed applications. This chapter provides an overview of
the motivation that drove the development of gRPC. It covers the communication flow of
gRPC and protocol buffers (Protobuf) used to serialize data for gRPC communications.
The chapter also shows how to work with gRPC using Python. The chapter then takes a
deep dive into gNMI, a gRPC-based specification. Finally, the chapter shows how gRPC
and gNMI are used to manage a Cisco IOS XE device.

9781587145148_print.indb 34 25/03/21 11:42 am


Introduction xxxv

Chapter 16, “Service Provider Programmability”: Service providers face unique


challenges due to the typical scale of their operations and the stringent KPIs that must be
imposed on their networks, especially given the heated race to adopt 5G and associated
technologies. This chapter discusses how such challenges influence the programmability
and automation in service provider networks and provides in-depth coverage of Segment
Routing, BGP-LS, and PCEP.

PART VIII, “Programmability Applications”


Chapter 17, “Programming Cisco Platforms”: This chapter explores the programmabil-
ity capabilities of several Cisco platforms, covering a wide range of technology domains.
In addition, this chapter provides several practical examples and makes heavy use of
Cisco’s DevNet sandboxes. This chapter covers the programmability of IOS XE, IOS XR,
NX-OS, Meraki, DNA Center, and Cisco’s collaboration platforms, with a use case
covering Webex Teams.

Chapter 18, “Programming Non-Cisco Platforms”: This chapter covers the program-
mability of a number of non-Cisco platforms, such as the Cumulus Linux and Arista EOS
platforms. This chapter shows that the knowledge and skills gained in the previous chap-
ters are truly vendor neutral and global. In addition, this chapter shows that programma-
bility using APIs does in fact abstract network configuration and management and breaks
the dependency on vendor-specific CLIs.
Chapter 19, “Ansible”: This chapter covers a very popular tool that has become synony-
mous with network automation: Ansible. As a matter of fact, Ansible is used in the appli-
cation and compute automation domains as well. Ansible is a very simple, yet extremely
powerful, automation tool that provides a not-so-steep learning curve, and hence a quick
and effective entry point into network automation. This is quite a lengthy chapter that
takes you from zero to hero in Ansible.

PART IX, “Looking Ahead”


Chapter 20, “Looking Ahead”: This chapter builds on the foundation covered in the pre-
ceding chapters and discusses more advanced technologies and tools that you might want
to explore to further your knowledge and skills related to network programmability and
automation.

9781587145148_print.indb 35 25/03/21 11:42 am


This page intentionally left blank

9781587145148_print.indb 36 25/03/21 11:42 am


Chapter 3

Linux Storage, Security,


and Networks

Chapter 2, “Linux Fundamentals,” covers Linux basics, and by now, you should be
familiar with the Linux environment and feel comfortable performing general system
maintenance tasks. This chapter takes you a step further in your Linux journey and
covers storage, security, and networking.

Linux Storage
Many network engineers struggle with concepts such as what mounting a volume means
and the relationship between physical and logical volumes. This section covers every-
thing you need to know about storage to effectively manage a Linux-based environment,
whether it is your development environment or the underlying Linux system on which a
network operating system is based, such as IOS XR and NX-OS.

Physical Storage
The /dev directory contains device files, which are special files used to access the hard-
ware on a system. A program trying to access a device uses a device file as an interface to
the device driver of that device. Writing data to a device file is the same as sending data
to the device represented by that device file, and reading data from a device file is the
same as receiving data from that device. For example, writing data to the printer device
file prints this data, and reading data from the device file of a hard disk partition is the
same as reading data from that partition on the disk.

Example 3-1 shows the output of the ls -l command for the /dev directory. Notice that,
unlike other directories, the first bit of the file permissions is one of five characters:

■■ - for regular files

■■ d for directories

9781587145148_print.indb 119 25/03/21 11:43 am


120 Chapter 3: Linux Storage, Security, and Networks

■■ l for links

■■ c for character device files

■■ b for block device files

You learned about the first three of these bits in Chapter 2, and the other two are covered
here.

Example 3-1 Contents of the /dev Directory

[netdev@server1 dev]$ ls -l
total 0
-rw-r--r--. 1 root root 0 Aug 10 00:28 any_regular_file
crw-r--r--. 1 root root 10, 235 Aug 10 00:19 autofs
drwxr-xr-x. 2 root root 140 Aug 10 00:18 block
drwxr-xr-x. 2 root root 60 Aug 10 00:18 bsg
drwxr-xr-x. 3 root root 60 Aug 10 00:19 bus
drwxr-xr-x. 2 root root 2940 Aug 10 00:20 char
drwxr-xr-x. 2 root root 80 Aug 10 00:18 cl
crw-------. 1 root root 5, 1 Aug 10 00:20 console
lrwxrwxrwx. 1 root root 11 Aug 10 00:18 core -> /proc/kcore
drwxr-xr-x. 6 root root 120 Aug 10 00:19 cpu
crw-------. 1 root root 10, 62 Aug 10 00:19 cpu_dma_latency
drwxr-xr-x. 6 root root 120 Aug 10 00:18 disk
brw-rw----. 1 root disk 253, 0 Aug 10 00:19 dm-0
brw-rw----. 1 root disk 253, 1 Aug 10 00:19 dm-1

--------- OUTPUT TRUNCATED FOR BREVITY ---------

Character device files provide unbuffered access to hardware. This means that what is
written to the file is transmitted to the hardware device right away, byte by byte. The
same applies to read operations. Think of data sent to the device file of an audio output
device or data read from the device file representing your keyboard. This data should not
be buffered.

On the other hand, block device files provide buffered access; that is, data written to a
device file is buffered by the kernel before it is passed on to the hardware device. The
same applies to read operations. Think of data written to or read from a partition on your
hard disk. This is typically done in data blocks, not individual bytes.

However, note that the device file type (as seen in the /dev directory) is not necessarily
the same as the device type. Storage devices such as hard disks are block devices, which
means that data is read from and written to the device in fixed-size blocks. Although this
may sound counterintuitive, block devices may be accessed using character device files
on some operating systems, such as BSD. This is not the case with Linux, where block

9781587145148_print.indb 120 25/03/21 11:43 am


Linux Storage 121

devices are always associated with block device files. The difference between block
devices and block device files is sometimes a source of confusion.

The first step in analyzing a storage and file system is getting to know the hard disks.
Each hard disk and partition has a corresponding device file in the /dev directory. By
listing the contents of this directory, you find the sda file for the first hard disk, and, if
installed, sdb for the second hard disk, sdc for the third hard disk, and so forth. Partitions
are named after the hard disk that the partition belongs to, with the partition number
appended to the name. For example, the first partition on the second hard disk is
named sdb1. The hard disk naming convention follows the configuration in the /lib/udev/
rules.d/60-persistent-storage.rules file, and the configuration is per hard disk type (ATA,
USB, SCSI, SATA, and so on). Example 3-2 lists the relevant files in the /dev directory on
a CentOS 7 distro. As you can see, this system has two hard disks. The first hard disk is
named sda and has two partitions—sda1 and sda2—and the second is named sdb and has
three partitions—sdb1, sdb2, and sdb3.

Example 3-2 Hard Disks and Partitions in the /dev Directory

[root@localhost ~]# ls -l /dev | grep sd


brw-rw----. 1 root disk 8, 0 Jun 8 04:55 sda
brw-rw----. 1 root disk 8, 1 Jun 8 04:55 sda1
brw-rw----. 1 root disk 8, 2 Jun 8 04:55 sda2
brw-rw----. 1 root disk 8, 16 Jun 8 04:55 sdb
brw-rw----. 1 root disk 8, 17 Jun 8 04:55 sdb1
brw-rw----. 1 root disk 8, 18 Jun 8 04:55 sdb2
brw-rw----. 1 root disk 8, 19 Jun 8 04:55 sdb3

Notice the letter b at the beginning of each line of the output in Example 3-2. This indi-
cates a block device file. A character device file would have the letter c instead.

The command fdisk -l lists all the disks and partitions on a system, along with some use-
ful details. Example 3-3 shows the output of this command for the same system as in
Example 3-2.

Example 3-3 Using the fdisk -l Command to Get Hard Disk and Partition Details

[root@localhost ~]# fdisk -l

Disk /dev/sda: 26.8 GB, 26843545600 bytes, 52428800 sectors


Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x000b4fba

9781587145148_print.indb 121 25/03/21 11:43 am


122 Chapter 3: Linux Storage, Security, and Networks

Device Boot Start End Blocks Id System


/dev/sda1 * 2048 2099199 1048576 83 Linux
/dev/sda2 2099200 52428799 25164800 8e Linux LVM

Disk /dev/sdb: 107.4 GB, 107374182400 bytes, 209715200 sectors


Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x149c8964

Device Boot Start End Blocks Id System


/dev/sdb1 2048 41945087 20971520 83 Linux
/dev/sdb2 41945088 83888127 20971520 83 Linux
/dev/sdb3 83888128 115345407 15728640 83 Linux

Disk /dev/mapper/centos-root: 23.1 GB, 23081254912 bytes, 45080576 sectors


Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

Disk /dev/mapper/centos-swap: 2684 MB, 2684354560 bytes, 5242880 sectors


Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
[root@localhost ~]#

In addition to physical disks /dev/sda and /dev/sdb and their respective partitions, the
command output in Example 3-3 lists two other disks: /dev/mapper/centos-root and /dev/
mapper/centos-swap. These are two logical volumes. (Logical volumes are discussed in
detail in the next section.) Notice that there is an asterisk (*) under the title Boot for parti-
tion /dev/sda1. As you may have guessed, this indicates that this is the partition on which
the boot sector resides, containing the boot loader. The boot loader is the software that
will eventually load the kernel image into memory during the system boot process, as
you have read in Section “The Linux Boot Process” in Chapter 2.

In addition to displaying existing partition details, fdisk can create new partitions and
delete existing ones. For example, after a third hard disk, sdc, is added to the system,
the fdisk utility can be used to create two partitions, sdc1 and sdc2, as shown in
Example 3-4.

9781587145148_print.indb 122 25/03/21 11:43 am


Linux Storage 123

Example 3-4 Creating New Hard Disk Partitions by Using the fdisk Utility

! Current status of the sdc hard disk: no partitions exist


[root@localhost ~]# fdisk -l /dev/sdc

Disk /dev/sdc: 21.5 GB, 21474836480 bytes, 41943040 sectors


Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

! Using fdisk to create two new partitions on sdc


[root@localhost ~]# fdisk /dev/sdc
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table


Building a new DOS disklabel with disk identifier 0x4cd00767.

Command (m for help): m


Command action
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition
g create a new empty GPT partition table
G create an IRIX (SGI) partition table
l list known partition types
m print this menu
n add a new partition
o create a new empty DOS partition table
p print the partition table
q quit without saving changes
s create a new empty Sun disklabel
t change a partition's system id
u change display/entry units
v verify the partition table
w write table to disk and exit
x extra functionality (experts only)

Command (m for help): n


Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended

9781587145148_print.indb 123 25/03/21 11:43 am


124 Chapter 3: Linux Storage, Security, and Networks

Select (default p): p


Partition number (1-4, default 1):
First sector (2048-41943039, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039): +5G
Partition 1 of type Linux and of size 5 GiB is set

Command (m for help): n


Partition type:
p primary (1 primary, 0 extended, 3 free)
e extended
Select (default p):
Using default response p
Partition number (2-4, default 2):
First sector (10487808-41943039, default 10487808):
Using default value 10487808
Last sector, +sectors or +size{K,M,G} (10487808-41943039, default 41943039):
Using default value 41943039
Partition 2 of type Linux and of size 15 GiB is set

Command (m for help): w


The partition table has been altered!

Calling ioctl() to re-read partition table.


Syncing disks.

! Status after creating the two new partitions sdc1 and sdc2
[root@localhost ~]# fdisk -l /dev/sdc

Disk /dev/sdc: 21.5 GB, 21474836480 bytes, 41943040 sectors


Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x4cd00767

Device Boot Start End Blocks Id System


/dev/sdc1 2048 10487807 5242880 83 Linux
/dev/sdc2 10487808 41943039 15727616 83 Linux3
[root@localhost ~]#

The interactive dialogue of the fdisk utility is self-explanatory. After the fdisk /dev/sdc
command is issued, you can enter m to see all available options. You can enter n to start
the new partition dialogue. Note the different methods to specify the size of the

9781587145148_print.indb 124 25/03/21 11:43 am


Linux Storage 125

partition. If you go with the default option (by simply pressing Enter), the command uses
all the remaining space on the disk to create that particular partition.

Before a hard disk partition can be used to store data, the partition needs to be format-
ted; that is, a file system has to be created. (File systems are discussed in some detail in
Chapter 2.) At the time of writing, the two most common file systems used on Linux are
ext4 and xfs. A partition is formatted using the mkfs utility. In Example 3-5, the sdc1
partition is formatted to use the ext4 file system, and sdc2 is formatted to use the xfs
file system.

Example 3-5 Creating File Systems by Using the mkfs Command

[root@localhost ~]# mkfs -t ext4 /dev/sdc1


mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
327680 inodes, 1310720 blocks
65536 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=1342177280
40 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736

Allocating group tables: done


Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done

[root@localhost ~]# mkfs -t xfs /dev/sdc2


meta-data=/dev/sdc2 isize=512 agcount=4, agsize=982976 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0, sparse=0
data = bsize=4096 blocks=3931904, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
[root@localhost ~]#

9781587145148_print.indb 125 25/03/21 11:43 am


126 Chapter 3: Linux Storage, Security, and Networks

To specify a file system type, you use mkfs with the -t option. Keep in mind that the
command output depends on the file system type used with the command.

The final step toward making a partition usable is to mount that partition or file system.
Mounting is usually an ambiguous concept to engineers who are new to Linux. As dis-
cussed in Chapter 2, the Linux file hierarchy always starts at the root directory, repre-
sented by /, and branches down. For a file system to be accessible, it has to be mounted
to a mount point—that is, attached (mounted) to the file hierarchy at a specific path in
that hierarchy (mount point). The mount point is the path in the file hierarchy that the file
system is attached to and through which the contents of that file system can be accessed.
For example, mounting the /dev/sdc1 partition to the /Operations directory maps the
content of /dev/sdc1 to, and makes it accessible through, the /Operations directory, for
both read and write operations. Example 3-6 shows the /Operations directory being
created and the sdc1 partition being mounted to it.

Example 3-6 Mounting /dev/sdc1 to /Operations

[root@localhost ~]# mkdir /Operations


[root@localhost ~]# mount /dev/sdc1 /Operations

To display all the mounted file systems, you use the df command, as shown in
Example 3-7. The option -h displays the file system sizes in human-readable format.

Example 3-7 Output of the df -h Command

[root@localhost ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 22G 5.3G 17G 25% /
devtmpfs 3.9G 0 3.9G 0% /dev
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 3.9G 9.4M 3.9G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/sda1 1014M 333M 682M 33% /boot
tmpfs 783M 32K 783M 1% /run/user/1000
/dev/sdc1 4.8G 20M 4.6G 1% /Operations
[root@localhost ~]#

Each row in the output in Example 3-7 is a separate file system. The entry /dev/mapper/
centos-root is a logical volume (and is discussed in detail in the next section). The fol-
lowing few entries are tmpfs file systems, which are temporary file systems created in
memory (not on disk) for cache-like operations due to the high speed of RAM, as com-
pared to the low speed of hard disks. An entry exists in the list for partition /dev/sda1
that is mounted to directory /boot. Then the entry at the bottom is for /dev/sdc1 that was
mounted to directory /Operations as shown in Example 3-6.

9781587145148_print.indb 126 25/03/21 11:43 am


Linux Storage 127

To unmount the /dev/sdc1 file system, you use the umount /dev/sdc1 command. You can
also use the mount point, in which case the command is umount /Operations. Note that
the command is umount, not unmount. Adding the letter n is a very common error.

The mounting done by using the mount command is not persistent. In other words, once
the system is rebooted, the volumes mounted using the mount command are no longer
mounted. For persistent mounting, an entry needs to be added to the /etc/fstab file.
Example 3-8 shows the contents of the /etc/fstab file after the entry for /dev/sdc1 is added.

Example 3-8 Editing the /etc/fstab File for Persistent Mounting

! Adding an entry for /etc/sdc1 using the echo command


[root@localhost ~]# echo "/dev/sdc1 /Operations ext4 defaults 0 0" >> /etc/fstab

! After adding an entry for /etc/sdc1


[root@localhost ~]# cat /etc/fstab
#
# /etc/fstab
# Created by anaconda on Sat May 26 04:28:54 2018
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root / xfs defaults 0 0
UUID=dfe65618-19ab-458d-b5e3-dafdb59b4e68 /boot xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
/dev/sdc1 /Operations ext4 defaults 0 0

! Command mount -a immediately mounts all file systems listed in fstab


[root@localhost ~]# mount -a

The command mount -a immediately mounts all file systems listed in /etc/fstab.

The /etc/fstab file has one entry for each file system that is to be mounted at system boot.
It is important to understand the entries in the /etc/fstab file because this is the file that
defines what file systems a system will have mounted right after it boots and the options
that each of these file systems will be mounted with. Each line has the following fields:

■■ The first field can be either the file system path, the universal unique identifier (UUID),
or the label. You can learn the UUID (and type) of all file systems by using the com-
mand blkid. You can show the label by using the command tune2fs -l {file_system}
for ext2/3/4 file systems or xfs_admin -l {file_system} for xfs file systems. Using the
file system path, which is /dev/sdc1 in this case, is pretty straightforward. However,
when a system has tens of hard disks installed, it would be wiser to use the partition
UUIDs. A UUID is a unique number that identifies a partition. The UUID does not
change if the hard disk containing the partition is moved to another system, and hence
it is universal. Using a UUID eliminates the possibility of errors in the /etc/fstab file.

9781587145148_print.indb 127 25/03/21 11:43 am


128 Chapter 3: Linux Storage, Security, and Networks

■■ The second field is the file system mount point, which is /Operations in this case.

■■ The third field is the file system type, which is ext4 in this example.

■■ The fourth field is the mounting options. In this example, defaults indicates that
the default mounting options will be used. You can also add non-default mounting
options such as acl for ACL support. You add options in a comma-separated list.

■■ The fifth field indicates which file systems are to be backed up by the dump utility.
The zero value in this case indicates that this file system will not be automatically
backed up.

■■ The sixth field is used by the fsck utility to determine whether to check the health
of the file system. The fsck utility checks file systems with a nonzero value in this
field, in order, starting with the file system that has the value one. A zero in this field
tells the fsck utility not to check that file system.

fdisk is not the only Linux utility available to manipulate disk partitions. Two other
popular utilities for disk partitioning are gdisk and parted. You can use the man pages
for these utilities to explore them and use a non-production environment (ideally a virtual
machine) to experiment with using them. You may run into a distro that has one of them
implemented but not the other. The more utilities you are familiar with, the better.

Logical Volume Manager


Linux generally uses the concept of logical volumes to provide storage to users. Logical
volumes abstract the storage that is available to a user from the actual physical disks.
Logical volumes on Linux are managed by system software called Logical Volume
Manager (LVM). LVM operates by grouping physical disks or disk partitions, each
referred to as a physical volume (PV), such as /dev/sda or /dev/sdb2, into a volume
group (VG). LVM then manages a VG as one pool of storage that is split by the LVM into
one or more logical volumes (LVs). Figure 3-1 illustrates these concepts.

Logical
Volume 1 Logical
Volume 2 Logical
Volume Z

Volume Group Y

Physical Physical Physical


Volume 1 Volume 2 Volume X

Figure 3-1 Physical Volumes, Volume Groups, and Logical Volumes

M03_Abuelenain_C03_p119-p182.indd 128 26/03/21 1:44 pm


Linux Storage 129

To better understand the concept of logical volumes, keep in mind the following:

■■ The different PVs that constitute a VG do not have to be equal in size.

■■ The different PVs that constitute a VG may be different disks, or different partitions
on the same disk, or different partitions on different disks.

■■ Two different partitions on the same disk may be members of two different VGs.

■■ The LVs that are created from a VG do not correlate to the PVs that constitute the
VG in either size or number.

Using LVs created by LVM provides several advantages over using physical storage directly.
The most significant benefit is the disassociation between user data and specific physi-
cal storage volumes. From a capacity perspective, capacity can be added to and removed
from a logical volume without having to repartition a physical disk to create a bigger or
smaller partition, and a file system is not limited by the size of the physical disk that it
resides on. From a performance perspective, data may be striped across several physical
volumes (for added throughput) transparently from the user. These are just a few of the
advantages.

The following steps are involved in creating a logical volume that is ready to use:

Step 1. Using the command pvcreate {physical_disk/partition}, label the physical


volumes that will constitute the volume group as LVM physical volumes.

Step 2. Using the command vgcreate {vg_name} {pv1} {pv2} .. {pvN}, create the VG
by using the physical volumes pv1, pv2,…pvN.

Step 3. Using the command lvcreate -n {lv_name} -L {lv_size} {vg_name}, create the
logical volume named lv_name from the volume group named vg_name.

Step 4. Create the file system of choice on the new logical volume by using the mkfs
command, exactly as you would on a physical partition.
Step 5. Mount the new file system by using the mount command exactly as you
would mount a file system created on a physical partition.

In Example 3-9, two disks, sdb and sdc, are each divided into two partitions
as follows:

■■ sdb1: 12 GB

■■ sdb2: 8 GB

■■ sdc1: 15 GB

■■ sdc2: 10 GB

9781587145148_print.indb 129 25/03/21 11:43 am


130 Chapter 3: Linux Storage, Security, and Networks

Example 3-9 The Four Partitions That Will Be Used to Create a Volume Group

[root@server1 ~]# fdisk -l | grep –E sd[b,c]


Disk /dev/sdc: 26.8 GB, 26843545600 bytes, 52428800 sectors
/dev/sdc1 2048 31459327 15728640 83 Linux
/dev/sdc2 31459328 52428799 10484736 83 Linux
Disk /dev/sdb: 21.5 GB, 21474836480 bytes, 41943040 sectors
/dev/sdb1 2048 25167871 12582912 83 Linux
/dev/sdb2 25167872 41943039 8387584 83 Linux
[root@server1 ~]#

After each of the four partitions is labeled as a PV, all four partitions are added to the VG
VGNetProg, which has a total capacity of 40 GB. The volume group capacity is then used
to create two logical volumes—LVNetAutom with a capacity of 10 GB and LVNetDev
with a capacity of 30 GB—as shown in Example 3-10.

Example 3-10 Creating Physical Volumes, Volume Groups, and Logical Volumes

! Label the physical volumes


[root@server1 ~]# pvcreate /dev/sdb1 /dev/sdb2 /dev/sdc1 /dev/sdc2
Physical volume "/dev/sdb1" successfully created.
Physical volume "/dev/sdb2" successfully created.
Physical volume "/dev/sdc1" successfully created.
Physical volume "/dev/sdc2" successfully created.

! Create the volume group


[root@server1 ~]# vgcreate VGNetProg /dev/sdb1 /dev/sdb2 /dev/sdc1 /dev/sdc2
Volume group "VGNetProg" successfully created

! Create the two logical volumes


[root@server1 ~]# lvcreate -n LVNetAutom -L 10G VGNetProg
Logical volume "LVNetAutom" created.
[root@server1 ~]# lvcreate -n LVNetDev -L 30G VGNetProg
Logical volume "LVNetDev" created.
[root@server1 ~]#

Example 3-11 shows the pvdisplay command being used to display the details of the
physical volumes.

9781587145148_print.indb 130 25/03/21 11:43 am


Linux Storage 131

Example 3-11 Displaying Physical Volume Details by Using the pvdisplay Command

[root@server1 ~]# pvdisplay /dev/sdb1


--- Physical volume ---
PV Name /dev/sdb1
VG Name VGNetProg
PV Size 12.00 GiB / not usable 4.00 MiB
Allocatable yes
PE Size 4.00 MiB
Total PE 3071
Free PE 511
Allocated PE 2560
PV UUID dPYPj6-Wv1i-iX7H-3iH0-oCnE-OzkA-2LcJlx
[root@server1 ~]# pvdisplay /dev/sdb2
--- Physical volume ---
PV Name /dev/sdb2
VG Name VGNetProg
PV Size <8.00 GiB / not usable 3.00 MiB
Allocatable yes
PE Size 4.00 MiB
Total PE 2047
Free PE 765
Allocated PE 1282
PV UUID ftOYQo-a19G-0Gs6-01ir-i6M5-Yj1N-TRREDR
[root@server1 ~]# pvdisplay /dev/sdc1
--- Physical volume ---
PV Name /dev/sdc1
VG Name VGNetProg
PV Size 15.00 GiB / not usable 4.00 MiB
Allocatable yes (but full)
PE Size 4.00 MiB
Total PE 3839
Free PE 0
Allocated PE 3839
PV UUID DYW0TD-vXGl-8Ssr-BCcy-SLQQ-mkfi-rvQFVd
[root@server1 ~]# pvdisplay /dev/sdc2
--- Physical volume ---
PV Name /dev/sdc2
VG Name VGNetProg
PV Size <10.00 GiB / not usable 3.00 MiB
Allocatable yes (but full)
PE Size 4.00 MiB
Total PE 2559
Free PE 0
Allocated PE 2559
PV UUID n1snhx-aevL-X5ay-la43-ljlo-83uC-LIkIT7
[root@server1 ~]#

9781587145148_print.indb 131 25/03/21 11:43 am


132 Chapter 3: Linux Storage, Security, and Networks

Example 3-12 shows the vgdisplay command being used to display the volume group
that has been created.

Example 3-12 Displaying Volume Group Details by Using the vgdisplay Command

[root@server1 ~]# vgdisplay VGNetProg


--- Volume group ---
VG Name VGNetProg
System ID
Format lvm2
Metadata Areas 4
Metadata Sequence No 3
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 2
Open LV 0
Max PV 0
Cur PV 4
Act PV 4
VG Size 44.98 GiB
PE Size 4.00 MiB
Total PE 11516
Alloc PE / Size 10240 / 40.00 GiB
Free PE / Size 1276 / 4.98 GiB
VG UUID PSi3RJ-9lkc-lZFE-oCVA-RaXC-HDh5-K0VuV3
[root@server1 ~]#

Example 3-13 shows the lvdisplay command being used to display the logical volumes
that have been created. A logical volume is addressed using its full path in the /dev
directory, as shown in the example.

Example 3-13 Displaying Logical Volume Details by Using the lvdisplay Command

[root@server1 ~]# lvdisplay /dev/VGNetProg/LVNetAutom


--- Logical volume ---
LV Path /dev/VGNetProg/LVNetAutom
LV Name LVNetAutom
VG Name VGNetProg
LV UUID Y09QdN-J8Fw-s3Nb-RB84-bBPs-1USv-tzMfAw
LV Write Access read/write
LV Creation host, time server1, 2018-08-05 21:57:42 +0300
LV Status available
# open 0
LV Size 10.00 GiB

9781587145148_print.indb 132 25/03/21 11:43 am


Linux Storage 133

Current LE 2560
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:2
[root@server1 ~]# lvdisplay /dev/VGNetProg/LVNetDev
--- Logical volume ---
LV Path /dev/VGNetProg/LVNetDev
LV Name LVNetDev
VG Name VGNetProg
LV UUID Z9VRTv-CUe6-uSa8-S821-jGY5-ymKh-zsKfHZ
LV Write Access read/write
LV Creation host, time server1, 2018-08-05 21:58:17 +0300
LV Status available
# open 0
LV Size 30.00 GiB
Current LE 7680
Segments 3
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:3
[root@server1 ~]#

Note that you can issue the pvdisplay, vgdisplay, and lvdisplay commands without any
arguments to display all physical volumes, all volume groups, and all logical volumes,
respectively, that are configured on the system.

To delete a physical volume, volume group, or logical volume, you use the commands
pvremove, vgremove, or lvremove, respectively.

After logical volumes are created, you use the mkfs command to format the LVNetAutom
LV as an ext4 file system and the LVNetDev LV as an xfs file system, as shown in
Example 3-14.

Example 3-14 Creating File Systems on the new Logical Volumes by Using the mkfs
Command

[root@server1 ~]# mkfs -t ext4 /dev/VGNetProg/LVNetAutom


mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks

9781587145148_print.indb 133 25/03/21 11:43 am


134 Chapter 3: Linux Storage, Security, and Networks

655360 inodes, 2621440 blocks


131072 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2151677952
80 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done


Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
[root@server1 ~]# mkfs -t xfs /dev/VGNetProg/LVNetDev
meta-data=/dev/VGNetProg/LVNetDev isize=512 agcount=4, agsize=1966080 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0, sparse=0
data = bsize=4096 blocks=7864320, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=3840, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
[root@server1 ~]#

Finally, in Example 3-15, both logical volumes are mounted, which means they are usable
for storing and retrieving data.

Example 3-15 Mounting Both Logical Volumes by Using the mount Command

[root@server1 ~]# mkdir /Automation


[root@server1 ~]# mkdir /Development
[root@server1 ~]# ls /
Automation dev hd3 lib64 opt root srv usr
bin Development home media proc run sys var
boot etc lib mnt Programming sbin tmp

[root@server1 ~]# mount /dev/VGNetProg/LVNetAutom /Automation


[root@server1 ~]# mount /dev/VGNetProg/LVNetDev /Development/
[root@server1 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 44G 6.7G 38G 16% /
devtmpfs 3.9G 0 3.9G 0% /dev

9781587145148_print.indb 134 25/03/21 11:43 am


Linux Security 135

tmpfs 3.9G 0 3.9G 0% /dev/shm


tmpfs 3.9G 8.8M 3.9G 1% /run
tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup
/dev/sda1 1014M 233M 782M 23% /boot
tmpfs 783M 20K 783M 1% /run/user/1001
/dev/mapper/VGNetProg-LVNetAutom 9.8G 37M 9.2G 1% /Automation
/dev/mapper/VGNetProg-LVNetDev 30G 33M 30G 1% /Development
[root@server1 ~]#

Of course, the mounting done in Example 3-15 is not persistent. To mount both logical
volumes during system boot, two entries need to be added to the /etc/fstab file—one
entry for each LV.

You may have noticed in the output of the df -h command in Example 3-15 that each LV
appears as a subdirectory to the directory /dev/mapper. The device mapper is a kernel
space driver that provides the generic function of creating mappings between different
storage volumes. The term generic is used here because the mapper is not particularly
aware of the constructs used by LVM to implement logical volumes. LVM uses the
device mapper to create the mappings between a volume group and its constituent logical
volumes, without the device mapper explicitly knowing that the latter is a logical volume
(rather than a physical one).

The examples in this section show only the very basic functionality of LVM—that is,
creating the basic building blocks for having and using logical volumes on a system.
However, the real power of LVM becomes clear when you use advanced features such as
increasing or decreasing the size of a logical volume, without having to delete the volume
and re-create it, or the several options for high availability of logical volumes. Red Hat
has a 147-page document titled “Logical Volume Manager Administration” on managing
logical volumes. You can check out the document for RHEL 8 at https://access.redhat.
com/documentation/en-us/red_hat_enterprise_linux/8/html/configuring_and_managing_
logical_volumes/index.

Linux Security
Linux security is a massive and complex topic so it is important to establish the intended
scope of this section early on. The purpose of this section is two-fold. The first purpose
is to familiarize you with basic Linux security operations that would enable you to effec-
tively manage your development environment without being stumped. For example, you
can’t execute a script unless your user on the system has the privileges to execute that
script, based on the script’s file permissions and your group memberships. The second
purpose of this section is to show you how to accomplish a minimal level of hardening
for your development environment. Using an unsecured device to run scripts that access
network devices—and possibly push configuration to those devices—is not a wise thing
to do. Accordingly, this section covers user, group, file, and directory security, including
access control lists. This chapter also covers the Linux firewall.

9781587145148_print.indb 135 25/03/21 11:43 am


136 Chapter 3: Linux Storage, Security, and Networks

User and Group Management


Linux is a multiuser operating system, which means that more than one user can access a
single Linux system at a time.

For a user to access a Linux system, the user’s account must be configured on the system.
The user will then have a username and user ID (UID). A user with an account on the
system is a member of one or more groups. Each group has a group name and a group ID
(GID). By default, when a user is created on the system, a new group is also created; it has
the same name as the username, and this becomes the primary group of the user. A user
typically has a password, and each group also has a password.

Each user has a home directory that contains that user’s files. One way that Linux main-
tains user segregation and security is by maintaining permissions on files and directories
and allowing users with the appropriate authorization level to set those permissions. File
permissions are classified into permissions for the owner of the file, the group of the file,
and everyone else. The root user and any other user with root privileges can access all
resources on the system, including other users’ files and directories. The root user and
users with root privileges are members of a group named wheel.

You can find user information by using the command id {username}, as shown in
Example 3-16 for user NetProg.

Example 3-16 Getting User Information by Using the id Command

[root@localhost ~]# id NetProg


uid=1001(NetProg) gid=1002(NetProg) groups=1002(NetProg),10(wheel)
[root@localhost ~]#

User NetProg’s UID is 1001. The output in Example 3-16 shows that the user’s default
(primary) group has the same name as the username. User NetProg in the example is also
a member of the wheel group and therefore has root privileges that can be invoked by
using the sudo {command} command, where command requires root privileges to be
executed. The number to the left of each group name is the group ID.
User information is also stored in the /etc/passwd file, and group information is stored in
the /etc/group file. Hashed user passwords are stored in the file /etc/shadow, and hashed
group passwords are stored in the file /etc/gshadow. Example 3-17 displays the last five
entries of each of the files.

Example 3-17 Last Five Entries from the /etc/passwd, /etc/group, /etc/shadow, and /etc/
gshadow Files

! Sample entries from the /etc/passwd file


[netdev@server1 ~]$ tail -n 5 /etc/passwd
netdev:x:1000:1000:Network Developer:/home/netdev:/bin/bash
vboxadd:x:970:1::/var/run/vboxadd:/bin/false
cockpit-wsinstance:x:969:969:User for cockpit-ws instances:/nonexisting:/sbin/
nologin

9781587145148_print.indb 136 25/03/21 11:43 am


Linux Security 137

flatpak:x:968:968:User for flatpak system helper:/:/sbin/nologin


rngd:x:967:967:Random Number Generator Daemon:/var/lib/rngd:/sbin/nologin
[netdev@server1 ~]$

! Sample entries from the /etc/group file


[netdev@server1 ~]$ tail -n 5 /etc/group
netdev:x:1000:
vboxsf:x:970:
cockpit-wsinstance:x:969:
flatpak:x:968:
rngd:x:967
[netdev@server1 ~]$

! file /etc/shadow requires root privileges to be read


[netdev@server1 ~]$ tail -n 5 /etc/shadow
tail: cannot open '/etc/shadow' for reading: Permission denied
[netdev@server1 ~]$

! Sample entries from the /etc/shadow file


[netdev@server1 ~]$ sudo tail -n 5 /etc/shadow
[sudo] password for netdev:
netdev:$6$.JUG9NvdC/NzqiYq$zpCkMR3eENFgk906PjFVLJ526qFRI9L2n13rFApiyPS0lgb2F1CTjJvc1
dqvvE3XV91q2fK.p3hvlEYtKciD2.:18489:0:99999:7:::
vboxadd:!!:18473::::::
cockpit-wsinstance:!!:18473::::::
flatpak:!!:18473::::::
rngd:!!:18473::::::
[netdev@server1 ~]$

! file /etc/gshadow requires root privileges to be read


[netdev@server1 ~]$ tail -n 5 /etc/gshadow
tail: cannot open '/etc/gshadow' for reading: Permission denied
[netdev@server1 ~]$

! Sample entries from the /etc/gshadow file


[netdev@server1 ~]$ sudo tail -n 5 /etc/gshadow
netdev:!::
vboxsf:!::
cockpit-wsinstance:!::
flatpak:!::
rngd:!::
[netdev@server1 ~]$

9781587145148_print.indb 137 25/03/21 11:43 am


138 Chapter 3: Linux Storage, Security, and Networks

Each line in the /etc/passwd file is a record containing the information for one user
account. Each record is formatted as follows: username:x:user_id:primary_group_
id:user_extra_information:user_home_directory:user_default_shell.
The /etc/passwd and /etc/group files can be read by any user on the system but can only
be edited by a user with root privileges. For this reason, as a security measure, the sec-
ond field in the record, which historically contained the user password hash, now shows
only the letter x. The user password hashes are now maintained in the /etc/shadow file,
which can only be read by users with root privileges. The same arrangement is true for
the /etc/group and the /etc/gshadow files. Whenever a user does not have a password, the
x is omitted. Two consecutive colons in any record indicate missing information for the
respective field.

Each line in the /etc/group file is a record containing information for one group. Each
record is formatted as follows: groupname:x:group_id:group_members. The last field
is a comma-separated list of non-default users in the group. For example, the record for
the netdev group shows all users who are members of the group netdev except the user
netdev itself.

Each line in the /etc/shadow file is a record containing the password information for one
user. Each record is formatted as follows: username:password_hash:last_changed:min:
max:warn:expired:disabled:reserved.

The field last_changed is the number of days between January 1, 1970, and the date the
password was last changed. The field min is the minimum number of days to wait before
the password can be changed. The value 0 indicates that it may be changed at any time.
The field max is the number of days after which the password must be changed. The
value 99999 means that the user can keep the same password practically forever. The
field warn is the number of days to send a warning to the user prior to the password
expiring. The field expired is the number of days after the password expires before the
account should be disabled. The field disabled is the number of days since January 1,
1970, that an account has been disabled. The last field is reserved.

Finally, each line in the /etc/gshadow file is a record that contains the password informa-
tion for one group. Each record is formatted as follows: groupname:group_password_
hash:group_admins:group_members. The group_password_hash field contains an
exclamation symbol (!) if no user is allowed to access the group by using the newgrp
command. (This command is covered later in this section.)

You use the command useradd {username} to create a new user, and the command
passwd {username} to set or change the password for a user. After switching to user root
by using the su command in Example 3-18, the id NetDev command is used to verify
that user NetDev does not already exist. The new user NetDev is then created by issuing
the command useradd NetDev.

Next, the example shows the su command being used to attempt to log in as user
NetDev. Notice that although a password was requested, no password will actually work.
This is because, by default, when a new user is created, a password entry is created in

9781587145148_print.indb 138 25/03/21 11:43 am


Linux Security 139

the /etc/shadow file, but until this password is actually set by using the passwd com-
mand, you cannot log in as the user because the default password hash in the shadow file
is an invalid hash. The example shows the password being removed altogether with the
command passwd -d NetDev. Only at this point are you able to log in without getting a
password prompt. The password is then set using the command passwd NetDev, and a
warning is displayed because the password entered was Cisco123. Once the password is
set, it is possible to log in as the user in question. Note that creating a user also creates a
home directory—in this case /home/NetDev—as shown in the output of the pwd com-
mand. The files /etc/passwd, /etc/group, and /etc/shadow are also updated to reflect the
new user details, as shown in the example.

Example 3-18 Creating a New User and Setting the Password

[NetProg@localhost ~]$ su -
Password:
Last login: Sun Apr 15 14:26:29 +03 2018 on pts/1
[root@localhost ~]#

! Verify whether the user NetDev exists


[root@localhost ~]# id NetDev
id: NetDev: no such user
[root@localhost ~]#

! Add user NetDev and log in to it


[root@localhost ~]# useradd NetDev
[root@localhost ~]# exit
Logout
[NetProg@localhost ~]$

! Authentication will fail due to invalid "default" hash


[NetProg@localhost ~]$ su NetDev
Password:
su: Authentication failure
[NetProg@localhost ~]$

! Switch back to user root and remove the password


[NetProg@localhost ~]$ su -
Password:
Last login: Sun Apr 15 14:27:07 +03 2018 on pts/1
[root@localhost ~]# passwd -d NetDev
Removing password for user NetDev.
passwd: Success
[root@localhost ~]# exit
logout

9781587145148_print.indb 139 25/03/21 11:43 am


140 Chapter 3: Linux Storage, Security, and Networks

[NetProg@localhost ~]$ su NetDev


[NetDev@localhost NetProg]$ exit
Exit
[NetProg@localhost ~]$

! Switch to user root and set the password manually then test
[NetProg@localhost ~]$ su -
Password:
Last login: Sun Apr 15 14:28:12 +03 2018 on pts/1
[root@localhost ~]# passwd NetDev
Changing password for user NetDev.
New password:
BAD PASSWORD: The password fails the dictionary check - it is based on a dictionary
word
Retype new password:
passwd: all authentication tokens updated successfully.
[root@localhost ~]# exit
logout
[NetProg@localhost ~]$ su NetDev
Password:
[NetDev@localhost NetProg]$

! Check the home directory and other details for user NetDev
[NetDev@localhost NetProg]$ cd
[NetDev@localhost ~]$ pwd
/home/NetDev
[NetDev@localhost ~]$ id NetDev
uid=1002(NetDev) gid=1003(NetDev) groups=1003(NetDev)
[NetDev@localhost ~]$ tail -n 1 /etc/passwd
NetDev:x:1002:1003::/home/NetDev:/bin/bash
[NetDev@localhost ~]$ tail -n 1 /etc/group
NetDev:x:1003:
[NetDev@localhost ~]$

! Switch to user root and check file /etc/shadow


[NetDev@localhost ~]$ su -
Password:
Last login: Sun Apr 15 14:50:37 +03 2018 on pts/0
[root@localhost ~]# tail -n 1 /etc/shadow
NetDev:$6$y27JA0id$i8Wze1ShSptxy5wRS8f7fOkPeeAezo2cayDl/
sqikRkYp2VseEXNrzwqDQXqvMeAqzMs2Jd./jj5fm05PK.Wi/:17636:0:99999:7:::
[root@localhost ~]# exit
logout
[NetDev@localhost ~]$

9781587145148_print.indb 140 25/03/21 11:43 am


Linux Security 141

A user can change her own password by simply typing passwd without any arguments.
The user is then prompted to enter the current password and then the new password and
then to confirm the new password.

To delete a user, you use the command userdel {username}. This command deletes the
user from the system; to delete that user’s home directory and print spool as well, you
use the option -r with the command. You use the option -f to force the delete action even
if the user is still logged in.

You can add groups separately from users by using the command groupadd {group_
name}. You can use the option -g to set the GID manually instead of allowing automatic
assignment of the next available GID. You delete groups by using the command groupdel
{group_name}. Example 3-19 shows how to create a new group called engineers and set
its GID to 1111.

Example 3-19 Creating a New Group engineers

[root@localhost ~]# tail -n 2 /etc/group


NetProg:x:1002:
NetDev:x:1003:
[root@localhost ~]# groupadd -g 1111 engineers
[root@localhost ~]# tail -n 3 /etc/group
NetProg:x:1002:
NetDev:x:1003:
engineers:x:1111:
[root@localhost ~]#

To delete a group, you use the command groupdel {group_name}. You change a group’s
details by using the command groupmod. The command groupmod -g {new_gid} {group_
name} changes the group gid to new_gid, and the command groupmod -n {new_name}
{old_name} changes the group’s name from old_name to new_name. Finally, you change
the group password by using the command gpasswd {group_name}. In Example 3-20,
the group engineers is changed to NetDevOps, and its GID is changed to 2222. Then its
password is modified to Cisco123.

Example 3-20 Modifying Group Details

[root@localhost ~]# tail -n -1 /etc/group


engineers:x:1111:
[root@localhost ~]#

! Change the group name to NetDevOps


[root@localhost ~]# groupmod -n NetDevOps engineers
[root@localhost ~]# tail -n -1 /etc/group
NetDevOps:x:1111:
[root@localhost ~]#

9781587145148_print.indb 141 25/03/21 11:43 am


142 Chapter 3: Linux Storage, Security, and Networks

! Change the gid to 2222


[root@localhost ~]# groupmod -g 2222 NetDevOps
[root@localhost ~]# tail -n -1 /etc/group
NetDevOps:x:2222:
[root@localhost ~]#

! Change the group password to Cisco123


[root@localhost ~]# gpasswd NetDevOps
Changing the password for group NetDevOps
New Password:
Re-enter new password:
[root@localhost ~]#

A user has one primary group and one or more secondary groups. A user’s primary group
is the group that the user is placed in when logging in. You modify user group member-
ship by using the command usermod. To change a user’s primary group, you use the
syntax usermod -g {primary_group} {username}. To change a user’s secondary group,
you use the syntax usermod -G {secondary_group} {username}; note that this command
removes all secondary group memberships for this user and adds the group secondary_
group specified in the command. To add a user to a secondary group while maintaining
his current group memberships, you use the syntax usermod -aG {new_secondary_
group} {username}. To lock a user account, you use the option -L with the usermod
command, and to unlock an account, you use the -U option with this command.
Example 3-21 shows how to change the primary group of user NetDev from NetDev to
NetOps and add the wheel group to the list of secondary groups to give the user root
privileges through the sudo command.

Example 3-21 Modifying User Details

[root@localhost ~]# id NetDev


uid=1002(NetDev) gid=1003(NetDev) groups=1003(NetDev)
[root@localhost ~]# usermod -g NetOps NetDev
[root@localhost ~]# id NetDev
uid=1002(NetDev) gid=2222(NetOps) groups=2222(NetOps)
[root@localhost ~]# usermod -aG wheel NetDev
[root@localhost ~]# id NetDev
uid=1002(NetDev) gid=2222(NetOps) groups=2222(NetOps),10(wheel)
[root@localhost ~]#

Notice that when the -g option is used to change the primary group, the secondary
group is also changed. This is because user NetDev was only a member of a single group,
NetDev, and that group was both the user’s primary group and secondary group. When
the primary and secondary groups are different, the -g option changes only the primary
group of the user.

9781587145148_print.indb 142 25/03/21 11:43 am


Linux Security 143

File Security Management


Chapter 2 describes the output of the ls -l command and introduces file permissions,
also known as the file mode bits. This section builds on that introduction and expands on
how to manage access to files and directories by modifying their permissions. It also dis-
cusses changing the file owner (user) and group. Keep in mind that in Linux, everything
is represented by a file. Therefore, the concepts discussed here have a wider scope than
what seems to be obvious. Also, whenever a reference is made to a file, the same concept
applies to a directory, unless explicitly stated otherwise.

Example 3-22 shows the output of ls -l for the NetProg home directory.

Example 3-22 Output of the ls -l Command

[NetProg@localhost ~]$ ls -l
total 0
drwxr-xr-x. 2 NetProg NetProg 40 Apr 9 09:41 Desktop
drwxr-xr-x. 2 NetProg NetProg 6 Mar 31 17:34 Documents
drwxr-xr-x. 2 NetProg NetProg 6 Mar 31 17:34 Downloads
drwxr-xr-x. 2 NetProg NetProg 6 Mar 31 17:34 Music
drwxr-xr-x. 2 NetProg NetProg 6 Mar 31 17:34 Pictures
drwxr-xr-x. 2 NetProg NetProg 6 Mar 31 17:34 Public
drwxrwxr-x. 2 NetProg NetProg 183 Apr 7 22:53 Scripts
drwxr-xr-x. 2 NetProg NetProg 6 Mar 31 17:34 Templates
-rw-rw-r--. 1 NetProg NetProg 0 Apr 9 17:51 Testfile.txt
drwxr-xr-x. 2 NetProg NetProg 6 Mar 31 17:34 Videos
[NetProg@localhost ~]$

Here is a quick recap on the file permissions: The very first bit indicates whether this is
a file (-), a directory (d), or a link (l). Then the following 3 bits define the permissions for
the file owner. By default, the owner is the user who created the file. The following 3 bits
define the permissions for the users who are members of the file group. By default, this is
the primary group of the user who created the file. The last 3 bits define the permissions
for everyone else, referred to as other. The letter r stands for read permission, w for write
permission, and x for execute permission.

The dot right after the mode bits indicates that this file has an SELinux context. SELinux
is a kernel security module that defines the access rights of every user, application,
process, and file on the system. SELinux then governs the interactions of these entities
using a security policy, where an entity referred to as a subject attempts to access another
entity referred to as an object. SELinux is an important component of Linux security but
is beyond the scope of this book. When a file or a directory has a + symbol in place of
the dot (.), it means the file has an access control list (ACL) applied to it. ACLs, which
are covered later in this chapter, provide more granular access control to files on a
per-user basis.

9781587145148_print.indb 143 25/03/21 11:43 am


144 Chapter 3: Linux Storage, Security, and Networks

The output of the ls -l command also displays the file owner (more formally referred to as
user) and the file group.

File permissions can be represented (and modified) by either using symbolic notation or
octal notation.

Symbolic notation is the type of notation described so far, where user, group, and others
are represented by u, g, and o, respectively, and the access permissions are write, read,
and execute, represented by w, r, and x, respectively. The following syntax is used to
set the file permissions: chmod [u={permissions}][,g={permissions}][,o={permissions}]
{file_name}.

Example 3-23 shows how to modify the file permissions for file TestFile.txt to the
following:

■■ User: Read, write, and execute

■■ Group: Read and write

■■ Other: No access

Example 3-23 Setting File Permissions by Using Symbolic Notation

! Current file permissions


[NetProg@localhost ~]$ ls -l Testfile.txt
-rw-rw-r--. 1 NetProg NetProg 0 Apr 9 17:51 Testfile.txt
[NetProg@localhost ~]$

! Change the file permissions as listed


[NetProg@localhost ~]$ chmod u=rwx,g=rw,o= Testfile.txt

! New file permissions


[NetProg@localhost ~]$ ls -l Testfile.txt
-rwxrw----. 1 NetProg NetProg 0 Apr 9 17:51 Testfile.txt
[NetProg@localhost ~]$

Notice that in order to remove all permissions for one of the categories, you just leave the
right side of the = symbol blank.

One of the challenges with the symbolic notation syntax as used in Example 3-23 is that
you have to know beforehand what permissions the file already has and make sure to
align the current permissions with the new permissions you are trying to set. For exam-
ple, if a file already has read and write permissions set for the file group and you would
like to add the execute permission, you have to know this fact prior to the change, and
then you need to make sure you do not delete the already existing write or read permis-
sions while setting the execute permission. In order to just add or remove permissions for

9781587145148_print.indb 144 25/03/21 11:43 am


Linux Security 145

a specific category, without explicitly knowing or considering the existing permissions,


you replace the = symbol in the previous syntax with either a + or a - symbol, as follows:
chmod [u[+|-]{permissions}][,g[+|-]{permissions}][,o[+|-]{permissions}] {file_name}.
In Example 3-24 the permissions for the file TestFile.txt are modified as follows:

■■ User: Unchanged

■■ Group: Write permission removed and execute permission added

■■ Other: Execute permission added

Notice that when using this syntax, you do not need to know what permissions the file
already has. You only need to consider the changes that you want to implement.

Example 3-24 Adding and Removing File Permissions by Using Symbolic Notation

[NetProg@localhost ~]$ ls -l Testfile.txt


-rwxrw----. 1 NetProg NetProg 0 Apr 9 17:51 Testfile.txt
[NetProg@localhost ~]$ chmod g-w,g+x,o+x Testfile.txt
[NetProg@localhost ~]$ ls -l Testfile.txt
-rwxr-x--x. 1 NetProg NetProg 0 Apr 9 17:51 Testfile.txt
[NetProg@localhost ~]$

Notice that you can mix the + and - symbols in the same command and for the same
category, as shown in Example 3-24 for the file group, where g-w is used to remove the
write permission for the group, and g+x is used to add the execute permission for
the group.

When a certain permission has to be granted or revoked from all categories, the letter a
is used to collectively mean u, g, and o. The letter a in this case stands for all. The letter a
may be dropped altogether, and the command then applies to all categories. For example,
the command chmod +w Example.py adds the write permission to all categories for the
file Example.py.

Octal notation, on the other hand, uses the following syntax: chmod {user_permission}
{group_permission}{other_permission} {file_name}. The user, group, and other catego-
ries are represented by their positions in the command. The permission granted to each
category is represented as a numeric value that is equal to the summation of each permis-
sion’s individual value. To elaborate, note the following permission values:

■■ Read=4

■■ Write=2

■■ Execute=1

9781587145148_print.indb 145 25/03/21 11:43 am


146 Chapter 3: Linux Storage, Security, and Networks

To set the read permission only, you need to use the value 4; for write permission only,
you use the value 2; and for execute permission only, you use the value 1. To set all per-
missions for any category, you need to use 4+2+1=7. To set the read and write permis-
sions only, you need to use 4+2=6, and so forth. Example 3-25 illustrates this concept
and uses octal notation to set the read, write, and execute permissions for both user and
group, and set only the execute permission for the category other for file Testfile.txt.

Example 3-25 Setting File Permissions Using Octal Notation

[NetProg@localhost ~]$ ls -l Testfile.txt


-rwxr-x--x. 1 NetProg NetProg 0 Apr 9 17:51 Testfile.txt
[NetProg@localhost ~]$ chmod 771 Testfile.txt
[NetProg@localhost ~]$ ls -l Testfile.txt
-rwxrwx--x. 1 NetProg NetProg 0 Apr 9 17:51 Testfile.txt
[NetProg@localhost ~]$

The number 7 in each of the first two positions in the command chmod 771 Testfile.txt
represents the sum of 4, 2, and 1 and is used to set all permissions for user and group.
The number 1 in the last position sets the execute only permission for other.

While octal notation looks snappier than symbolic notation, it does not provide the
option of adding or removing permissions without considering the existing file permis-
sions, as provided by the + and - symbols used with symbolic notation.

Besides modifying file and directory permissions, you can control access to a file or
directory by changing the file’s user and/or group through the chown command. The
command syntax is chown {user}:{group} {file}. Example 3-26 shows how to change the
user and group of file TestFile.txt to NetDev and networks, respectively.

Example 3-26 Changing File User and Group by Using the chown Command

[root@localhost ~]# ls -l /home/NetProg/Testfile.txt


-rwxrwx--x. 1 NetProg NetProg 0 Apr 9 17:51 /home/NetProg/Testfile.txt
[root@localhost ~]# chown NetDev:networks /home/NetProg/Testfile.txt
[root@localhost ~]# ls -l /home/NetProg/Testfile.txt
-rwxrwx--x. 1 NetDev networks 0 Apr 9 17:51 /home/NetProg/Testfile.txt
[root@localhost ~]#

You use the -R option (which stands for recursive) with both the chmod and the chown
commands if the operation is being performed on a directory, and you want the changes
to also be made to all subdirectories and files in that directory.

By default, any file or directory created by a user is assigned to the primary group of
that user. For example, if user NetDev is in the NetOps group, any file created by user
NetDev has NetDev as the file user and NetOps as the file group. You can change this

9781587145148_print.indb 146 25/03/21 11:43 am


Linux Security 147

default behavior by either using the sg command when creating the file or by logging in
to another group by using the command newgrp. If that other group is one of the user’s
secondary groups, no password is required. If that other group is not one of the user’s
secondary groups, the user is prompted for a password.

Example 3-27 shows the default behavior when creating a file. In this case, a new file
named NewFile is created by user NetDev. As expected, the file user is NetDev, and the
file group is NetOps.

Example 3-27 Default User and Group of a Newly Created File

[NetDev@localhost ~]$ id NetDev


uid=1002(NetDev) gid=2222(NetOps) groups=2222(NetOps),10(wheel)
[NetDev@localhost ~]$ touch NewFile
[NetDev@localhost ~]$ ls -l NewFile
-rw-r--r--. 1 NetDev NetOps 0 Apr 17 00:59 NewFile
[NetDev@localhost ~]$

Example 3-28 shows how to use the sg command to create file NewFile_1 but under the
group networks.

Example 3-28 Using the sg Command to Create a File Under a Different Group

[NetDev@localhost ~]$ id NetDev


uid=1002(NetDev) gid=2222(NetOps) groups=2222(NetOps),10(wheel)
[NetDev@localhost ~]$ sg networks 'touch NewFile_1'
Password:
[NetDev@localhost ~]$ ls -l NewFile_1
-rw-r--r--. 1 NetDev networks 0 Apr 17 01:03 NewFile_1
[NetDev@localhost ~]$

Notice that the command touch {file_name}, which itself is an argument to the sg com-
mand, has to be enclosed in quotes because it is a multi-word command. Notice also that
because the user NetDev is not a member in the networks group, as you can see from the
output of the id command, the user is prompted for the group password, which was set
earlier by using the command gpasswd networks.

Alternatively, the user can log in to another group by using the command newgrp and
create a file or directory under that group. Example 3-29 shows the user NetProg logging
in to group systems and not being prompted for a password since this is one of NetProg’s
secondary groups. When the file NewFile_2 is created, the user of the file is NetProg,
and the group is systems, not NetProg.

9781587145148_print.indb 147 25/03/21 11:43 am


148 Chapter 3: Linux Storage, Security, and Networks

Example 3-29 Using the newgrp Command to Log In to a Different Group

[NetProg@localhost ~]$ id NetProg


uid=1001(NetProg) gid=1002(NetProg) groups=1002(NetProg),10(wheel),2224(systems)
[NetProg@localhost ~]$ newgrp systems
[NetProg@localhost ~]$ touch NewFile_2
[NetProg@localhost ~]$ ls -l NewFile_2
-rw-r--r--. 1 NetProg systems 0 Apr 17 01:15 NewFile_2
[NetProg@localhost ~]$

Access Control Lists


So far in this chapter, you have seen how to set file and directory access permissions for
either user, or collectively for group, or other. What if you want to set those permissions
individually for a specific user who is not the file owner or for a group of users who
belong to a group other than the file group? File mode bits do not help in such situations.
Using the file mode bits, the only user whose permissions can be changed individually is
the file or directory owner (user) and the only group of users whose permissions can be
changed collectively are the users who are members of the file or directory group.

Access control lists (ACLs) provide more granular control over file and directory access.
ACLs allow a system administrator (or any other user who has root privileges) to set file
and directory permissions for any user or group on the system.

Before you can configure ACLs, three prerequisites must be met:

■■ The kernel must support ACLs for the file system type on which ACLs will be
applied.

■■ The file system on which ACLs will be used must be mounted with the ACL option.

■■ The ACL package must be installed.

Most common distros today—including CentOS 7 and Red Hat Enterprise Linux
(RHEL) 7 and later versions—have these prerequisites configured by default, and you
do not need to do any further configuration.

If you are running a different distro or an older version of CentOS, you can check the
first prerequisite by using either the findmnt or blkid command to determine the file sys-
tem type on your system. The command findmnt works only if the file system has been
mounted, and blkid works whether it is mounted or not. Then you need to inspect the
kernel configuration file /boot/conf-<version.architecture> to determine whether ACLs
have been enabled for this file system type. Example 3-30 shows the relevant output for
the file system on the sda1 partition.

9781587145148_print.indb 148 25/03/21 11:43 am


Linux Security 149

Example 3-30 ACL Support for the sda1 File System

[root@server1 ~]# findmnt /dev/sda1


TARGET SOURCE FSTYPE OPTIONS
/boot /dev/sda1 xfs rw,relatime,seclabel,attr2,inode64,noquota
[root@server1 ~]# cat /boot/config-3.10.0-693.el7.x86_64 | grep ACL
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_XFS_POSIX_ACL=y
CONFIG_BTRFS_FS_POSIX_ACL=y
CONFIG_FS_POSIX_ACL=y
CONFIG_GENERIC_ACL=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFSD_V2_ACL=y
CONFIG_NFSD_V3_ACL=y
CONFIG_NFS_ACL_SUPPORT=m
CONFIG_CEPH_FS_POSIX_ACL=y
CONFIG_CIFS_ACL=y
[root@server1 ~]#

The kernel configuration file lists different configuration options, each followed by an
= symbol and then the letter y, n, or m. The letter y means that this option (module) was
configured as part of the kernel when the kernel was first compiled. In this example,
CONFIG_XFS_POSIX_ACL=y means that the kernel supports ACLs for the xfs file
system. The letter n indicates that this module was not compiled into the kernel, and the
letter m means that this module was compiled as a loadable kernel module (introduced in
Chapter 2).

The second prerequisite is that the partition on which the ACLs will be used has to be
mounted with the ACL option. By default, on ext3/4 and xfs file systems, ACL support is
enabled. In older CentOS versions and other distros where the ACL option is not enabled
by default, the file system can be mounted with the ACL option by using the syntax
mount -o acl {partition} {mount_point}. On the other hand, if the ACL option is enabled
by default, and you want to disable ACL support while mounting the file system, you can
use the noacl option with the mount command. As discussed in the previous section,
mounting using the mount command is non-persistent. For persistent mounting with the
ACL option, you can add an entry to the /dev/fstab file (or amend an existing entry) and
add the acl option (right after the defaults keyword). The /dev/fstab file is discussed in
detail earlier in this chapter.

Finally, by using the yum info acl command, you can confirm whether the ACL package
has been installed. The yum command is covered in detail in Chapter 2.

When ACL support has been established, you can use the command getfacl {filename|
directory} to display the ACL configuration for a file or directory. Example 3-31 shows
the output of the getfacl command for the directory /Programming and then for the file
NewFile.txt.

9781587145148_print.indb 149 25/03/21 11:43 am


150 Chapter 3: Linux Storage, Security, and Networks

Example 3-31 Output of the getfacl Command

[root@localhost /]# ls -ld Programming


drwxr-xr-x. 2 root root 25 Jun 9 05:46 Programming
[root@localhost /]# ls -l Programming
total 0
-rw-r--r--. 1 root root 0 Jun 9 05:46 NewFile.txt
[root@localhost /]# getfacl Programming
# file: Programming
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
[root@localhost /]# getfacl Programming/NewFile.txt
# file: Programming/NewFile.txt
# owner: root
# group: root
user::rw-
group::r--
other::r—
[root@localhost /]#

As you can see from the output in Example 3-31, both the directory and file are owned
by the user root, and the group of both is also root. So far, there is no additional infor-
mation provided by the getfacl command beyond what is already displayed by ls -l; the
format is the only difference.

For the file NewFile.txt, the user NetProg is not the file owner and is not a member of
the file group. As per the permissions for other, the user NetProg should be able to only
read the file but not write to it or execute it. In Example 3-32, the user NetProg attempts
to write to the file NewFile.txt by using the echo command, but a “Permission denied”
error message is displayed. The setfacl -m u:NetProg:rw /Programming/Newfile.txt
command grants write permission to the user NetProg. When the write operation is
attempted again, it is successful due to the new elevated permissions.

Example 3-32 Changing the Permissions for the User NetProg by Using setfacl

! Echo(write) operation fails since NetProg has no write permissions


[NetProg@localhost /]$ echo "This is a write test" > /Programming/NewFile.txt
bash: /Programming/NewFile.txt: Permission denied

! Grant user NetProg write permission (requires root permissions)


[NetProg@localhost /]$ su
Password:

9781587145148_print.indb 150 25/03/21 11:43 am


Linux Security 151

[root@localhost /]# setfacl -m u:NetProg:rw /Programming/NewFile.txt


[root@localhost /]# getfacl /Programming/NewFile.txt
getfacl: Removing leading '/' from absolute path names
# file: Programming/NewFile.txt
# owner: root
# group: root
user::rw-
user:NetProg:rw-
group::r--
mask::rw-
other::r--

! Write operation now successful


[root@localhost /]# su NetProg
[NetProg@localhost /]$ echo "This is a write test" > /Programming/NewFile.txt
[NetProg@localhost /]$ cat /Programming/NewFile.txt
This is a write test
[NetProg@localhost /]$ ls -l /Programming/NewFile.txt
-rw-rw-r--+ 1 root root 21 Jun 9 07:24 /Programming/NewFile.txt
[NetProg@localhost /]$

Notice the + symbol that now replaces the dot to the right of file permission bits at the
end of Example 3-32. This indicates that an ACL has been applied to this file. The new
write permission has been granted to the user NetProg only, and not to any other user.
This was done without amending the file permissions for the user, group, or other cat-
egories. It was also done without modifying the group memberships of the user NetProg.
The same permission could also be applied to a group instead of an individual user. The
level of granularity provided by ACLs should be clear by now.

The setfacl command used in Example 3-32 was issued with the option -m, which is
short for modify and is used to apply a new ACL or modify an existing ACL. To remove
an ACL, you use the option -x instead of -m; the remainder of the command remains the
same, except that the ACL in the command is an existing ACL that is now being removed.

In Example 3-32 you can see the three-field argument u:NetProg:rw. When setting an
ACL for a user, the first field is u, as in the example. For a group, the first field would be
g, and for other, the first field would be o. The second field is the user or group name,
which is NetProg in this example. If the ACL is for other, this field remains empty. The
third field is the permissions you wish to grant to the user or group.

Finally, after the three-field argument is the name of the directory or file to which the
ACL is applied. Note that whether a full path or only a relative path is required depends
on the current working directory relative to the location of the file or directory to which
the ACL is being applied. The same rules apply here as with any other Linux command
that operates on a file or directory.

9781587145148_print.indb 151 25/03/21 11:43 am


152 Chapter 3: Linux Storage, Security, and Networks

Therefore, the general syntax of the setfacl command to add, modify, or remove an ACL
is setfacl {-m|-x} {u|g|o}:{username|group}:{permissions} {file|directory}. To remove all
ACL entries applied to a file, you use the option -b followed by the filename, omitting
the three-field argument.

In Example 3-32, notice the text mask::rw- in the output of the getfacl command, after
the ACL has been applied. The mask provides one more level of control over the permis-
sions granted by the ACL. Say that after granting several users different permissions to
a file, you decide to remove a specific permission, such as the write permission, from all
named users. The ACL mask then comes in handy. The permissions in the mask override
the permissions for all named users and the file group. For example, if the mask permis-
sions are r-x and the user NetProg has been granted rwx permissions, that user’s effective
permissions are r-x after the mask is set. The effective mask permissions are applied using
the command setfacl -m m:{permissions} {filename}. In Example 3-33, the user NetProg
has permissions rw-, and so does the mask. The mask is modified to r--. Notice the effec-
tive permissions that appear on the right side of the output of the getfacl command
after the mask has been modified. After you remove the write permission from the mask,
NetProg’s write attempt to the file fails.

Example 3-33 Changing the Mask Permissions by Using setfacl

! Set the effective rights mask


[root@localhost /]# setfacl -m m:r /Programming/NewFile.txt
[root@localhost /]# getfacl /Programming/NewFile.txt
getfacl: Removing leading '/' from absolute path names
# file: Programming/NewFile.txt
# owner: root
# group: root
user::rw-
user:NetProg:rw- #effective:r--
group::r--
mask::r--
other::r--

! Write operation to file by user NetProg now fails


[root@localhost /]# su NetProg
[NetProg@localhost /]$ echo "Testing mask permissions" > /Programming/NewFile.txt
bash: /Programming/NewFile.txt: Permission denied
[NetProg@localhost /]$

When ACLs are applied to directories, by default, these ACLs are not inherited by files
and subdirectories in that directory. In order to achieve inheritance, the option -R has to

9781587145148_print.indb 152 25/03/21 11:43 am


Linux Security 153

be added to the same setfacl command used earlier. In Example 3-34, an ACL setting rwx
permissions for the user NetProg is applied to the directory Programming. Attempting to
write to file NewFile.txt under the directory by user NetProg fails because the write per-
mission has not been inherited by the file.

Example 3-34 ACLs Are Not Inherited by Default by Subdirectories and Files Under a
Directory

! Apply an acl to the /Programming directory


[root@localhost ~]# setfacl -m u:NetProg:rwx /Programming
[root@localhost ~]# getfacl /Programming
getfacl: Removing leading '/' from absolute path names
# file: Programming
# owner: root
# group: root
user::rwx
user:NetProg:rwx
group::r-x
mask::rwx
other::r-x

! The acl is not applied to NewFile.txt under the directory


[root@localhost ~]# getfacl /Programming/NewFile.txt
getfacl: Removing leading '/' from absolute path names
# file: Programming/NewFile.txt
# owner: root
# group: root
user::rw-
group::r--
other::r--

! And the write operation fails as expected


[root@localhost ~]# su - NetProg
[NetProg@localhost ~]$ echo "This is a write test" > /Programming/NewFile.txt
bash: /Programming/NewFile.txt: Permission denied
[NetProg@localhost ~]$

After the ACL has been removed and then reapplied in Example 3-35 using the -R option,
the user NetProg can write to the file successfully. The getfacl command also shows that
the ACL has been applied to the file as if the setfacl command had been applied to the
file directly.

9781587145148_print.indb 153 25/03/21 11:43 am


154 Chapter 3: Linux Storage, Security, and Networks

Example 3-35 ACL Inheritance by Subdirectories and Files Under a Directory Using
the -R Option

! Clear the acl from the /Programming directory


[root@localhost ~]# setfacl -b /Programming

! Apply the acl to directory /Programming using the -R option


[root@localhost ~]# setfacl -R -m u:NetProg:rwx /Programming
[root@localhost ~]# getfacl /Programming
getfacl: Removing leading '/' from absolute path names
# file: Programming
# owner: root
# group: root
user::rwx
user:NetProg:rwx
group::r-x
mask::rwx
other::r-x

! The acl is inherited by the file NewFile.txt


[root@localhost ~]# getfacl /Programming/NewFile.txt
getfacl: Removing leading '/' from absolute path names
# file: Programming/NewFile.txt
# owner: root
# group: root
user::rw-
user:NetProg:rwx
group::r--
mask::rw-
other::r--

! And the write operation is successful


[root@localhost ~]# su - NetProg
[NetProg@localhost ~]$ echo "This is to test inheritance" > /Programming/NewFile.txt
[NetProg@localhost ~]$ cat /Programming/NewFile.txt
This is to test inheritance
[NetProg@localhost ~]$

It is important to remember that the ACL applied to a directory and inherited by all
subdirectories and files will not be applied to any files created after the ACL has been
applied. Only the files that existed before the ACL was applied will be affected.

The ACLs described so far are called access ACLs. Another type of ACLs, called default
ACLs, may be used with directories (only) if the requirement is that all files and subdirec-
tories, when created, should inherit the parent directory ACLs. The syntax for applying a
default ACL is setfacl -m d:{u|g|o}:{username|group}:{permissions} {directory}. Try to

9781587145148_print.indb 154 25/03/21 11:43 am


Linux Security 155

experiment with default ACLs and note how newly created files inherit the directory
ACL without your having to explicitly issue the setfacl command after the file or subdi-
rectory has been created.
The same concepts discussed previously for a single user apply to a group when you set
the ACL for a group of users other than the file or directory group by using the letter g
along with the group name in the setfacl command instead of a u with the username.

In addition to using the setfacl command to set permissions for a specific user or group,
you can use this command to set permissions for the file user, group, or other categories,
similar to what can be accomplished using the chmod command as shown in the previous
section. Note that if the setfacl command is used to apply an ACL to a file or directory, it
is recommended that you not use chmod.

When a file or directory is copied or moved, ACLs are moved along with the file or
directory.

Linux System Security


CentOS 7 and later versions come with a default built-in firewall service named firewalld.
This service functions in a similar manner to a regular firewall in terms of providing
security zones with different trust levels. Each zone constitutes a group of permit/deny
rules for incoming traffic. Each physical interface on the server is bound to one of the
firewall zones. However, firewalld provides only a subset of the services provided by a
full-fledged firewall.
You can check the status of the firewalld service and start, stop, enable, and disable the
service just as you would any other service on Linux by using the systemctl command.
Example 3-36 shows the status of the firewalld service: In this example, you can see that
it is active and enabled.

Example 3-36 The firewalld Service Status

[NetProg@localhost ~]$ systemctl status firewalld


● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor
preset: enabled)
Active: active (running) since Sat 2018-04-21 21:37:06 +03; 30min ago
Docs: man:firewalld(1)
Main PID: 787 (firewalld)
CGroup: /system.slice/firewalld.service
└─787 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid

Apr 21 21:37:05 localhost.localdomain systemd[1]: Starting firewalld - dynamic


firewall daemon...
Apr 21 21:37:06 localhost.localdomain systemd[1]: Started firewalld - dynamic
firewall daemon.

--------- OUTPUT TRUNCATED FOR BREVITY ---------

9781587145148_print.indb 155 25/03/21 11:43 am


156 Chapter 3: Linux Storage, Security, and Networks

The firewalld service has a set of zones created by default when the service is first
installed; these zones are sometimes referred to as the base or predefined zones. Custom
zones can also be created and deleted. However, base zones cannot be deleted. One zone
is designated as the default zone and is the zone to which all interfaces are bound, by
default, unless the interface is explicitly moved to another zone. By default, the default
zone is the public zone. Each zone has a set of rules attached to it and a list of interfaces
bound to it. Rules and interfaces can be added to or removed from a zone.

Example 3-37 shows how to list the base zones of firewalld by using the command
firewall-cmd --get-zones and how to identify the default zone by using the command
firewall-cmd --get-default-zone.

Example 3-37 Listing the Base and Default Zones of a Firewall

[root@localhost ~]# firewall-cmd --get-zones


block dmz drop external home internal public trusted work
[root@localhost ~]# firewall-cmd --get-default-zone
public
[root@localhost ~]#

You can change the default zone by using the command firewall-cmd --set-default-
zone={zone_name}.

You can list the details of a zone by using the command firewall-cmd --list-all
--zone={zone_name}, as shown in Example 3-38. To list the details of the default zone,
you omit the --zone={zone_name} option.

Example 3-38 Listing Zone Details

[root@localhost ~]# firewall-cmd --list-all --zone=internal


internal
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh mdns samba-client dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

[root@localhost ~]# firewall-cmd --list-all


public (active)

9781587145148_print.indb 156 25/03/21 11:43 am


Linux Security 157

target: default
icmp-block-inversion: no
interfaces: enp0s3 enp0s9 enp0s10 enp0s8
sources:
services: ssh dhcpv6-client
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@localhost ~]#

Example 3-39 shows how to add rules to the zone dmz to permit specific incoming
traffic on interfaces bound to this zone. The first rule added permits traffic from the
source IP address 10.10.1.0/24 by using a source-based rule. Then BGP traffic on TCP
port 179 is permitted by using a port-based rule. HTTP service is then permitted by
defining a service-based rule. Finally, interface enp0s9 is removed from the public zone
and bound to the dmz zone. Notice how the rules appear when the details of the zone are
listed at the end of the example.

Example 3-39 Adding Rules to Zone dmz

[root@localhost ~]# firewall-cmd --list-all --zone=dmz


dmz
target: default
icmp-block-inversion: no
interfaces:
sources:
services: ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

[root@localhost ~]# firewall-cmd --zone=dmz --add-source=10.10.1.0/24


success
[root@localhost ~]# firewall-cmd --zone=dmz --add-port=179/tcp
success

9781587145148_print.indb 157 25/03/21 11:43 am


158 Chapter 3: Linux Storage, Security, and Networks

[root@localhost ~]# firewall-cmd --zone=dmz --add-service=http


success
[root@localhost ~]# firewall-cmd --zone=dmz --add-interface=enp0s9
The interface is under control of NetworkManager, setting zone to 'dmz'.
success
[root@localhost ~]# firewall-cmd --zone=dmz --list-all
dmz (active)
target: default
icmp-block-inversion: no
interfaces: enp0s9
sources: 10.10.1.0/24
services: ssh http
ports: 179/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
[root@localhost ~]#

Note that in order to remove a rule, instead of using the --add option, you use the
--remove option. For example, to remove the rule for TCP port 179, you use the com-
mand firewall-cmd --zone=dmz --remove-port=179/tcp.

Much like running and startup configurations on routers and switches, firewalld supports
both runtime and permanent configurations. A runtime configuration is not persistent
and is lost after a reload. A permanent configuration is persistent but takes effect only
after a reload when the configuration has been changed. Any configuration commands
that have been executed are reflected in the runtime configuration. To make a configura-
tion permanent, you use the option --permanent with the command. You reload the
firewalld service by using the command firewall-cmd --reload.

Linux Networking
Linux provides several methods for managing network devices and interfaces on a sys-
tem. Usually, a system administrator can accomplish the same task using several different
methods. A network device or an interface is managed by the kernel, and each method
accesses the Linux kernel via a different path. There are three popular methods for man-
aging Linux networking:

■■ Using the command-line ip utility


■■ Using the NetworkManager service

■■ Using network configuration files

9781587145148_print.indb 158 25/03/21 11:43 am


Linux Networking 159

This section covers these three methods listed. It should be fairly easy to use the help
resources on your Linux distro, such as the man and info pages, to learn about any utility
not covered here.

Note Keep in mind that some commands and utilities for managing Linux networking,
such as ifconfig, netstat, arp, and route, are considered legacy utilities. These utilities have
not been updated for years and have been deprecated on some distros but are still available
on others. Even if any of these commands are available in the distro you are using, we do
not recommend using them; instead, use the methods described in this section. Basically,
the way legacy utilities function, particularly how these utilities speak with the kernel,
is not very efficient. You will probably run into these legacy utilities at some point while
working on Linux. For example, at the time of this writing, all four legacy utilities men-
tioned here are still supported on the Bash shells exposed by IOS XR and NX-OS.

The ip Utility
ip is a command-line utility that is part of the iproute2 group of utilities. It is invoked
using the command ip [options] {object} {action}. This syntax is quite intuitive in that the
action in the command indicates what action you would want to apply to an object. For
example, the command ip link show applies the action show to the object link. As you
may have guessed, this command displays the state of all network interfaces (links) on the
system, as shown in Example 3-40. To limit the output to one specific interface, you can
add dev {intf} to the end of the command, as also shown in the example.

Note The man pages for the ip command refer to the action part in the previous syntax
as command. We took the liberty to call it action in the upcoming few paragraphs in order
to avoid the obvious confusion that will result from calling it command.

Example 3-40 Output of the Command ip link show

[NetProg@localhost ~]$ ip link show


1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT
qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode
DEFAULT qlen 1000
link/ether 08:00:27:a7:32:f7 brd ff:ff:ff:ff:ff:ff
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode
DEFAULT qlen 1000
link/ether 08:00:27:83:40:75 brd ff:ff:ff:ff:ff:ff
4: enp0s9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode
DEFAULT qlen 1000
link/ether 08:00:27:b4:ce:55 brd ff:ff:ff:ff:ff:ff

9781587145148_print.indb 159 25/03/21 11:43 am


160 Chapter 3: Linux Storage, Security, and Networks

5: enp0s10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP


mode DEFAULT qlen 1000
link/ether 08:00:27:48:59:02 brd ff:ff:ff:ff:ff:ff
6: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
mode DEFAULT qlen 1000
link/ether 52:54:00:ea:c5:d4 brd ff:ff:ff:ff:ff:ff
7: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state
DOWN mode DEFAULT qlen 1000
link/ether 52:54:00:ea:c5:d4 brd ff:ff:ff:ff:ff:ff
[NetProg@localhost ~]$ ip link show dev enp0s3
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode
DEFAULT qlen 1000
link/ether 08:00:27:a7:32:f7 brd ff:ff:ff:ff:ff:ff
[NetProg@localhost ~]$

Table 3-1 lists some of the objects that are commonly used with the ip command.

Table 3-1 Objects That Are Commonly Used with the ip Command
Object Description
address IPv4 or IPv6 protocol address
link Network interface
route Routing table entry
maddress Multicast address
neigh ARP entry

As of this writing, there are 19 objects that can be acted upon by using the ip command.
A full list of objects can be found in the man pages for the ip command. Objects can be
written in full or in abbreviated form, such as address or addr. The actions that can be
used with the ip command are limited to three options listed in Table 3-2.

Table 3-2 Actions That Can Be Used with the ip Command


Action Description
add Adds the object
delete Deletes the object
show (or list) Displays information about the object

9781587145148_print.indb 160 25/03/21 11:43 am


Linux Networking 161

The keyword show or list can be dropped from a command, and the command will still
be interpreted as a show action. For example, the command ip link show is equivalent to
just ip link.

The ip addr command lists all interfaces on the system, each with its IP address informa-
tion, and the ip maddr command displays the multicast information for each and every
interface. The ip neigh command displays the ARP table. The ARP table consists of a list
of neighbors on each interface on the local network. The examples in this section show
how to use these show commands.

You can bring an interface on Linux up or down by using the command ip link set {intf}
{up|down}. The set action is only applicable to the link object and therefore was not listed in
Table 3-2. Example 3-41 shows how to bring interface enp0s8 down and then up again. Note
that changing networking configuration on Linux, including toggling an interface’s state,
requires root privileges. The show commands, however, do not. To keep Example 3-41
short and avoid the frequent password prompt, all commands in the example are issued
by the root user. However, running commands as root in general is not a recommended
practice. On a production network, make sure to avoid logging in as root. It is best prac-
tice to log in with your regular user account and use the sudo command whenever a com-
mand requires root privileges to execute, as explained in Chapter 2.

Example 3-41 Toggling Interface State

[root@localhost ~]# ip link show dev enp0s8


3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode
DEFAULT qlen 1000
link/ether 08:00:27:83:40:75 brd ff:ff:ff:ff:ff:ff
[root@localhost ~]# ip link set enp0s8 down
[root@localhost ~]# ip link show dev enp0s8
3: enp0s8: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT
qlen 1000
link/ether 08:00:27:83:40:75 brd ff:ff:ff:ff:ff:ff
[root@localhost ~]# ip link set enp0s8 up
[root@localhost ~]# ip link show dev enp0s8
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode
DEFAULT qlen 1000
link/ether 08:00:27:83:40:75 brd ff:ff:ff:ff:ff:ff
[root@localhost ~]#

You can add an IP address to an interface by using the command ip addr add {IP_
address} dev {intf}. By replacing the action add with del, you remove the IP address.
In Example 3-42, IP address 10.1.0.10/24 is added to interface enp0s8, and then the origi-
nal IP address, 10.1.0.1/24, is removed. The ip addr show dev enp0s8 command is used
to inspect the interface IP address before and after the change.

9781587145148_print.indb 161 25/03/21 11:43 am


162 Chapter 3: Linux Storage, Security, and Networks

Example 3-42 Adding and Removing IP Addresses on Interfaces

[root@localhost ~]# ip addr show dev enp0s8


3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen
1000
link/ether 08:00:27:83:40:75 brd ff:ff:ff:ff:ff:ff
inet 10.1.0.1/24 brd 10.1.0.255 scope global enp0s8
valid_lft forever preferred_lft forever
inet6 fe80::8b8:d663:847f:79d9/64 scope link
valid_lft forever preferred_lft forever
[root@localhost ~]# ip addr add 10.1.0.10/24 dev enp0s8
[root@localhost ~]# ip addr show dev enp0s8
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen
1000
link/ether 08:00:27:83:40:75 brd ff:ff:ff:ff:ff:ff
inet 10.1.0.1/24 brd 10.1.0.255 scope global enp0s8
valid_lft forever preferred_lft forever
inet 10.1.0.10/24 scope global secondary enp0s8
valid_lft forever preferred_lft forever
inet6 fe80::8b8:d663:847f:79d9/64 scope link
valid_lft forever preferred_lft forever
[root@localhost ~]# ip addr del 10.1.0.1/24 dev enp0s8
[root@localhost ~]# ip addr show dev enp0s8
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen
1000
link/ether 08:00:27:83:40:75 brd ff:ff:ff:ff:ff:ff
inet 10.1.0.10/24 scope global enp0s8
valid_lft forever preferred_lft forever
inet6 fe80::8b8:d663:847f:79d9/64 scope link
valid_lft forever preferred_lft forever
[root@localhost ~]#

Notice that the IP address 10.1.0.10/24 is added as a secondary address, as long as another
IP address is configured on the interface. When the original IP address is removed, the
new IP address becomes the primary address.

Notice the mtu value in the output of the ip addr show command in Example 3-42. By
default the mtu is set to 1500 bytes. To change that value, you use the command ip link
set {intf} mtu {mtu_value}.

A very useful feature that any network engineer would truly appreciate is interface
promiscuous mode. By default, when an Ethernet frame is received on an interface,
that frame is passed on to the upper layers for processing only if the destination MAC
address of the frame matches the MAC address of the interface (or if the destination
MAC address is a broadcast address). If the MAC addresses do not match, the frame is
ignored. This renders packet sniffing applications such as Wireshark and features such as
port mirroring unusable. In promiscuous mode, an interface accepts any and all incoming

9781587145148_print.indb 162 25/03/21 11:43 am


Linux Networking 163

packets, whether the packets are addressed to that interface or not. You can enable pro-
miscuous mode by using the command ip link set {intf} promisc on.

In the routing table, the list of routes on the system can be displayed by using the com-
mand ip route. Example 3-43 shows that the routing table is empty when no IP addresses
are configured on any of the interfaces. When the IP address 10.2.0.30/24 is configured on
interface enp0s3, one entry, corresponding to that interface, is added to the routing table.

Example 3-43 Viewing a Routing Table by Using the ip route Command

[NetProg@server4 ~]$ ip addr


1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen
1000
link/ether 08:00:27:2c:61:d0 brd ff:ff:ff:ff:ff:ff
inet6 fe80::a00:27ff:fe2c:61d0/64 scope link
valid_lft forever preferred_lft forever
[NetProg@server4 ~]$ ip route

[NetProg@server4 ~]$ sudo ip addr add 10.2.0.30/24 dev enp0s3


[sudo] password for NetProg:
[NetProg@server4 ~]$ ip addr show dev enp0s3
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen
1000
link/ether 08:00:27:2c:61:d0 brd ff:ff:ff:ff:ff:ff
inet 10.2.0.30/24 scope global enp0s3
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe2c:61d0/64 scope link
valid_lft forever preferred_lft forever
[NetProg@server4 ~]$ ip route
10.2.0.0/24 dev enp0s3 proto kernel scope link src 10.2.0.30
[NetProg@server4 ~]$

Routing tables on Linux systems are very similar to routing tables on routers. In fact, a
Linux server could easily function as a router. In order to display routing table function-
ality in Linux, server1 in the topology in Figure 3-2 is used as a router to route traffic
between server2 and server3. server2 is connected to network 10.1.0.0/24, and server3
is connected to network 10.2.0.0/24. All three servers are configured such that server1
routes between the two networks, and eventually server2 should be able to ping server3.

9781587145148_print.indb 163 25/03/21 11:43 am


164 Chapter 3: Linux Storage, Security, and Networks

.20 .10 .10 .30


10.1.0.0/24 10.2.0.0/24

server2 server1 server3

Figure 3-2 Server1 Configured to Route Between server2 and server3, Each on a
Different Subnet

IP addressing needs to be configured first. server1 is configured with IP addresses ending


with .10, server2 with an IP address ending in .20, and server3 with an IP address ending
in .30, as shown in Example 3-44.

Example 3-44 Configuring IP Addresses on the Interfaces Connecting The Three


Servers

! server1
[root@server1 ~]# ip addr add 10.1.0.10/24 dev enp0s8
[root@server1 ~]# ip addr add 10.2.0.10/24 dev enp0s9
[root@server1 ~]# ip addr show enp0s8 | grep "inet "
inet 10.1.0.10/24 scope global enp0s8
[root@server1 ~]# ip addr show enp0s9 | grep "inet "
inet 10.2.0.10/24 scope global enp0s9
[root@server1 ~]#

! server2
[root@server2 ~]# ip addr add 10.1.0.20/24 dev enp0s3
[root@server2 ~]# ip addr show enp0s3 | grep "inet "
inet 10.1.0.20/24 scope global enp0s3
[root@server2 ~]#

! server3
[root@server3 ~]# ip addr add 10.2.0.30/24 dev enp0s3
[root@server3 ~]# ip addr show dev enp0s3 | grep "inet "
inet 10.2.0.30/24 scope global enp0s3
[root@server3 ~]#

A ping to the directly connected server is successful on all three servers. However, when
server2 attempts to ping server3, the ping fails, as shown in Example 3-45.

9781587145148_print.indb 164 25/03/21 11:43 am


Linux Networking 165

Example 3-45 Pinging the Directly Connected Interfaces Is Successful but Pinging
server3 From server2 Is Not

! Pinging the directly connected interfaces

! server2 to server1
[root@server2 ~]# ping -c 1 10.1.0.10
PING 10.1.0.10 (10.1.0.10) 56(84) bytes of data.
64 bytes from 10.1.0.10: icmp_seq=1 ttl=64 time=0.796 ms

--- 10.1.0.10 ping statistics ---


1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.796/0.796/0.796/0.000 ms
[root@server2 ~]#

! server3 to server1
[root@server3 ~]# ping -c 1 10.2.0.10
PING 10.2.0.10 (10.2.0.10) 56(84) bytes of data.
64 bytes from 10.2.0.10: icmp_seq=1 ttl=64 time=1.13 ms

--- 10.2.0.10 ping statistics ---


1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.139/1.139/1.139/0.000 ms
[root@server3 ~]#

! Pinging server2 to server3 and vice versa is not successful

! server2 to subnet 10.2.0.0/24


[root@server2 ~]# ping 10.2.0.10
connect: Network is unreachable
[root@server2 ~]# ping 10.2.0.30
connect: Network is unreachable
[root@server2 ~]#

! server3 to subnet 10.1.0.0/24


[root@server3 ~]# ping -c 1 10.1.0.10
connect: Network is unreachable
[root@server3 ~]# ping -c 1 10.1.0.20
connect: Network is unreachable
[root@server3 ~]#

You are probably very familiar with the ping command. ping works on Linux exactly as
it does on network devices: by sending one or more ICMP packets to the destination
and either receiving an ICMP reply if the ping is successful (one reply per packet sent)

9781587145148_print.indb 165 25/03/21 11:43 am


166 Chapter 3: Linux Storage, Security, and Networks

or receiving an ICMP unreachable packet or no response at all if the ping is not. The
command in Example 3-45 uses the -c 1 option to send a single ICMP packet, which is
enough to test the reachability of the destination.
Example 3-46 shows how to use the command ip route add 10.2.0.0/24 via 10.1.0.10 on
server2 and the command ip route add 10.1.0.0/24 via 10.2.0.10 on server3 to add routes
to the routing tables of each server. The general syntax for adding a route to the routing
table is ip route add {destination}{/mask} via {nexthop}. The routes instruct each server
to use server1 as the next hop to reach the remote network. After the routes are added,
server2 and server3 are able to ping server1’s interface on the remote network, but they
are still not able to ping each other.

Example 3-46 Adding Routing Table Entries for Remote Subnets on server2 and
server3. server2 and server3 Can Ping the Remote Subnets on server1, But Still Cannot
Ping Each Other

! server2
[root@server2 ~]# ip route add 10.2.0.0/24 via 10.1.0.10
[root@server2 ~]# ip route
10.1.0.0/24 dev enp0s3 proto kernel scope link src 10.1.0.20
10.2.0.0/24 via 10.1.0.10 dev enp0s3
[root@server2 ~]# ping -c 1 10.2.0.10
PING 10.2.0.10 (10.2.0.10) 56(84) bytes of data.
64 bytes from 10.2.0.10: icmp_seq=1 ttl=64 time=0.822 ms

--- 10.2.0.10 ping statistics ---


1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.822/0.822/0.822/0.000 ms
[root@server2 ~]# ping -c 1 10.2.0.30
PING 10.2.0.30 (10.2.0.30) 56(84) bytes of data.

--- 10.2.0.30 ping statistics ---


1 packets transmitted, 0 received, 100% packet loss, time 0ms
[root@server2 ~]#

! server3
[root@server3 ~]# ip route add 10.1.0.0/24 via 10.2.0.10
[root@server3 ~]# ip route
10.1.0.0/24 via 10.2.0.10 dev enp0s3
10.2.0.0/24 dev enp0s3 proto kernel scope link src 10.2.0.30
[root@server3 ~]# ping -c 1 10.1.0.10
PING 10.1.0.10 (10.1.0.10) 56(84) bytes of data.
64 bytes from 10.1.0.10: icmp_seq=1 ttl=64 time=0.865 ms

9781587145148_print.indb 166 25/03/21 11:43 am


Linux Networking 167

--- 10.1.0.10 ping statistics ---


1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.865/0.865/0.865/0.000 ms
[root@server3 ~]# ping -c 1 10.1.0.20
PING 10.1.0.20 (10.1.0.20) 56(84) bytes of data.

--- 10.1.0.20 ping statistics ---


1 packets transmitted, 0 received, 100% packet loss, time 0ms
[root@server3 ~]#

Forwarding between the interfaces on server1 is disabled by default for security reasons.
Therefore, the remaining step is to enable forwarding in the kernel of server1 by toggling
the default value of 0 in file /proc/sys/net/ipv4/ip_forward to 1 by using either the com-
mand echo 1 > /proc/sys/net/ipv4/ip_forward or the command /sbin/sysctl -w net.ipv4.
ip_forwad=1. After either command is used, forwarding is enabled, and both servers can
ping each other successfully, as shown in Example 3-47.

Example 3-47 Enabling Routing on Server1 Resulting in Successful ping Between


server2 and server3

! Enabling routing on server1


[root@server1 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
[root@server1 ~]# cat /proc/sys/net/ipv4/ip_forward
1

! server2 to server3 ping is successful


[root@server2 ~]# ping -c 1 10.2.0.30
PING 10.2.0.30 (10.2.0.30) 56(84) bytes of data.
64 bytes from 10.2.0.30: icmp_seq=1 ttl=63 time=0.953 ms
--- 10.2.0.30 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.953/0.953/0.953/0.000 ms
[root@server2 ~]#

! server3 to server2 ping is successful


[root@server3 ~]# ping -c 1 10.1.0.20
PING 10.1.0.20 (10.1.0.20) 56(84) bytes of data.
64 bytes from 10.1.0.20: icmp_seq=1 ttl=63 time=1.39 ms

--- 10.1.0.20 ping statistics ---


1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.394/1.394/1.394/0.000 ms
[root@server3 ~]#

9781587145148_print.indb 167 25/03/21 11:43 am


168 Chapter 3: Linux Storage, Security, and Networks

Note that two commands to achieve the same result are mentioned here. The first method
gets the job done by editing a file, and the second gets the same job done by using the
command sysctl. Which one you should use depends on several factors, the first of
which is personal preference. Another issue is whether you know which file in the /proc/
sys/ directory contains the kernel setting (sometimes referred to as a kernel tunable) that
you need to change. If you do not know the file, you can simply use the sysctl command
to target the parameter directly, regardless of where it is located. You can list all kernel
tunables by using the command /sbni/sysctl -a.

Note You in this case does not necessarily have to literally mean you. It may refer to the
automation script or tool that you are using to get the job done. Using a particular tool to
amend a file may be more efficient than issuing a command; the reverse may be the case
for another tool. Always choose the method that is most efficient and effective for your
specific environment.

To remove a routing table entry, you use the syntax ip route delete {destination}{/mask}
via {nexthop}. You can also have routes point to exit interfaces rather than next hops
by using the syntax ip route add {destination}{/mask} dev {intf}. You can add a default
route by using the syntax ip route add default via {next_hop} dev {intf}.

One final note on the ip utility is that any configuration performed using the commands
discussed in this section is not persistent. Any changes to the configuration disappear
after a system reboot. Persistent configuration is discussed in the following sections.

The NetworkManager Service


NetworkManager is the default network management service on several Linux distros,
including Red Hat and Fedora. Because NetworkManager is a service, you can check its
status, and you can start, stop, enable, or disable it as you can any other service on Linux
by using the systemctl command. For example, the command systemctl status network-
manager displays the current status of the service. To poll NetworkManager for informa-
tion or push configuration to it, you can use one of several user interfaces:

■■ Graphical user interfaces (GUIs): There are two main graphical user interface
tools that interact with NetworkManager. The first is the Network Control Center,
which is accessible via the Settings menu. The Settings window has an icon labeled
Network that opens the network control center, which provides basic network con-
figuration. The other GUI tool is the Connection Editor and is used to configure
more advanced settings. You can start the Connection Editor from the terminal by
entering the command nm-connection-editor.

■■ NetworkManager command-line interface (nmcli): The NetworkManager CLI is a


command-line utility that you can use to control NetworkManager. You can use this
interface to NetworkManager via the nmcli command in the Bash shell.

9781587145148_print.indb 168 25/03/21 11:43 am


Linux Networking 169

■■ NetworkManager text user interface (nmtui): Similar to the interface used to con-
figure a computer’s BIOS settings or old DOS-based programs, the nmtui provides
an interface to NetworkManager that displays graphics in text mode. You start the
text user interface by issuing the nmtui command in the shell.

■■ API: NetworkManager provides an API that can be used by applications for pro-
grammatic access to NetworkManager.

Because the majority of automation is typically performed through CLI tools (and API calls)
and not the GUI, this section cover NetworkManager configuration via the nmcli interface.

NetworkManager deals with objects called connections. A connection is a representation


of a link to the outside world and may represent, for example, a wired connection, a wire-
less connection, or a VPN connection. To display the current status of all network con-
nections on a system, use the command nmcli con show, as shown in Example 3-48.

Example 3-48 Listing All Connections on a System

[root@server1 ~]# nmcli con show


NAME UUID TYPE DEVICE
Wired connection 1 d8323782-5cf2-3afc-abcd-e603605ac4f8 802-3-ethernet --
Wired connection 2 669fefb4-bc57-3d19-b83b-2b2125e0036b 802-3-ethernet --
[root@server1 ~]#

The output in Example 3-48 indicates that there are two connections, named Wired
connection 1 and Wired connection 2. These connections are not bound (applied) to
any interfaces, as indicated by the -- in the last column. Both connections are of type
Ethernet. A connection is uniquely identified by its universally unique identifier (UUID).
Although not shown in the command output, a connection can either be active or inac-
tive. To activate an inactive connection, you use the command nmcli con up {connection_
name}. To deactivate a connection, you replace the keyword up with the keyword down.

Each connection is known as a connection profile and contains several attributes or


properties that you can set. These properties are known as settings. Connection profile
settings are created and then applied to a device or device type. Settings are represented
in a dot notation. For example, a connection’s IPv4 addresses are represented by the set-
ting ipv4.addresses. To drill down on the details for a specific connection and list its
settings and their values, you can use the command nmcli con show {connection_name}.
Example 3-49 lists the connection profile settings for Wired connection 1. The output
is truncated due to the length of the list. A full list of settings and their meanings can be
found in the man pages for the nmcli command.

Note Use of the terms “master” and “slave” is ONLY in association with the official ter-
minology used in industry specifications and standards, and in no way diminishes Pearson’s
commitment to promoting diversity, equity, and inclusion, and challenging, countering and/
or combating bias and stereotyping in the global population of the learners we serve.

9781587145148_print.indb 169 25/03/21 11:43 am


170 Chapter 3: Linux Storage, Security, and Networks

Example 3-49 Connection Attributes for Wired Connection 1

[root@server1 ~]# nmcli con show "Wired connection 1"


connection.id: Wired connection 1
connection.uuid: d8323782-5cf2-3afc-abcd-e603605ac4f8
connection.stable-id: --
connection.interface-name: --
connection.type: 802-3-ethernet
connection.autoconnect: yes
connection.autoconnect-priority: -999
connection.autoconnect-retries: -1 (default)
connection.timestamp: 1525512827
connection.read-only: no
connection.permissions: --
connection.zone: --
connection.master: --
connection.slave-type: --
connection.autoconnect-slaves: -1 (default)
connection.secondaries: --
connection.gateway-ping-timeout: 0
connection.metered: unknown
connection.lldp: -1 (default)
802-3-ethernet.port: --
802-3-ethernet.speed: 0
802-3-ethernet.duplex: --
802-3-ethernet.auto-negotiate: no
802-3-ethernet.mac-address: 08:00:27:83:40:75
802-3-ethernet.cloned-mac-address: --
802-3-ethernet.generate-mac-address-mask:--
802-3-ethernet.mac-address-blacklist: --
802-3-ethernet.mtu: auto
802-3-ethernet.s390-subchannels: --
802-3-ethernet.s390-nettype: --
802-3-ethernet.s390-options: --
802-3-ethernet.wake-on-lan: 1 (default)
802-3-ethernet.wake-on-lan-password: --
ipv4.method: auto
ipv4.dns: --
ipv4.dns-search: --
ipv4.dns-options: (default)
ipv4.dns-priority: 0
ipv4.addresses: --
ipv4.gateway: --
ipv4.routes: --

--------- OUTPUT TRUNCATED FOR BREVITY ---------

9781587145148_print.indb 170 25/03/21 11:43 am


Linux Networking 171

To list the devices (aka interfaces) on the system and the status of each one, you use the
command nmcli dev status for all devices or the command nmcli dev show {device_
name} for a specific device, as shown in Example 3-50.

Example 3-50 Device Status Using the nmcli dev status and nmcli dev show
Commands

[root@server1 ~]# nmcli dev status


DEVICE TYPE STATE CONNECTION
enp0s8 ethernet disconnected --
enp0s9 ethernet disconnected --
lo loopback unmanaged --
[root@server1 ~]# nmcli dev show enp0s8
GENERAL.DEVICE: enp0s8
GENERAL.TYPE: ethernet
GENERAL.HWADDR: 08:00:27:83:40:75
GENERAL.MTU: 1500
GENERAL.STATE: 30 (disconnected)
GENERAL.CONNECTION: --
GENERAL.CON-PATH: --
WIRED-PROPERTIES.CARRIER: on
[root@server1 ~]#

As you can see from the outputs in Examples 3-49 and 3-50, connections and devices are
mutually exclusive. A connection profile may or may not be applied to a device after it
is created.

In Example 3-51, both of the wired connections are deleted, and one new connection
named NetDev_1 is created. NetDev_1 is of type ethernet and is applied to device
enp0s8. Connections are deleted using the command nmcli con del {connection_name}.
You create new connections and configure their settings by using the command nmcli
con add {connection_name} {setting} {value}. In Example 3-51, the type, ifname, ip4, and
gw4 settings are set to Ethernet, enp0s8, 10.1.0.10/24, and 10.1.0.254, respectively. Note
that in this command, setting can either be entered in the full dot format or in abbrevi-
ated format. For example, the IP address can be set using either ip4 or ipv4.address.

Example 3-51 Deleting and Creating Connections

[root@server1 ~]# nmcli con show


NAME UUID TYPE DEVICE
Wired connection 1 d8323782-5cf2-3afc-abcd-e603605ac4f8 802-3-ethernet --
Wired connection 2 669fefb4-bc57-3d19-b83b-2b2125e0036b 802-3-ethernet --
[root@server1 ~]# nmcli con del "Wired connection 1"
Connection 'Wired connection 1' (d8323782-5cf2-3afc-abcd-e603605ac4f8) successfully
deleted.
[root@server1 ~]# nmcli con del "Wired connection 2"

9781587145148_print.indb 171 25/03/21 11:43 am


172 Chapter 3: Linux Storage, Security, and Networks

Connection 'Wired connection 2' (669fefb4-bc57-3d19-b83b-2b2125e0036b) successfully


deleted.
[root@server1 ~]# nmcli con show
NAME UUID TYPE DEVICE
[root@server1 ~]# nmcli con add con-name NetDev_1 type ethernet ifname enp0s8 ip4
10.1.0.10/24 gw4 10.1.0.254
Connection 'NetDev_1' (a8ac9116-697a-4a0a-85a2-63428d6e75a3) successfully added.
[root@server1 ~]# nmcli con show
NAME UUID TYPE DEVICE
NetDev_1 a8ac9116-697a-4a0a-85a2-63428d6e75a3 802-3-ethernet enp0s8
[root@server1 ~]# nmcli con show --active
NAME UUID TYPE DEVICE
NetDev_1 a8ac9116-697a-4a0a-85a2-63428d6e75a3 802-3-ethernet enp0s8
[root@server1 ~]# nmcli dev status
DEVICE TYPE STATE CONNECTION
enp0s8 ethernet connected NetDev_1
enp0s9 ethernet disconnected --
lo loopback unmanaged --
[root@server1 ~]# nmcli dev show enp0s8
GENERAL.DEVICE: enp0s8
GENERAL.TYPE: ethernet
GENERAL.HWADDR: 08:00:27:83:40:75
GENERAL.MTU: 1500
GENERAL.STATE: 100 (connected)
GENERAL.CONNECTION: NetDev_1
GENERAL.CON-PATH: /org/freedesktop/NetworkManager/ActiveCon-
nection/359
WIRED-PROPERTIES.CARRIER: on
IP4.ADDRESS[1]: 10.1.0.10/24
IP4.GATEWAY: 10.1.0.254
IP6.ADDRESS[1]: fe80::8c1f:4c4a:51a5:6423/64
IP6.GATEWAY: --
[root@server1 ~]# ping 10.1.0.20 -c 3
PING 10.1.0.20 (10.1.0.20) 56(84) bytes of data.
64 bytes from 10.1.0.20: icmp_seq=1 ttl=64 time=0.604 ms
64 bytes from 10.1.0.20: icmp_seq=2 ttl=64 time=0.602 ms
64 bytes from 10.1.0.20: icmp_seq=3 ttl=64 time=0.732 ms

--- 10.1.0.20 ping statistics ---


3 packets transmitted, 3 received, 0% packet loss, time 2011ms
rtt min/avg/max/mdev = 0.602/0.646/0.732/0.060 ms
[root@server1 ~]#

Notice that once a connection has been created and the device enp0s8 has been bound to
it (all in the same command), the connection and device both come up, and that results in
the device successfully pinging server2 on the other end of the link.

9781587145148_print.indb 172 25/03/21 11:43 am


Linux Networking 173

After a connection is created, you can modify its settings by using the command nmcli
con mod {connection_name} {setting} {value}. When modifying a setting, the full dot
format is required in the command. If the shorthand format is used, the new value in the
command may be added to the existing value of the setting. For example, if the short-
hand format is used to modify the IP address, the new IP address in the command is
added to the device as a secondary IP address. On the other hand, if the full dot format
is used, the IP address in the command replaces the IP address configured on the device.
Example 3-52 shows how to modify the IP address of device enp0s8 to 10.1.0.100/24.

Example 3-52 Deleting and Creating Connections

[root@server1 ~]# nmcli con show NetDev_1 | grep ipv4.addr


ipv4.addresses: 10.1.0.10/24
[root@server1 ~]# nmcli dev show enp0s8 | grep IP4.ADD
IP4.ADDRESS[1]: 10.1.0.10/24
[root@server1 ~]# nmcli con mod NetDev_1 ip4 10.1.0.100/24

! The new IP address is added as a secondary address due to the shorthand format
[root@server1 ~]# nmcli con show NetDev_1 | grep ipv4.addr
ipv4.addresses: 10.1.0.10/24, 10.1.0.100/24

! The new IP address is not reflected to the device enp0s8


[root@server1 ~]# nmcli dev show enp0s8 | grep IP4.ADD
IP4.ADDRESS[1]: 10.1.0.10/24

[root@server1 ~]# nmcli con up NetDev_1


Connection successfully activated (D-Bus active path: /org/freedesktop/
NetworkManager/ActiveConnection/366)

! After resetting the con, the new IP address now is reflected to the device
[root@server1 ~]# nmcli dev show enp0s8 | grep IP4.ADD
IP4.ADDRESS[1]: 10.1.0.10/24
IP4.ADDRESS[2]: 10.1.0.100/24

! Using the full dot format will replace the old IP address with the new one
[root@server1 ~]# nmcli con mod NetDev_1 ipv4.address 10.1.0.100/24
[root@server1 ~]# nmcli con up NetDev_1
Connection successfully activated (D-Bus active path: /org/freedesktop/
NetworkManager/ActiveConnection/367)
[root@server1 ~]# nmcli con show NetDev_1 | grep ipv4.addr
ipv4.addresses: 10.1.0.100/24
[root@server1 ~]# nmcli dev show enp0s8 | grep IP4.ADD
IP4.ADDRESS[1]: 10.1.0.100/24
[root@server1 ~]#

9781587145148_print.indb 173 25/03/21 11:43 am


174 Chapter 3: Linux Storage, Security, and Networks

Note that each time a change is made to a connection using nmcli, the connection needs
to be reactivated in order for the changes to be reflected to the device.

Adding routes using nmcli is different than adding routes using the ip utility in that when
using nmcli, routes are added per interface and not globally. You add routes by using
the syntax nmcli con mod {intf} +ipv4.routes {destination} ipv4.gateway {next_hop}.
Therefore, to accomplish the same task that was done earlier by using the ip utility (to
add a route on server2 to direct traffic destined for network 10.2.0.0/24 using the next
hop 10.1.0.10 on server1), you use the following command: nmcli con mod enp0s3 +ipv4.
routes 10.2.0.0/24 ipv4.gateway 10.1.0.10.

Unlike with the ip utility, changes made through nmcli are, by default, persistent and will
survive a system reload.

It is important to understand the difference between the ip utility and NetworkManager.


The ip utility is a program. When you use the ip command, you run this program, which
makes a system call to the kernel, either to retrieve information or configure a component
of the Linux networking system.

On the other hand, NetworkManager is a system daemon. It is software that runs (lurks)
in the background, by default, and oversees the operation of the Linux network system.
NetworkManager may be used to configure components of the network or to retrieve
information about the network by using a variety of methods discussed earlier in this
section—one of them being nmcli.

The nuances of how the ip utility interacts with NetworkManager are not discussed in
detail here. All you need to know for now is that changes to the network that are made
via the ip utility are detected and preserved by NetworkManager. There is no conflict
between them. As mentioned at the very beginning of this section, different software
on Linux can achieve the same result via different communication channels with the ker-
nel. However, any software that needs access to the network will eventually have to go
through the kernel.

Network Scripts and Configuration Files


The third method for configuring network devices and interfaces is to modify network
scripts and configuration files directly. Different files in Linux control different compo-
nents of the networking ecosystem, and editing these files was the only way to configure
networking on Linux before NetworkManager was developed. Configuration files and
scripts can still be used instead of, or in addition to, NetworkManager.

On Linux distros in the Red Hat family, configuration files for network interfaces are
located in the /etc/sysconfig/network-scripts directory, and each interface configuration
file is named ifcfg-<intf_name>. The first script that is executed on system bootup is
/etc/init.d/network. When the system boots up, this script reads through all interface
configuration files whose names start with ifcfg. Example 3-53 shows the ifcfg file for
the enp0s8 interface.

9781587145148_print.indb 174 25/03/21 11:43 am


Linux Networking 175

Example 3-53 Interface Configuration File for Interface enp0s8

[root@server1 network-scripts]# cat ifcfg-enp0s8


TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=dhcp
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=NetDev_1
UUID=a8ac9116-697a-4a0a-85a2-63428d6e75a3
DEVICE=enp0s8
ONBOOT=yes
[root@server1 network-scripts]#

The filename just needs to be prefixed with ifcfg. The network script simply scans the
directory and reads any file whose name has this prefix. Therefore, you can safely assume
that the configuration file is for the interface or connection. However, while the filename
has to start with ifcfg, there is general consensus that the value in the DEVICE field
(interface) should follow the ifcfg prefix.

The TYPE field in the file indicates the connection type, which is Ethernet in this case.
The BOOTPROTO field is set to dhcp, which means the connection gets an IP address
via DHCP. If a static IP address is required on the interface, then dhcp is replaced with
none. The interface associated with this configuration is also shown in the DEVICE
field (enp0s8 in this case), and the ONBOOT field indicates that this connection is to be
brought up at system bootup. When a static IP address is required on the interface, the
fields IPADDR, PREFIX, and GATEWAY and their respective values are added to the file.

When ONBOOT=yes is set, the /etc/init.d/network script checks whether this interface
is managed by NetworkManager. If it is and the connection has already been activated,
no further action is taken. If the connection has not been activated, the script requests
NetworkManager to activate the connection. In case the connection is not managed by
NetworkManager, the network script activates the connection by running another script,
/usr/sbin/ifup. The ifup script checks the field TYPE in the ifcfg file, and based on that, it
calls another type-specific script. For example, if the type of the connection is Ethernet,
the ifup-eth script is called. Linux requires type-specific scripts because different con-
nection types require different configuration parameters. For example, the concept of
an SSID (wireless network name) does not exist for an Ethernet connection. Similarly, to
bring down an interface for an unmanaged interface, the ifdown script is called. The vast
majority of interface types are managed by NetworkManager by default, unless the line
NM_CONTROLLED=no has been added to the ifcfg file.

9781587145148_print.indb 175 25/03/21 11:43 am


176 Chapter 3: Linux Storage, Security, and Networks

While the recommended method for configuring interfaces is to use the nmcli utility, as
discussed in the previous section, you can also configure interfaces by editing the cor-
responding ifcfg file.

Static routes configured on a system have configuration files named route-<intf_name>


in the same directory as the interface configuration files. As you have probably guessed,
the name has to be prefixed with route. However, the -<intf_name> is just a naming con-
vention, and the file may have any name as long as the prefix route is there. The routing
entries in the file may have one of two formats:

■■ The ip command arguments format:

{destination}/{mask} via {next_hop} [dev interface]

With this format, specifying the interface using [dev interface] is optional.
■■ The network/netmask directives format:

ADDRESS{N}:{destination}

NETMASK{N}:{netmask}

GATEWAY{N}:{next_hop}

where N is the routing table entry starting with 0 and incrementing by 1 for each
entry, without skipping any values. In other words, if the routing table has four
entries, the entries are numbered from 0 to 3.

Going back to the network of three servers in Figure 3-2, where server1 is required to
route between server2 on subnet 10.1.0.0/24 and server3 on subnet 10.2.0.0/24: the static
routes previously configured in order to route between the servers are deleted, after
which the ping from server2 to server3 fails, as shown in Example 3-54.

Example 3-54 Ping Fails Due To Lack of Static Routes on server2 and server3
! No routes in routing table of server2 to remote subnet 10.2.0.0/24
[root@server2 ~]# ip route
10.1.0.0/24 dev enp0s3 proto kernel scope link src 10.1.0.20 metric 100
[root@server2 ~]#

! Ping to the directly connected interface on server1 is successful


[root@server2 ~]# ping -c 1 10.1.0.10
PING 10.1.0.10 (10.1.0.10) 56(84) bytes of data.
64 bytes from 10.1.0.10: icmp_seq=1 ttl=64 time=0.828 ms

--- 10.1.0.10 ping statistics ---


1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.828/0.828/0.828/0.000 ms
[root@server2 ~]#

9781587145148_print.indb 176 25/03/21 11:43 am


Linux Networking 177

! Ping to server3 on subnet 10.2.0.0/24 is not successful


[root@server2 ~]# ping -c 1 10.2.0.30
connect: Network is unreachable
[root@server2 ~]#

! No routes in routing table of server3 to remote subnet 10.1.0.0/24


[root@server3 ~]# ip route
10.2.0.0/24 dev enp0s3 proto kernel scope link src 10.2.0.30 metric 100
[root@server3 ~]#

! Ping to the directly connected interface on server1 is successful


[root@server3 ~]# ping -c 1 10.2.0.10
PING 10.2.0.10 (10.2.0.10) 56(84) bytes of data.
64 bytes from 10.2.0.10: icmp_seq=1 ttl=64 time=0.780 ms

--- 10.2.0.10 ping statistics ---


1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.780/0.780/0.780/0.000 ms
[root@server3 ~]#

! Ping to server2 on subnet 10.1.0.0/24 is not successful


[root@server3 ~]# ping -c 1 10.1.0.20
connect: Network is unreachable
[root@server3 ~]#

The file route-enp0s3 is created under the directory /etc/sysconfig/network-scripts/ on


both servers. A routing entry is added to the routing configuration file on server2 by
using the ip command arguments format, and a routing entry is added to the file on
server3 by using the network/netmask directives format, as shown in Example 3-55.

Example 3-55 Routing Configuration Files Added on Both server2 and server3

! server2

! No routing configuration files in the directory


[root@server2 ~]# cd /etc/sysconfig/network-scripts/
[root@server2 network-scripts]# ls -l | grep "route"
[root@server2 network-scripts]#

! Create the file route-enp0s3 and populate it with a route to the remote subnet
10.2.0.0/24 using the IP Command Arguments format
[root@server2 network-scripts]# touch route-enp0s3
[root@server2 network-scripts]# echo "10.2.0.0/24 via 10.1.0.10" >> route-enp0s3
[root@server2 network-scripts]# ls -l | grep " route"
-rw-r--r--. 1 root root 26 Aug 17 15:52 route-enp0s3

9781587145148_print.indb 177 25/03/21 11:43 am


178 Chapter 3: Linux Storage, Security, and Networks

[root@server2 network-scripts]# cat route-enp0s3


10.2.0.0/24 via 10.1.0.10
[root@server2 network-scripts]#

! Restart the network service and check the routing table


[root@server2 network-scripts]# systemctl restart network
[root@server2 network-scripts]# ip route
10.1.0.0/24 dev enp0s3 proto kernel scope link src 10.1.0.20 metric 100
10.2.0.0/24 via 10.1.0.10 dev enp0s3 proto static metric 100
[root@server2 network-scripts]#

! server3

! No routing configuration files in the directory


[root@server3 ~]# cd /etc/sysconfig/network-scripts/
[root@server3 network-scripts]# ls -l | grep " route"

! Create the file route-enp0s3 and populate it with a route to the remote subnet
10.1.0.0/24 using the Network/Netmask Directives format
[root@server3 network-scripts]# touch route-enp0s3
[root@server3 network-scripts]# echo "ADDRESS0=10.1.0.0" >> route-enp0s3
[root@server3 network-scripts]# echo "NETMASK0=255.255.255.0" >> route-enp0s3
[root@server3 network-scripts]# echo "GATEWAY0=10.2.0.10" >> route-enp0s3
[root@server3 network-scripts]# ls -l | grep " route"
-rw-r--r--. 1 root root 60 Aug 17 16:04 route-enp0s3
[root@server3 network-scripts]# cat route-enp0s3
ADDRESS0=10.1.0.0
NETMASK0=255.255.255.0
GATEWAY0=10.2.0.10
[root@server3 network-scripts]#

! Restart the network service and check the routing table


[root@server3 network-scripts]# systemctl restart network
[root@server3 network-scripts]# ip route
10.1.0.0/24 via 10.2.0.10 dev enp0s3 proto static metric 100
10.2.0.0/24 dev enp0s3 proto kernel scope link src 10.2.0.30 metric 100
[root@server3 network-scripts]#

The ping test is now successful, and server2 can reach server3, as shown in Example 3-56.

9781587145148_print.indb 178 25/03/21 11:43 am


Linux Networking 179

Example 3-56 Ping from server2 to server3 and Vice Versa Is Successful Now

[root@server2 network-scripts]# ping -c 1 10.2.0.30


PING 10.2.0.30 (10.2.0.30) 56(84) bytes of data.
64 bytes from 10.2.0.30: icmp_seq=1 ttl=63 time=2.11 ms

--- 10.2.0.30 ping statistics ---


1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.119/2.119/2.119/0.000 ms
[root@server2 network-scripts]#

[root@server3 network-scripts]# ping -c 1 10.1.0.20


PING 10.1.0.20 (10.1.0.20) 56(84) bytes of data.
64 bytes from 10.1.0.20: icmp_seq=1 ttl=63 time=1.58 ms

--- 10.1.0.20 ping statistics ---


1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.585/1.585/1.585/0.000 ms
[root@server3 network-scripts]#

The network script is run as a service and, like any other service, can be controlled
by using the command systemctl {start|stop|restart|status} network. To enable/disable
the network service at startup, you use the command chkconfig network {on|off}. Keep
in mind that after a configuration file is changed, the network service has to be restarted
for the changes to take effect. It goes without saying that any configuration done via
amending the network configuration files is persistent and will remain intact after a
system reload.

Network Services: DNS


Domain Name System (DNS) is a hierarchical naming system used on the Internet and
some private networks to assign domain names to resources on the network. Domain
names tend to be easier to remember than IP addresses. Using domain names provides the
additional capability to resolve a domain name to multiple IP addresses for purposes such
as high availability or routing user traffic based on the geographically closest server.

DNS uses the concept of a resolver, commonly referred to as a DNS server, which is a
server or a database that contains mappings between domain names and the information
related to each of those domain names, such as the IP addresses. These mappings are
called records. DNS is hierarchical and distributed. The majority of DNS servers maintain
records for only some domain names and then initiate queries to other DNS servers for
the rest of the domain names, for which it does not maintain records.

9781587145148_print.indb 179 25/03/21 11:43 am


180 Chapter 3: Linux Storage, Security, and Networks

Performing a DNS query means sending a request to a DNS server to resolve the domain
name and return the data associated with that domain name. To resolve a domain name
on Linux to its corresponding information, including its IP address, you use the dig com-
mand, which stands for domain information groper. Example 3-57 shows dig being
used to resolve google.com to its public IP address. The public IP address received from
the DNS response is highlighted in the example.

Example 3-57 Using the dig Command to Resolve google.com

[root@server1 ~]# dig google.com

; <<>> DiG 9.9.4-RedHat-9.9.4-51.el7_4.2 <<>> google.com


;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38879
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;google.com. IN A

;; ANSWER SECTION:
google.com. 264 IN A 216.58.207.14

;; Query time: 31 msec


;; SERVER: 192.168.8.1#53(192.168.8.1)
;; WHEN: Fri Aug 17 17:16:06 +03 2018
;; MSG SIZE rcvd: 55
[root@server1 ~]#

In Example 3-57, the DNS server used for the name resolution is 192.168.8.1. The
IP address of this DNS server is configured in the /etc/resolv.conf file, shown in
Example 3-58. To configure other DNS servers, you list each server’s IP address on a
new line in this file.

Example 3-58 List of DNS Servers in the /etc/resolv.conf File

[root@server1 ~]# cat /etc/resolv.conf


# Generated by NetworkManager
nameserver 192.168.8.1
[root@server1 ~]#

9781587145148_print.indb 180 25/03/21 11:43 am


Summary 181

Manual DNS entries are configured in the /etc/hosts file. If an entry for a domain name is
found in that file, the DNS servers are not consulted for resolution. There is one caveat,
though: The dig command still requests the name resolution from the DNS server config-
ured in /etc/resolv.conf. However, the ping command and also the web browsers on the
system use the hosts file, and, therefore, use the manual entry there. Try to add a manual
entry for google.com in the hosts file, pointing to an IP address that is not reachable and
then try to use dig, use ping, and browse to google.com and notice how each of these
behave differently.

Summary
This chapter takes Linux administration a step further and covers storage, security, and
networking. It discusses the following topics:

■■ Partitioning, formatting, and managing physical storage

■■ Creating physical volumes, volume groups, and logical volumes using LVM

■■ User and group security management

■■ File security management, including permission bits and ACLs

■■ Linux system security, including the Linux firewall

■■ Managing Linux networking by using the ip utility

■■ Managing Linux networking by using the NetworkManager CLI (nmcli)

■■ Managing Linux networking via network scripts and configuration files

■■ Network services such as DNS

Chapter 4, “Linux Scripting,” builds on this chapter and covers Linux scripting, which is
one big step towards automation.

9781587145148_print.indb 181 25/03/21 11:43 am


Index

Symbols {N, M}, regular expressions (regex),


186, 189–192
regular expressions (regex), 185
& (ampersands)
$ (dollar signs), regular expressions
&= operator, Python, 284
(regex), 185, 187
AND operator, Python, 281,
. (dots),
285–286
.* notation, regular expressions
* (asterisks)
(regex), 190
** assignment operator, Python, 281
.. notation, Linux directories, 37
**= operator, Python, 284
regular expressions (regex), 185, 189
*= operator, Python, 284
= (equal signs)
assignment operator, Python, 281
= assignment operator, Python,
regular expressions (regex), 185, 189 284
\ (backslashes) == (double equal sign)
\<, regular expressions (regex), 185, conditional statements, 229
188–189
Jinja2 operator, 1019
\>, regular expressions (regex), 185,
Python operator, 285
188–189
conditional statements, 229
regular expressions (regex), 186
!= operator
^ (carets)
Jinja2, 1019
^= operator, Python, 284
Python, 285
regular expressions (regex), 185, 187
/ (forward slashes)
XOR operator, 281
/ assignment operator, Python, 281
{ } (curly braces)
/: root directory, Linux, 36–37
{N}, regular expressions (regex), 186,
189–192 /= operator, Python, 284

Z01_Abuelenain_Index_p1121-p1196.indd 1121 27/03/21 6:37 pm


1122 < (left arrows)

< (left arrows) >>= operator, Python, 284


< operator, Python, 285, 1019 ; (semicolons)
<< operator, Python, 281 ;&, case-in constructs, 233–234
<= assignment operator ;; (double semicolons), case-in
Jinja2, 1019 constructs, 233–234
Python, 285 ;;&, case-in constructs, 233–234
- (minus signs) Linux notation, 61–62
-= operator, Python, 284 [ ] (square brackets)
- assignment operator, Python, 281 [=] operator, Python, 284
( ) (capture groups), regular [first_literal - last_literal], regular
expressions (regex), 185–186 expressions (regex), 185
% (percentage symbols) [literals], regular expressions (regex),
185
%= operator, Python, 284
Python
Modulo Operator, 274, 281
lists, 286–287
| (pipes), 58, 65–67, 281
strings, 278
| (OR operator)
regular expressions (regex), 185
Python, 281, 285
~ (NOT) operator, Python, 281, 285
regular expressions (regex), 186
|= operator, Python, 284
+ (plus signs) Numbers
+ assignment operator, Python, 281
0-RTT, TLS, 502–503
+= operator, Python, 284
1xx information status codes, 411
regular expressions (regex), 186,
2xx successful status codes, 411–412
189–190, 192
3xx redirection status codes, 412
#! (hashbangs), Linux shell scripting,
205–208 4xx server error status codes,
413–414
? (question marks), regular
expressions (regex), 186, 189, 5xx client error status codes, 414
191–192 200 OK responses, static routing
> (right arrows) DELETE method, 405–406
> Jinja2 operator, 1019 POST method, 394–401
> Python operator, 285 PUT method, 403–404
>= (right arrow, equal sign)
assignment operator, Jinja2,
1019
A
assignment operator, Python, absolute paths
285 Linux directories, 38–39
>> signed right shift operator, XPath expressions, 576–577
Python, 281

Z01_Abuelenain_Index_p1121-p1196.indd 1122 27/03/21 6:37 pm


Ansible 1123

abstraction checking for substrings in


API, 12–13 variables, 1021–1022
defined, 9–13 checking for variables,
1019–1021
NaC, 12
combining multiple conditional
OOP, 257
statements, 1022–1024
single sources of truth, 11–12
Jinja2 templates, 1045–1049
access tokens, OAuth protocol,
with loops, 1024–1027
481–483
with loops and variables,
ACI (Application Centric
1027–1033
Infrastructures), 13
configuring, 991–995
ACL, Linux, 148–155
connection plug-ins, 1003–1004
ad hoc command, Ansible, 994–997
filters, 1013–1015
Adj-SID, 824, 827, 839–842
help, 995–996
AEAD (Authenticated Encryption
with Associated Data), 495–496 installing, 990
AES-CCM protocol, 495 inventories
AES-GCM protocol, 495 default paths, 992
alert protocol, TLS 1.3, 499 IP addresses, 993–994
algorithms, 258–259 simple inventory files,
992–993
ampersands (&),
inventory files, defining variables,
&= operator, Python, 284
1009–1011
AND operator, Python, 281, 285
IOS XE
analyzing cost/benefit analysis, 1112
clearing counters, 1060–1061
anchors, YAML, 624–625
configuring, 1061–1069
AND operator (&), Python, 281,
configuring with ios_* modules,
285–286
1069–1073
AND/OR logic, combining
configuring with iosxr_*
multiple conditional statements,
modules, 1083–1084
1022–1024
preparing for Ansible
Android, Linux distributions, 26
management, 1055–1057
annotation, JSON schemas, 596
preparing for NETCONF
Ansible, 15–16, 989 management, 1095–1096
ad hoc command, 994–997 updating files with additional
basics, 989–990 hosts/variables, 1057–1058
call flows, for a single command, verifying Ansible management,
990–991 1057
conditional statements, 1016–1019 verifying operational data,
AND/OR logic, 1022–1024 1058–1060

Z01_Abuelenain_Index_p1121-p1196.indd 1123 27/03/21 6:37 pm


1124 Ansible

IOS XR structure of, 1000


configuring, 1078–1084 utility modules, 1003
preparing for management, NETCONF
1073–1074 configuring, 1103–1107
preparing for NETCONF IOS XE management,
management, 1096–1098 1095–1096
verifying Ansible management, IOS XR management,
1074–1075 1096–1098
verifying operational data, NX-OS management, 1098
1074–1078
verifying operational data,
ios_command module 1098–1103
clearing counters, NX-OS
1060–1061
collecting show output with
verifying operational data, nxos_command, 1086–1088
1058–1060
configuring, 1090–1095
iosxr_command
interactive commands,
input parameters, 1001 1088–1089
playbooks, 997–999 preparing for management,
verifying operational data, 1084–1085
1074–1078 preparing for NETCONF
Jinja2 templates, 1034–1040 management, 1098
conditional statements, verifying management,
1045–1049 1085–1086
loops, 1040–1043 verifying operational data,
playbooks, 1040–1043 1086–1089
variables, 1042–1043 overview of, 989–990
Linux, host files, 993 playbooks, 990, 997–1000
loops conditional statements
with loops and variables,
conditional statements with 1032–1033
loops, 1024–1027
defining variables, 1005–1006
Jinja2 templates, 1040–1043
Jinja2 templates, 1040–1043
modules
Python, 991–992
control functions, 1001–1002
variables, 999
debug modules, 999
Boolean variables, 1006
file modules, 1003
checking for substrings with
iosxr_command, parameters, conditional statements,
1001 1021–1022
network modules, 1003 checking with conditional
return values, 1001–1002 statements, 1019–1021

Z01_Abuelenain_Index_p1121-p1196.indd 1124 27/03/21 6:37 pm


API (Application Programming Interface) 1125

conditional statements with xAPI, 946


loops and variables, XML API, 945
1027–1033
CUCM Serviceability API, 945
defining from external files,
DNA Center API
1007–1009
device management, 934
defining in inventory files,
1009–1011 Eastbound API, 933
defining in playbooks, event notifications, 935
1005–1006 Integration API, 935–936
dictionary variables, 1007 Intent API, 934, 936–941
importing from external files, Northbound API, 933
1007–1009 Southbound API, 933
Jinja2 templates, 1042–1043 webhooks, 935
list variables, 1007 Westbound API, 933
setting dynamically, 1011–1013 eastbound API, 883
string variables, 1006 endpoints, 882
types of, 1006–1007 IOS XE
version command, 991–992 gNMI, insecure mode, 815
anywhere selection, XPath NETCONF, 918–922
expressions, 576
programmability, 885–886
API (Application Programming
IOS XR
Interface)
NETCONF, 916–918
abstraction, 12–13
programmability, 886–887
automation, 12–13
Linux, 24
AXL API, 944
Meraki API, 922, 923
CER API, 944
Captive Portal API, 923
classifications, 882–883
Dashboard API, 922–931
CLI versus, 8
Location Scanning API, 923
collaboration API, 942–944
MV Sense API, 923
AXL API, 944
Webhook Alerts API, 922
CER API, 944
model-based industry-standard API
CUCM Serviceability API, 945
IOS XE programmability, 885
Finesse Desktop API, 946–947
Open NX-OS programmability,
PAWS API, 944
884
REST API, 945–946, 948–954
NETCONF
TSP API, 945
IOS XE, 918–922
UDS API, 945
IOS XR, 916–918
URL API, 945
NX-OS, 905–916

Z01_Abuelenain_Index_p1121-p1196.indd 1125 27/03/21 6:37 pm


1126 API (Application Programming Interface)

northbound API, 883 webhooks, 882


NX-API CLI, use cases, 893–898 westbound API, 883
NX-API REST, use cases, 898–905 XML API, 945
Open NX-OS transport protocols, 18–19
Bash shells, 887–891 API resource, RESTCONF, 747–749
Guest shells, 887, 891–892 applications
NETCONF, 905–916 developing
programmability, 884–885 different environments, 311
use cases, 887–892 Docker, 317–331
PAWS API, 944 Git, 312–317
platforms, 882 organizing development
Postman, 436–437 environment, 311–312
installing, 438 Python modules, 333–336
interface, 438–441 replicating product environ-
ments, 312
usage, 441–446
reusable code, 312
resource server calls, OAuth
protocol, 483 version control, 311
REST API, 322, 392–393, 945–946, virtualenv tool, 331–333
948–954 Django
RESTful API, 883 creating applications, 341–345
RPC-based API, 883 demo applications, 343–345
rules of thumb, 1118 dockerizing, 326–331
service layer API, IOS XR program- hosting
mability, 886 containerized application
southbound API, 883 hosting, 1116
transport protocols, 18–19 IOS XE programmability, 886
TSP API, 945 IOS XR programmability, 887
UDS API, 945 iPerf, 1116
URL API, 945 native application hosting,
vendor/API matrix, network 1115–1116
programmability, 957–958 Open NX-OS programmability,
web/API development, 336–337 885
back end development, 336 rules of thumb, 1115–1116
Django, 337–345 Linux communication, 24
Flask, 345–352 Python
front end development, 336 machine learning, 382–384
Postman, 337–345 network automation, architec-
tures, 353–354, 371–375

Z01_Abuelenain_Index_p1121-p1196.indd 1126 27/03/21 6:37 pm


authentication 1127

network automation, Jinja2 arrays


templates, 363–375 JSON arrays, 593
network automation, NAPALM Linux scripting
libraries, 354–359
adding/removing elements,
network automation, Nornir 224–226
libraries, 359–363, 367–369,
associative arrays, 222
371–375
concatenating, 221–226
orchestration, 375–382
declaring, 222–224
web/API development, Django,
337–345 defined, 222
web/API development, Flask, indexed arrays, 222–224
345–352 assignment operators, Python, 284
web/API development, 336–337 associative arrays, 222
back end development, 336 asterisks (*)
Django, 337–345 Python
Flask, 345–352 *= operator, 284
front end development, 336 ** assignment operator, 281
Postman, 337–345 **= operator, 284
web servers, running with assignment operator, 281
Django, 338–339 regular expressions (regex), 185,
Arch, Linux distributions, 26 189–190
architectures asymmetric keys, 490
BGP-LS peering architectures, attributes, XML, 558, 568, 570
843–844 augmentation, YANG modules,
Linux, 23–25 656–658
microservice architectures, 782 authentication
network automation, 353–354 host-based authentication, 517–518
archiving utilities, Linux HTTP/1.1, 469–471
bzip2, 67, 69 base64 encoding, 472, 474
gzip, 67–68 basic authentication, 472–474
tar, 67, 70–73 OAuth protocol, 474–483
xz, 67, 69–70, 72–73 UTF-8 encoding, 472–473
Arguments.bash script, Linux workflows, 470
scripting, 213–214 key-based authentication, SSH,
arithmetic operators 523–525
Bash, 220–222, 229 MAC, 493–494
Linux, 220–222 NETCONF, 694
Python, 281–283 Nexus switches, 401–402, 463

Z01_Abuelenain_Index_p1121-p1196.indd 1127 27/03/21 6:37 pm


1128 authentication

password authentication, 517, networks


522–523, 525–526 architectures, 353–354
peer authentication, 496–497 Jinja2 templates, 363–375
public key authentication, 516–517 NAPALM libraries, 354–359,
SSH Authentication Protocol, 371–375
514–516 Nornir libraries, 359–363,
host-based authentication, 367–369, 371–375
517–518 one-time automations, 1111
password authentication, 517, orchestration versus, 6–7
522–523, 525–526
reusing automations, 1111
public key authentication,
rules of thumb, 1109–1112, 1118
516–517
single sources of truth, 11–12
authorization grants, OAuth protocol,
477–481 software/network engineers, 19–20
automation awk programming language, 194–197
API, 12–13 AXL API, 944
benefits, 6
broken processes, 1110 B
cloud computing, 1118
back end web/API development, 336
complexity, 1111–1112
backslashes (\), regular expressions
configuration management
(regex), 186
automation
\<, regular expressions (regex), 185,
IOS XE programmability, 886
188–189
Open NX-OS programmability,
\>, regular expressions (regex), 185,
885
188–189
cost/benefit analysis, 1112
base64 encoding, HTTP/1.1
defined, 5–6 authentication, 472, 474
model-driven telemetry, 1113–1114 Bash, 184
Network Programmability and Arguments.bash script, 213–214
Automation toolbox, 14–15
arithmetic operators, 220–222, 229
Ansible. See also separate
CLI programmable interface creation,
entry, 15–16
963–967
Linux, 16–17
Expect programming language,
protocols, 18–19 245–246
Python, 15 file comparison operators, 230–232
virtualization, 17 functions, 244
YANG, 17 HTTP, 447–454

Z01_Abuelenain_Index_p1121-p1196.indd 1128 27/03/21 6:37 pm


career paths, software/network engineers 1129

integer comparison operators, Boolean variables, Ansible, 1006


229–230 boot directory, Linux, 36
IOS XR programmability, 886 boot process, Linux, 26–28
Linux, 29 broken processes, automation, 1110
Linux interface configuration, buffered/unbuffered access,
969–970 Linux /dev directory, 120
Open NX-OS, 884, 887–891 built-in data types, YANG modules,
scripting, 206–207, 213–214 647–648
SSH, 539–540, 548–549 Business Edition (Cisco), 942
string comparison operators, bytecode, Python, 265–267
228–229 generators, 264
string operators, 227–228 interpreters, 264
Bearer Tokens, HTTP, 475–476 bzip2 archiving utility, Linux, 67, 69
beginnings/endings of words,
matching, regular expressions
(regex), 188–189 C
benefit/cost analysis automation,
call flows, PCEP, 861–864
1112
<cancel-commit> operations,
BGP, SR-TE, 836–843
NETCONF, 722–724
BGP-LS (BGP-Link State), 843
candidate configuration, NETCONF,
lab topologies, 845–846 722–724, 732
link NLRI, 856–857 capabilities, NETCONF, 731
node NLRI, 854–855 candidate configuration capability,
NPF-XR, 845, 849, 851–854 732
peering, 843–844, 847–849 confirmed commit capability, 732
prefix NLRI, 858–859 distinct startup capability, 733
routing, 846–847 rollback-on-error capability, 732–733
routing types (overview), 850–854 URL capability, 733–734
bidirectional RPC, 785 validate capability, 733
binary message framing, HTTP/2, writable-running capability, 732
506–507 XPath capability, 735
BIOS (Basic Input/Output Capabilities RPC, gNMI, 810–811
Systems), 27
CAPEX (Capital Expenditures), 2
bitwise operators, Python, 281–283
Captive Portal API (Meraki), 923
blkid command, Linux, 148–149
capture groups ( ( ) ), regular
block ciphers, 492–493 expressions (regex), 185–186
blocking, head-of-line, 504 career paths, software/network
Boolean data, JSON, 593 engineers, 1118–1119

Z01_Abuelenain_Index_p1121-p1196.indd 1129 27/03/21 6:37 pm


1130 carets (^)

carets (^) ciphers, 492


^= operator, Python, 284 block ciphers, 492–493
regular expressions (regex), 185, 187 CBC, 492–493
XOR operator, 281 CMAC, 494
case-in constructs, Linux scripting, CTR mode, 492–493
232–234 symmetric ciphers, 492
;&233–234 Cisco Business Edition, 942
;;, 233–234 Cisco collaboration portfolio, 942–944
;;&233–234 Cisco devices
cat command, 41–42, 61–62 server status codes, 414
cat/proc/cpuinfo command, Linux, SSH setup, 545–549
87–88 Cisco Finesse, 943, 946–947
CBC (Cipher Block Chaining), Cisco IOS XE
492–493
Ansible
CCM (Counter with CBC mode),
clearing counters, 1060–1061
495–496
configuring IOS XE, 1061–1069
CentOS
configuring IOS XE with ios_*
Docker
modules, 1069–1073
containers, 322–325
configuring IOS XR with
installing, 318–320 iosxr_* modules, 1083–1084
Git, setting up, 313–314 preparing IOS XE for Ansible
OpenSSH installations, 522 management, 1055–1057
SCP, 549–550 preparing IOS XE for
SSH setup, 521–526 NETCONF management,
1095–1096
CER API, 944
updating files with additional
changing
hosts/variables, 1057–1058
CLI, 19 verifying IOS XE for Ansible
file users/groups, Linux, 146 management, 1057
channels, SSH Connection Protocol, verifying operational data,
518–521 1058–1060
character classes, matching uppercase/ SSH setup, 526–531, 545–546
lowercase characters in regular Cisco IOS XR
expressions (regex), 187–188
Ansible
child/parent relationships, XML,
configuring IOS XR, 1078–1084
555–556
preparing for management,
chmod command, Linux, 144–146
1073–1074
chown command, Linux, 146
preparing IOS XR for
Chrome (Google), LocalRepo NETCONF management,
repositories, 114–117 1096–1098

Z01_Abuelenain_Index_p1121-p1196.indd 1130 27/03/21 6:37 pm


code execution, Python 1131

verifying IOS XR for Ansible transport protocols, 19


management, 1074–1075 unstructured data, 19
verifying operational data, client registration, OAuth protocol,
1074–1078 476–477
PCEP configurations, 867–880 client requests, HTTP, 388–392,
SSH setup, 532–536, 546–547 397–398
Cisco IP Phones, 944 CONNECT method, 407
Cisco Meeting Server, 943 DELETE method, 405–406
Cisco Unified Contact Center, 943 GET method, 398
Cisco Webex Board, 943 Bash shells, 447–454
Cisco Webex Cloud Calling, 942 Postman, 445–446
Cisco Webex Contact Center, 943 HEAD method, 398
Cisco Webex Meetings, 943 header fields, 422–425
REST API, 945–946, 948–954 OPTIONS method, 407–408
TSP API, 945 POST method, 399–402
URL API, 945 Postman, 443–445
XML API, 945 Python and HTTP, 465
Cisco Webex Room Series, 944 PUT method, 402–405
Cisco Webex Support, 943 TRACE method, 408
Cisco Webex Teams, 942, 945–946, client/server connections, HTTP,
948–954 394–395
classes, Python modules, 335–336 client-streaming RPC, 785
cleaning up networks, 1110 cloning
clear command, 30 git repositories, 316–317
CLI (Command-Line Interface) YANG modules, 665
API versus, 8 <close-session> operations,
changing, 19 NETCONF, 721–722
command shell, Linux, 28–30 cloud computing
loopback interfaces, CLI programma- Cisco Webex Cloud Calling, 942
bility, 962–963 rules of thumb, 1118
network programmability, 958–959, CMAC (Cipher-based MAC), 494
962–967 CMDB (Configuration Management
NX-API CLI Database), 12
Open NX-OS programmability, code execution, Python, 263–269
884 bytecode, 265–267
use cases, 893–898 generators, 264
as programmable CLI, 962–967 interpreters, 264

Z01_Abuelenain_Index_p1121-p1196.indd 1131 27/03/21 6:37 pm


1132 code execution, Python

code testing/verification, 269 collections, YAML, 618–620


compiling code, 265–266 command shell, Linux, 28–30
executable Python files, 265 comments
lexical analyzers, 263 Linux scripting, 207–208
numeric data, 269 XML, 558
simple Python program, 264 YAML, 616
tokenizers, 263 <commit> operations, NETCONF,
collaboration 722–724
API, 942–944 commit phase, Git workflows, 317
AXL API, 944 compact GBP, 1113–1114
CER API, 944 comparison operators
CUCM Serviceability API, 945 Jinja2, 1018–1019
Finesse Desktop API, 946–947 Python, 284–285
PAWS API, 944 compiling
REST API, 945–946, 948–954 Linux software installations, 94,
96–97
TSP API, 945
Python code, 265–266
UDS API, 945
complex elements, XML validation,
URL API, 945
570–573
xAPI, 946
complex numbers, Python, 276
XML API, 945
compose versions, Docker, 320–322
Cisco collaboration portfolio,
compression, HTTP/1.1, 396–397
942–944
computer science concepts, 255
endpoints, 943
concatenating
Cisco IP Phones, 944
arrays, 221–226
Cisco Webex Room Series, 944
strings, Python, 277
platforms, API, 942
conditional statements
AXL API, 944
Ansible, 1016–1019
CER API, 944
checking for substrings in
CUCM Serviceability API, 945
variables, 1021–1022
Finesse Desktop API, 946–947
checking for variables,
PAWS API, 944 1019–1021
REST API, 945–946, 948–954 combining multiple conditional
TSP API, 945 statements, 1022–1024
UDS API, 945 conditional statements with
URL API, 945 loops, 1024–1027
xAPI, 946 conditional statements
with loops and variables,
XML API, 945
1027–1033

Z01_Abuelenain_Index_p1121-p1196.indd 1132 27/03/21 6:37 pm


CONNECT method 1133

Jinja2 templates, 1045–1049 IOS XR with Ansible, general


AND/OR logic, 1022–1024 configuration, 1078–1083
Jinja2 templates, 1045–1049 NETCONF, 1103–1107
Linux scripting, 226 <cancel-commit> operations,
722–724
== (double equal sign), 229
candidate configuration
= (equal sign), 229
operations, 722–724
case-in constructs, 232–234
<close-session> operations,
if-then constructs, 226–232 721–722
nested code blocks with conditional <commit> operations, 722–724
statements, Python control flow,
configuration validation,
295–296
724–725
conferencing, 943
<copy-config> operations, 719
Cisco Meeting Server, 943
datastore configurations,
Cisco Webex Meetings, 943 712–720
REST API, 945–946, 948–954 datastore operations, 720–721
TSP API, 945 <delete-config> operations,
URL API, 945 719–720
XML API, 945 <discard-changes> operations,
Cisco Webex Support, 943 722–724
configuration files, Linux networking, <edit-config> operations,
174–179 712–719
configuration management <kill-session> operations,
automation 721–722
IOS XE programmability, 886 <lock> operations, 720–721
IOS XR programmability, 887 session operations, 721–722
Open NX-OS programmability, 885 <unlock> operations, 720–721
configuring <validate> operations, 724–725
Ansible, 991–995 NX-OS
candidate configuration capability, with nx-os_* modules,
NETCONF, 732 1093–1095
CMDB, 12 with nx-os_config modules,
1086–1088
IOS XE with Ansible
YAML configuration files, building,
general configuration,
635–637
1061–1069
confirmed commit capability,
with ios_* modules, 1069–1073
NETCONF, 732
with iosxr_* modules,
CONNECT method, 407
1083–1084

Z01_Abuelenain_Index_p1121-p1196.indd 1133 27/03/21 6:37 pm


1134 connection plug-ins, Ansible

connection plug-ins, Ansible, copying


1003–1004 directories, Linux, 49–51
connections, NetworkManager files, Linux, 46–48
attributes, 169–170 public keys onto servers, 524–525
creating, 171–174 SCP
deleting, 171–174 CentOS, 549–550
listing, 169 SFTP comparisons, 550
constructors, Python modules, cost/benefit analysis, automation,
335–336 1112
Contact Center, 942–943 costs
container nodes, YANG data CAPEX, 2
modeling, 652–653
human operations, 2
containerized application hosting,
networks, 2
1116
OPEX, 2
containers
cp command, 46–48, 49–51
Docker, 1115
CRLF, HTTP messages, 415, 418
Docker Swarm, 1115
cryptography, 488, 495–496
hello-world containers,
322–325 AEAD, 495–496
virtualization, 317–318 AES-CCM protocol, 495
Kubernetes, 1115 AES-GCM protocol, 495
rules of thumb, 1114–1115 CCM, 495
content layer ciphers, 492
NETCONF, 693, 725–730 block ciphers, 492–493
RESTCONF, 743 CBC, 492–493
content parameter, RESTCONF, 771 CMAC, 494
control flow, Python CTR mode, 492–493
elif statements, 297–298 symmetric ciphers, 492
for loops, 301–302, 306 digital signatures, 496–497
nested for loops, 303–304 encryption keys, 488–489
range() function, 302–303 asymmetric keys, 490
if-else statements, 296–300 DH protocol, 490–492
nested code blocks with conditional ephemeral keys, 490
statements, 295–296 generation/exchanges, 488–492
while loops, 304–306 HKDF, 492
cookies, HTTP state management, key exchange algorithm, 490
483–487 KM, 492
<copy-config> operations, 719 PFS, 490

Z01_Abuelenain_Index_p1121-p1196.indd 1134 27/03/21 6:37 pm


data structures, Python 1135

PSK, 489 home of, 664–666


symmetric keys, 489 IETF YANG modules, 670–671
GCM, 495 native (vendor-specific)
MAC, 493–494 modules, 666–669
peer authentication, 496–497 OpenConfig YANG modules,
671–673
.csv files, 1052
structure of, 644–646
CTR mode, ciphers, 492–493
verifying downloaded modules,
CUCM (Cisco Unified
665–666
Communications Manager), 942
nodes, 649
AXL API, 944
container nodes, 647–648
CER API, 944
grouping, 654–656
CUCM Serviceability API, 945
leaf nodes, 649–651
PAWS API, 944
leaf-list nodes, 651–652
UDS API, 945
list nodes, 647–648
curly braces ({ })
pyang, 673–679, 683–687
{N}, regular expressions (regex), 186,
189–192 pyangbind, 679–682
{N, M}, regular expressions (regex), YANG 1.1, 662–663
186, 189–192 data plane verification
regular expressions (regex), 185 SR, 830–831
SR-TE, 842–843
D data resource, RESTCONF, 753–756
data streams, YAML
daemons, Linux, 24 saving to files, 629
dashes (-) sorting, 630–631
-= operator, Python, 284 data structures, Python, 286
assignment operator, Python, 281 dictionaries, 290–291
Dashboard API (Meraki), 922–931 deleting, 292
data modeling, YANG, 642 functions, 292
defined, 639–640 if-else statements, 299–300
importance of, 640–642 lists, 286–288
modules, 642–644 functions, 288–289
augmentation, 656–658 if-else statements, 298–299
built-in data types, 647–648 nested lists, 289–290
cloning, 665 slicing, 286–287
derived data types, 648–649 square brackets ([ ]), 286–287
deviations, 658–662 value assignments, 286–288

Z01_Abuelenain_Index_p1121-p1196.indd 1135 27/03/21 6:37 pm


1136 data structures, Python

sets, 294–295 deleting


tuples connections, NetworkManager,
deleting, 293 171–174
functions, 292–293 dictionaries, Python, 292
joining, 293 directories, Linux, 50–51
data types files, Linux, 47, 48
JSON, 592–594 groups, Linux user/group manage-
ment, 141–142
numbers, Python, numbers, 273–276
tuples, Python, 293
numbers data types, Python,
numbers, 273–276 users, Linux user/group management,
141
Python, 270, 276–280
variables, Python, 272–273
XML, 567–568
dependencies, software, 95
data validation, JSON schemas,
609–614 dependency hell, 1114–1115
databases, rules of thumb, 1117 depsolve, 95
datastores depth parameter, RESTCONF, 771
NETCONF derived data types, YANG modules,
648–649
configuring datastores,
712–720 /dev directory, Linux storage, 36,
119–120
datastore operations, 720–721
contents of, 120
RESTCONF, 749–750
device file types, 120–121
date command, Linux, 85–86
fdisk command, 121–125
Debian, Linux distributions, 26
file system creation, 125–126
debugging
hard disk partitions, 121–125
debug modules, Ansible, 999
mkfs command, 125–126
SSH, 528–531, 533–534
mounting file systems, 126–128
decision tree algorithms, Python
machine learning, 382–384 unmounting file systems, 127
declaring developing applications
arrays, Linux scripting, 222–224 different environments, 311
variables, Linux scripting, 218–219 Docker, 317
XML declarations, 566–567 CentOS containers, 322–325
delegating PCEP, LSP delegation, clients, 322
864–867 commands list, 325–326
<delete-config> operations, 719–720 components of, 322
DELETE method, 405–406, 770–771 compose versions, 320–322

Z01_Abuelenain_Index_p1121-p1196.indd 1136 27/03/21 6:37 pm


dict.keys() function, Python 1137

container virtualization, network automation, Nornir


317–318 libraries, 359–363, 367–369,
docker images command, 325 371–375
docker pull command, 325 orchestration, 375–382
Dockerfile instructions, web/API development, Django,
326–328 337–345
dockerizing applications, web/API development, Flask,
326–331 345–352
hello-world containers, replicating product environments,
322–325 312
installing, 318–320 reusable code, 312
Python orchestration, 376–378 version control, 311
REST API, 322 virtualenv tool, 331
servers, 322 creating virtual environments,
332–333
verifying, 320–322
installing, 331
Git
web/API development, 336–337
commit phase, 317
back end development, 336
flexibility, 312
Django, 337–345
initialization commands, 314
Flask, 345–352
performance, 312
front end development, 336
pull phase, 317
Postman, 337–345
push phase, 317
deviations, YANG modules, 658–662
repositories, 312–313, 314–317
device drivers, Linux, 23
security, 312
device management, DNA Center,
server setup, 313–314
934
workflows, 317
device mappers, 135
organizing development environment,
DH (Diffie-Hellman) protocol,
311–312
490–492
Python
dictionaries, Python, 290–291,
machine learning, 382–384 583–585
modules, 333–336 deleting, 292
network automation, functions, 292
architectures, 353–354,
if-else statements, 299–300
371–375
dictionary variables, Ansible, 1007
network automation, Jinja2
templates, 363–375 dict.items() function, Python, 292
network automation, NAPALM dict.keys() function, Python, 292,
libraries, 354–359, 371–375 307–308

Z01_Abuelenain_Index_p1121-p1196.indd 1137 27/03/21 6:37 pm


1138 dict.values() function, Python

dict.values() function, Python, 292 direct-tcpip channels, SSH


dig command, Linux, 180–181 Connection Protocol, 521
digital signatures, 496–497 disabling password authentication,
525–526
directories
<discard-changes> operations,
Linux, 48–49
NETCONF, 722–724
/: root directory, 36
distinct startup capability, NETCONF,
absolute paths, 38–39 733
attributes, 40–41 distributions, Linux, 26
boot directory, 36 Django, web/API development, 337
copying, 49–51 application web servers, 338–339
creating, 49, 51 creating applications, 341–345
deleting, 50–51 demo applications, 343–345
dev directory, 36 installing, 337–338
double dot notation (..), 37 migrations, 338–339
etc directory, 36 models.py files, 343
home directory, 36 serializer.py files, 343
media directory, 37 settings.py files, 339–341
mnt directory, 37 starting new projects, 337–338
moving, 49, 51 urls.py files, 343
navigating, 38–41 views.py files, 343
opt directory, 37 dmesg command, Linux, 90
proc directory, 37 dmidecode command, Linux, 88–89
relative paths, 38–39 DNA Center, 931–933
renaming, 50–51 device management, 934
root directory, 37 Eastbound API, 933
run directory, 37 event notifications, 935
srv directory, 37 Integration API, 935–936
sys directory, 37 Intent API, 934, 936–941
tmp directory, 37 Northbound API, 933
usr directory, 37 Southbound API, 933
usr/bin directory, 37 webhooks, 935
usr/local directory, 37 Westbound API, 933
usr/sbin directory, 37 DNF (Dandified YUM), 95, 117
var directory, 37 DNS (Domain Name System),
local/remote directory operations, 179–181
SFTP, 542–543 Docker, 317, 1115

Z01_Abuelenain_Index_p1121-p1196.indd 1138 27/03/21 6:37 pm


endings/beginnings of words, matching with regular expressions (regex) 1139

CentOS containers, 322–325 DTD (Document Type Definition),


clients, 322 563
commands list, 325–326 example of, 563–564
components of, 322 joint XML/DTD files, 564–565
compose versions, 320–322 dynamic data type allocation, Python,
271–272
containers, virtualization, 317–318
dynamically setting Ansible variables,
docker images command, 325
1011–1013
docker pull command, 325
Docker Swarm, 1115
Dockerfile instructions, 326–328
E
dockerizing applications, 326–331 eastbound API, 883, 933
hello-world containers, 322–325 echo command, Linux, 208–210,
installing, 318–320 222–226
Python orchestration, 376–378 <edit-config> operations, 712–719
REST API, 322 elif statements, Python control flow,
servers, 322 297–298
verifying, 320–322 encapsulation, OOP, 257
documentation, rules of thumb, 1111 encoding protocols, 18
dollar signs ($) metacharacter, regular encryption
expressions (regex), 185, 187 AEAD, 495–496
dots (.) keys, 488–489
.* notation, regular expressions asymmetric keys, 490
(regex), 190 DH protocol, 490–492
.. notation, Linux directories, 37 ephemeral keys, 490
regular expressions (regex), 185, 189 generation/exchanges, 488–492
double asterisks (**), assignment HKDF, 492
operator, Python, 281
key exchange algorithm, 490
double dot notation (..), Linux
KM, 492
directories, 37
PFS, 490
double equal sign (==)
PSK, 489
conditional statements, 229
symmetric keys, 489
Jinja2, 1019
end tags, XML, 555
Python, 285
endings/beginnings of words,
double semicolons (;;), case-in
matching with regular expressions
constructs, 233–234
(regex), 188–189
DRY principle, 311, 336

Z01_Abuelenain_Index_p1121-p1196.indd 1139 27/03/21 6:37 pm


1140 endpoints

endpoints fdisk command, Linux, 121–125


API, 882 fetching/uploading files via SFTP, 543
collaboration endpoints, 943 fields parameter, RESTCONF, 771,
Cisco IP Phones, 944 773–777
Cisco Webex Room Series, 944 file comparison operators, Bash
shells, 230–232
Enoch, Linux distributions, 26
file modules, Ansible, 1003
entity bodies, HTTP, 391
files
entity header fields, HTTP, 416,
427–430 Linux
EPEL repositories, 111–112 attributes, 40–41
ephemeral keys, 490 copying, 46–48
equal sign (=) creating, 46
assignment operator, Python, 284 deleting, 47, 48
conditional statements, 229 moving, 47, 48
double equal sign (==) permissions, 40
conditional statements, 229 removing, 47, 48
Jinja2 operator, 1019 renaming, 47, 48
Python operator, 285 permissions, changing with SFTP,
544–545
error reporting, RESTCONF, 746
security management, Linux
etc directory, Linux, 36
ACL, 148–155
event notifications, DNA Center, 935
changing file users/groups, 146
exit() function, Python, 272
creating files under different
Expect programming language, Linux
groups, 147
scripting, 245–246
default users/groups of new
expressions, XPath, 575–576
files, 147
absolute path, 576
logging into different groups,
absolute path and multiple outputs, 147–148
577
permissions, 143–146,
anywhere selection, 576 150–152
path definitions, 578 file systems, Linux, 35–37
predicates, 577 creating file systems, 125–126
external JSON schemas, referencing, mounting file systems, 126–128
602–609
unmounting file systems, 127
filter parameter, RESTCONF, 771
F filters, Ansible, 1013–1015
finding sources of truth, 1110–1111
FCAPS (Fault, Configuration,
Accounting, Performance, findmnt command, Linux, 148–149
Security), 3 Finesse (Cisco), 943, 946–947

Z01_Abuelenain_Index_p1121-p1196.indd 1140 27/03/21 6:37 pm


Git 1141

firewalld service, 155–158 frames, HTTP/2, 504–505


Flask, web/API development binary message framing, 506–507
accessing in-memory employee data, multiplexing, 505–506
347–349 from-import statements, Python
installing in virtual environments, modules, 334–335
345–346 front end web/API development, 336
retrieving ID-based data, 349–350 funcname() function, Python, 307
simple applications, 346–347 functions
float() function, Python, 275 Linux scripting, 240–244
floating point data, Python, 275 Python, 306–307
flow control, Python calling in code blocks, 307–309
elif statements, 297–298 defining in code blocks,
for loops, 301–302, 306 307–309
nested for loops, 303–304 dictionary functions, 292
range() function, 302–303 representations, 307
if-else statements, 296–300
nested code blocks with conditional
statements, 295–296
G
while loops, 304–306 GBP, compact GBP, 1113–1114
for-do loops, 235–237 GCM (Galois/Counter Mode), 495
for loops, Python control flow, 301– general header fields, HTTP, 416,
302, 306 418–422
nested for loops, 303–304 <get> operations, NETCONF,
range() function, 302–303 702–703
format() function, Python, 280 <get-config> operations, NETCONF,
702–703
formatting
GET method
strings, Python, 280
HTTP client requests, 398
XML, 561–562
Bash shells, 447–454
forward slash (/)
Postman, 445–446
/: root directory, Linux, 36
request messages, 389–391, 416–417
/= operator, Python, 284
RESTCONF, 760–763
assignment operator, Python, 281
Get RPC, gNMI, 801–807
forwarded-tcpip channels, SSH
Connection Protocol, 520–521 getfacl command, Linux, 149–155
forwarding Git
interfaces, Linux networking, 167 commit phase, 317
SR, 832 flexibility, 312

Z01_Abuelenain_Index_p1121-p1196.indd 1141 27/03/21 6:37 pm


1142 Git

initialization commands, 314 grouping nodes, YANG data modeling,


performance, 312 654–656
pull phase, 317 group/user management, Linux,
136–138
push phase, 317
creating
repositories, 312–313
groups, 141
cloning, 316–317
new users, 138–141
fetching remote repository
updates, 314–315 deleting
setting up, 315–316 groups, 141–142
updating local repositories, users, 141
314–315 getting user information, 136
security, 312 modifying user details, 142
server setup, 313–314 passwords
workflows, 317 changing, 141
gNMI (gRPC Network Management setting user passwords, 138–141
Interface), 798–799 gRPC (Google Remote Procedure
anatomy of, 799–801 Calls)
Capabilities RPC, 810–811 gNMI, 798–799
Get RPC, 801–807 anatomy of, 799–801
insecure mode, IOS XE, 815 Capabilities RPC, 810–811
managing network elements, Get RPC, 801–807
814–818 insecure mode, IOS XE, 815
network programmability, 961–962 managing network elements,
Python 814–818
metaclasses, 815–816 Python, metaclasses, 815–816
sample Get script, 816–818 Python, sample Get script,
Set RPC, 807–810 816–818
Subscribe RPC, 811–814 Set RPC, 807–810
GNU Bash Manual, 184 Subscribe RPC, 811–814
GNU C library (glibc), 24 history of, 782–784
GNU info files, 35 networks
Google Chrome, LocalRepo managing network elements,
repositories, 114–117 814–818
grep command, regular expressions programmability, 961–962
(regex), 184–193 principles of, 782–784
groupadd command, Linux, 141 Protobuf
groupdel command, Linux, 141–142 example of, 788–789
in Python, 790–798

Z01_Abuelenain_Index_p1121-p1196.indd 1142 27/03/21 6:37 pm


HTTP (HyperText Transfer Protocol) 1143

server sample, 794–797 hierarchical inheritance, OOP, 257


as a transport, 784–786 history command, 30
guest shells HKDF (HMAC-based Extract-and-
IOS XE programmability, 885 Expand Key Derivation Function),
492
Open NX-OS, 884, 887, 891–892
HMAC (Hash function-based MAC),
GUI and Linux CLI, 28–29
494
gzip archiving utility, Linux, 67–68
home directory, Linux, 36
host-based authentication, 517–518
H hosting applications
containerized application hosting,
handshake protocol, TLS 1.3, 499–
1116
502
iPerf, 1116
hard disk partitions, /dev directory,
121–125 native application hosting, 1115–1116
hard links, Linux, 51–55 rules of thumb, 1115–1116
hashbangs (#!), Linux shell scripting, HTTP (HyperText Transfer Protocol),
205–208 414
head and tail command, 45–46 Bash shells, 447–454
HEAD method client requests, 388–392, 397–398
HTTP client requests, 398 CONNECT method, 407
RESTCONF, 763 DELETE method, 405–406
headers, HTTP, 389–391 GET method, 398
client request header fields, 422–425 GET method, Bash shells,
447–454
entity header fields, 416, 427–430
GET method, Postman,
general header fields, 416, 418–422
445–446
overview of, 416–418
HEAD method, 398
request header fields, 416
header fields, 422–425
response header fields, 416
OPTIONS method, 407–408
server response header fields, 425–427
POST method, 399–402,
head-of-line blocking, 504 443–445, 465
hello messages, NETCONF, 696–698, PUT method, 402–405
973–974
TRACE method, 408
hello-world containers, Docker,
client/server connections, 394–395
322–325
entity bodies, 391
help
entity header fields, 427–430
Ansible, 995–996
GET, request messages, 389–391,
Linux, 31–35
416–417
SFTP, 541–542

Z01_Abuelenain_Index_p1121-p1196.indd 1143 27/03/21 6:37 pm


1144 HTTP (HyperText Transfer Protocol)

headers, 389–391 messages


client request header fields, CRLF, 416, 418
422–425 format of, 415
entity header fields, 416, headers, client request header
427–430 fields, 422–425
general header fields, 416, headers, entity header fields,
418–422 416, 427–430
overview of, 416–418 headers, general header fields,
request header fields, 416 416, 418–422
response header fields, 416 headers, overview of,
server response header fields, 416–418
425–427 headers, request header fields,
HTTP/1.1, 388, 504 416
authentication, 469–471 headers, response header fields,
416
authentication, base64
encoding, 472, 474 headers, server response
header fields, 425–427
authentication, basic
authentication, 472–474 HTTP/2, 504–505
authentication, OAuth protocol, start lines, 415
474–483 whitespaces, 416
authentication, UTF-8 methods, 389
encoding, 472–473 CONNECT method, 407
authentication, workflows, 470 DELETE method, 405–406
compression, 396–397 GET method, 398
persistent connections, GET method, Bash shells,
395–396 447–454
pipelining, 396 GET method, Postman,
HTTP/2, 503–504, 507–508 445–446
frames, 504–505 HEAD method, 398
frames, binary message OPTIONS method, 407–408
framing, 506–507 POST method, 399–402,
frames, multiplexing, 505–506 443–445, 465
messages, 504–505 PUT method, 402–405
streams, 505 TRACE method, 408
HTTP/3, 504 overview, 387–392
HTTPS, 503 POST method
hyperlinks, 388 Flask, 350–352
hypertext, 388 RESTCONF, 740, 745–746

Z01_Abuelenain_Index_p1121-p1196.indd 1144 27/03/21 6:37 pm


initialization commands, Git 1145

Postman, 436–437 TCP over Python, 455–457


installing, 438 transactions, 389
interface, 438–441 client requests, 397–408
Python server status codes, 408–414
requests packages, 464–467 as transfer protocol, 387
socket modules, 455–457 URI, 389, 431, 432–436
TCP over Python, 455–457 urllib packages, 458–463
urllib packages, 458–463 versions of, 388
REST, framework, 392–394 HTTPS (HTTP over TSL), 503
RESTCONF, 740 human operations, costs, 2
HTTP headers, 745–746 hyperlinks, 388
request messages, 740 hypertext, 388
response messages, 740
RFC 2616, 416 I
RFC 3986, 393–394
RFC 6265, 484 IaC (Infrastructure as Code), .
See also NaC, 12
RFC 6749, 475–476
IBN (Intent-Based Networking)
RFC 6750, 475–476
defined, 13–14
RFC 7230, 416–417
intent assurance, 14
RFC 7231, server status codes,
409–410 intent fulfillment, 14
RFC 7540, 388 id command, Linux, 136
server status codes, 408–409 identity operators, Python, 284–285
1xx information status codes, IETF drafts, SDN, 823
411 IETF YANG modules, 670–671
2xx successful status codes, if-else statements, Python control
411–412 flow, 296–300
3xx redirection status codes, if-then constructs, Linux scripting,
412 226–232
4xx server error status codes, import statements, Python modules,
413–414 333–334
5xx client error status codes, importing Ansible variables from
414 external files, 1007–1009
Cisco devices, 414 indexed arrays, 222–224
RFC 7231, 409–410 info command, 35
socket modules, 455–457 inheritance, OOP, 256–257
state management with cookies, initialization commands, Git, 314
483–487

Z01_Abuelenain_Index_p1121-p1196.indd 1145 27/03/21 6:37 pm


1146 inode numbers

inode numbers, 40 interface state (Linux), toggling, 161


input() function, Python, 298 interfaces, network programmability
input, Linux scripting, 213 CLI programmable interfaces,
Arguments.bash script, 213–214 962–967
read command, 214–217 Linux, 967–973
input/output redirection, Linux, NETCONF/YANG, 973–978
57–59 RESTCONF/YANG, 978–987
>> notation, 61–62 interpreters, 28
piping (|), 58, 65–67 inventories, Ansible
stderr, 59, 62–65 default paths, 992
stdin, 59, 61 IP addresses, 993–994
stdout, 59, 61, 62–65 simple inventory files, 992–993
tee command, 66–67 inventory files, Ansible,
insecure mode, gNMI in IOS XE, 815 1009–1011
insert parameter, RESTCONF, 771 IOS XE
installing Ansible
Ansible, 990 clearing counters, 1060–1061
Django, 337–338 configuring IOS XE,
1061–1069
Docker, 318–320
configuring IOS XE with ios_*
Flask in virtual environments,
modules, 1069–1073
345–346
configuring IOS XR with
OpenSSH, CentOS installations, 522
iosxr_* modules, 1083–1084
Postman, 438
preparing IOS XE for Ansible
protoc on Python, 790–791 management, 1055–1057
Python, 260–263 preparing IOS XE for
software on Linux, 94–96 NETCONF management,
virtualenv tool, 331 1095–1096
instance identifiers, 850 updating files with additional
hosts/variables, 1057–1058
int() function, Python, 275
verifying IOS XE for Ansible
integer comparison operators, Bash
management, 1057
shells, 229–230
verifying operational data,
integer operations, Python, 275
1058–1060
Integration API, DNA Center,
gNMI, insecure mode, 815
935–936
Jinja2 templates, 367–371
Intent API, DNA Center, 934,
936–941 NETCONF, 918–922
intent assurance, 14 programmability, 885–886
intent fulfillment, 14 SSH setup, 526–531, 545–546

Z01_Abuelenain_Index_p1121-p1196.indd 1146 27/03/21 6:37 pm


JSD (JSON Schema Definition) 1147

IOS XR
Ansible
J
configuring IOS XR, Jinja2
1078–1084
!= operator, 1019
preparing for management,
< operator, 1019
1073–1074
<= operator, 1019
preparing IOS XR for
NETCONF management, > operator, 1019
1096–1098 >= operator, 1019
verifying IOS XR for Ansible comparison operators, 1018–1019
management, 1074–1075 Python functions, 1049
verifying operational data, join() function, 1050–1051
1074–1078
map() function, 1054–1055
Jinja2 templates, 367–371
split() function, 1051–1054
NETCONF, 916–918
templates, 363–364, 1034–1040
PCEP configurations, 867–880
conditional statements,
programmability, 886–887 1045–1049
SSH setup, 532–536, 546–547 IOS XE, 367–371
ios_command module, Ansible IOS XR, 367–371
clearing counters, 1060–1061 loops, 1040–1043
verifying operational data, 1058–1060 NAPALM libraries, 371–375
iosxr_command, Ansible Netmiko libraries, 364–367
input parameters, 1001 Nornir libraries, 367–369,
playbooks, 997–999 371–375
verifying operational data, 1074–1078 NX-OS, 367–371
IP addresses nx-os_config modules,
adding to/removing from Linux 1091–1093
interfaces, 161–162 playbooks, 1043–1045
Ansible inventories, 993–994 variables, 1042–1043
ip command, Linux, 158–167 YAML and, 635–637
IP Phones (Cisco), 944 jobs, Linux, 74
IP VPN, JSON schemas, 597–598, displaying status, 80
601–602, 607–609 stopping, 80–81
iPerf, application hosting, 1116 join() function, 1050–1051
IS-IS IGP, SR configuration, 825–827 joining tuples, Python, 293
is not operator, Python, 285 joint XML/DTD files, 564–565
is operator, Python, 285 journald command, Linux, 93–94
ITIL 4 management practices, 3–5 JSD (JSON Schema Definition), 595

Z01_Abuelenain_Index_p1121-p1196.indd 1147 27/03/21 6:37 pm


1148 JSON (JavaScript Object Notation)

JSON (JavaScript Object Notation) repetitive objects, 598–602


arrays, 593 structure of, 595–598
Boolean data, 593 validation keywords, 596–597
characteristics, 591 strings, 593
data example, 591–592 YAML versus, 615–616
data format, 592–594 JTOX drivers and pyang, 683–687
data types, 592–594
defined, 591 K
JSD, 595
JTOX drivers and pyang, 683–687 kernels, Linux
null values, 593 kernel space, 23–24
numbers, 593 LKM, 25
objects microkernel kernels, 25
key/pair values, 592 monolithic kernels, 25
out of range objects and data SCI, 24
validation, 613–614 key/pair values, JSON objects, 592
referencing external JSON keys
schemas, 606–607 authentication, SSH, 523–525
repetitive objects, 598–602 encryption, 488–489
simple JSON object example, asymmetric keys, 490
592
DH protocol, 490–492
typos and data validation,
ephemeral keys, 490
611–612
generation/exchanges, 488–492
unexpected keys and data
validation, 612–613 HKDF, 492
schemas key exchange algorithm, 490
annotation, 596 KM, 492
basic schema without content, PFS, 490
596–597 PSK, 489
data validation, 609–614 symmetric keys, 489
definitions in, 598–601 RSA keys, Linux network
IP VPN, 597–598, 601–602, programmability, 971–973
607–609 keywords, JSON schemas, 596
JSD, 595 kill command, Linux system
keywords, 596 maintenance, 78–80, 81
properties of, 597–598 <kill-session> operations, NETCONF,
721–722
purpose of, 595–596
KM (Keying Material), 492
referencing external schemas,
602–609 Kubernetes, 378–382, 1115

Z01_Abuelenain_Index_p1121-p1196.indd 1148 27/03/21 6:37 pm


Linux 1149

L applications, communication, 24
architecture, 23–25
lab topologies archiving utilities
BGP-LS, 845–846 bzip2, 67, 69
PCEP, 867 gzip, 67–68
SR, 825 tar, 67, 70–73
lastlog command, Linux, 91 xz, 67, 69–70, 72–73
leading spaces, XML documents, 555 Bash shells, 29
leaf nodes, YANG data modeling, IOS XR programmability, 886
649–651 Open NX-OS, 886, 887–891
leaf-list nodes, YANG data modeling, BIOS, 27
651–652 blkid command, 148–149
left arrow (<) boot process, 26–28
Jinja2 operator, 1019 bzip2 archiving utility, 67, 69
Python operator, 285 cat command, 41–42, 61–62
left arrow, equal sign (<=) cat/proc/cpuinfo command, 87–88
Jinja2 operator, 1019 chmod command, 144–146
Python operator, 285 clear command, 30
left shift operator (<<), Python, 281 command shell, 28–30
less command, 43–44 comments in scripts, 207–208
lexical analyzers, Python code compiling software, 94, 96–97
execution, 263
cp command, 46–48, 49–51
libraries
daemons, 24
NAPALM libraries, 354–359
date command, 85–86
Netmiko libraries, Jinja2 templates,
depsolve, 95
364–367
/dev directory, storage, 119–120
Nornir libraries, 354–359, 371–375
contents of, 120
libsolv, 95
device file types, 120–121
link NLRI, BGP-LS, 856–857
fdisk command, 121–125
links, Linux
file system creation, 125–126
hard links, 51–55
hard disk partitions, 121–125
soft links, 55–57
mkfs command, 125–126
symlinks, 56–57
mounting file systems, 126–128
Linux, 16–17, 21, 25
unmounting file systems, 127
>> notation, 61–62
development, 22
ACL, 148–155
device drivers, 23
API, 24

Z01_Abuelenain_Index_p1121-p1196.indd 1149 27/03/21 6:37 pm


1150 Linux

device mappers, 135 double dot notation (..), Linux


dig command, 180–181 directories, 37
directories, 48–49 echo command, 208–210, 222–226
/: root directory, 36 EPEL repositories, 111–112
absolute paths, 38–39 fdisk command, 121–125
attributes, 40–41 file security management
boot directory, 36 ACL, 148–155
copying, 49–51 changing file users/groups, 146
creating, 49, 51 creating files under different
groups, 147
deleting, 50–51
default users/groups of new
dev directory, 36
files, 147
double dot notation (..), 37
logging into different groups,
etc directory, 36 147–148
home directory, 36 permissions, 143–148, 150–
media directory, 37 152
mnt directory, 37 file systems, 35–37
moving, 49, 51 creating, 125–126
navigating, 38–41 mounting, 126–128
opt directory, 37 unmounting, 127
proc directory, 37 files
relative paths, 38–39 attributes, 40–41
renaming, 50–51 creating, 46
root directory, 37 permissions, 40
run directory, 37 viewing, 41–46
srv directory, 37 findmnt command, 148–149
sys directory, 37 getfacl command, 149–155
tmp directory, 37 GNU C library (glibc), 24
usr directory, 37 GNU info files, 35
usr/bin directory, 37 grep command, regular expressions
usr/local directory, 37 (regex), 184–193
usr/sbin directory, 37 groupadd command, 141
var directory, 37 groupdel command, 141–142
distributions, 26 Guest shells, Open NX-OS, 884, 886,
887, 891–892
dmesg command, 90
gzip archiving utility, 67–68
dmidecode command, 88–89
hard links, 51–55
DNF, 95, 117
head and tail command, 45–46

Z01_Abuelenain_Index_p1121-p1196.indd 1150 27/03/21 6:37 pm


Linux 1151

help, 31–35 mv command, 47, 48, 50–51


history command, 30 networking, 158–159
history of, 21–22 adding/removing IP addresses
host files and Ansible, 993 from interfaces, 161–162
id command, 136 configuration files, 174–179
info command, 35 DNS, 179–181
inode numbers, 40 ip command, 158–167
interpreters, 28 NetworkManager, 168–174
ip command, 158–167 ping command, 164–167,
178–179, 181
jobs, 74
programmability, 960, 967–973
displaying status, 80
routing tables, 163–168
stopping, 80–81
scripting, 174–179
journald command, 93–94
sysctl command, 167–168
kernels
toggling interface state, 161
kernel space, 23–24
newgrp command, 138, 146–148
LKM, 25
package management software, 95
microkernel kernels, 25
DNF, 95, 117
monolithic kernels, 25
RPM, 95, 97–101
SCI, 24
YUM, 95, 101–117
kill command, 78–80, 81
patches, 22
lastlog command, 91
pgrep command, 78
less command, 43–44
pinfo command, 35
libsolv, 95
ping command, 164–167, 178–179,
links
181
hard links, 51–55
piping (|), 58, 65–67
soft links, 55–57
POST, 27
symlinks, 56–57
printf command, 210–213
ls command, 31–34, 39, 143–144
processes, 73–74, 80–81
lspci command, 90
ps command, 74–77
lvdisplay command, 132–133
pvdisplay command, 130–131, 133
LVM, 128–135
pwd command, 29, 138–140
man command, 34
read command, 214–217
MBR, 27
redirecting input/output, 57–59
mkdir command, 49, 51, 134–135
>> notation, 61–62
mkfs command, 125–126, 133–134
piping (|), 58, 65–67
more command, 42–43, 44
stderr, 59, 62–65

Z01_Abuelenain_Index_p1121-p1196.indd 1151 27/03/21 6:37 pm


1152 Linux

stdin, 59 conditional statements, equal


stdin, sort command, 59–61 sign (=), 229
stdout, 59, 62–65 conditional statements, if-then
constructs, 226–232
stdout, sort command, 61
Expect programming language,
tee command, 66–67
245–246
resource utilization, 83–85
functions, 240–244
rm command, 47, 48
GNU Bash Manual, 184
rmdir command, 50–51
if-then constructs, 226–232
RPM, 95, 97–101
input, 213
RSA keys, network programmability,
input, Arguments.bash script,
971–973
213–214
ryslogd command, 91–93
input, read command, 214–217
scale command, 221–222
loops, 234–235
scripting, 183
loops, for-do loops, 235–237
Arguments.bash script,
loops, until-do loops, 239–240
213–214
loops, while-do loops, 237–239
arithmetic operations, 220–222
networks, 174–179
arrays, adding/removing
elements, 224–226 output, 208
arrays, associative arrays, 222 output, echo command, 208–210
arrays, concatenating, 221–226 output, POSIX, 210
arrays, declaring, 222–224 output, printf command,
210–213
arrays, defined, 222
regular expressions (regex),
arrays, indexed arrays,
184–193
222–224
scale command, 221–222
awk programming language,
194–197 sed command, 197–205
Bash scripting, 184 shells, 183
Bash shells, 206–207, 213–214 shells, structure of, 205–208
Bash shells, Arguments.bash variables, 217–218
script, 213–214 variables, declaring, 218–219
case-in constructs, 232–234 variables, one-dimensional
comments, 207–208 variables, 218
conditional statements, 226 variables, value assignments,
218–219
conditional statements, case-in
constructs, 232–234 security, 135
conditional statements, double ACL, 148–155
equal sign (==), 229 file security management,
143–148

Z01_Abuelenain_Index_p1121-p1196.indd 1152 27/03/21 6:37 pm


Linux 1153

system security, 155–158 sysctl command, 167–168


user/group management, syslog messages, 93–94
136–142 system calls, 24
sed command, 197–205 system daemons, 24
services, 74, 81–83 system information
setfacl command, 151–155 cat/proc/cpuinfo command,
sg command, 146–147 87–88
shells, 183, 205–208 date command, 85–86
shred command, 48 dmesg command, 90
soft links, 55–57 dmidecode command, 88–89
software lspci command, 90
dependencies, 95 timedatectl command, 86
installation/maintenance, update command, 86–87
94–96 system logs, 91
software repositories, 95–96 journald command, 93–94
EPEL repositories, 111–112 lastlog command, 91
listing, 110–111 rotation, 91
LocalRepo repositories, ryslogd command, 91–93
112–117
tail command, 91
sort command, stdin, 59–61
system maintenance, 73
source code, software installation, 94
jobs, 74, 80–81
SSH, network programmability,
kill command, 78–80, 81
971–973
pgrep command, 78
stat command, 62–63
processes, 73–74, 80–81
stderr, 59, 62–65
ps command, 74–77
stdin, 59, 61
services, 74, 81–83
stdout, 59, 61, 62–65
systemctl command, 81–83
storage, 119
threads, 73
/dev directory, 119–128
system security, 155–158
LVM, 128–135
systemctl command, 81–83
physical storage, 119–128
tar archiving utility, 67, 70–73
su command, 29–30
tee command, 66–67
sudo command, 136
Terminal, 29
sudo yum remove httpd command,
109 threads, 73
sudo yum update command, 110 time stamps, 41
symlinks, 56–57 timedatectl command, 86

Z01_Abuelenain_Index_p1121-p1196.indd 1153 27/03/21 6:37 pm


1154 Linux

today, 22 list nodes, YANG data modeling,


top command, 83–85 653–654
touch command, 46, 48 list variables, Ansible, 1007
update command, 86–87 list.append() function, Python,
288–289
usage, 22
list.pop() function, Python, 288–289
user space (userland), 23–24
list.reverse() function, Python, 289
useradd command, 138–140
lists, Python, 286–287
userdel command, 141
accessing data/operations, 287–288
user/group management, 136–138
functions, 288–289
changing passwords, 141
if-else statements, 298–299
creating groups, 141
nested lists, 289–290
creating new users, 138–141
slicing, 286–287
deleting groups, 141–142
square brackets ([ ]), 286–287
deleting users, 141
value assignments, 286–288
getting user information, 136
list.sort() function, Python, 289
modifying user details, 142
LKM, Linux, 25
setting user passwords, 138–141
local Git repositories, updating,
usermod command, 142
314–315
vgdisplay command, 132, 133–134
local/remote directory operations,
volumes SFTP, 542–543
logical volumes, 132–133 LocalRepo repositories, 112–117
physical volumes, 130–131 Location Scanning API (Meraki), 923
volume groups, 132, 133–134 <lock> operations, NETCONF,
mounting, 134–135 720–721
xz archiving utility, 67, 69–70, 72–73 logical AND/OR, combining multiple
YUM, 95, 101 conditional statements, 1022–1024
commands list, 102–103 logical operators
sudo yum remove httpd Python, 284–285, 297–298
command, 109 XPath values, 577
sudo yum update command, 110 logins, SFTP, 541
yum info command, 104–105 loopback interfaces
yum install command, 106–109 CLI programmability, 962–963
yum list command, 103 NETCONF programmability, 975–978
yum repolist all command, loops
110–111 Ansible
yum search command, 103–104 conditional statements with
yum-config-manager command, loops, 1024–1027
111–112 Jinja2 templates, 1040–1043

Z01_Abuelenain_Index_p1121-p1196.indd 1154 27/03/21 6:37 pm


managing 1155

for loops, Python control flow, changing file users/groups, 146


301–302, 306 creating files under different
nested for loops, 303–304 groups, 147
range() function, 302–303 default users/groups of new
Jinja2 templates, 1040–1043 files, 147
Linux scripting, 234–235 logging into different groups,
147–148
for-do loops, 235–237
permissions, 143–148, 150–152
until-do loops, 239–240
IOS XE with Ansible
while-do loops, 237–239
clearing counters, 1060–1061
nx-os_config modules, 1090–1091
NETCONF, 1095–1096
while loops, 304–306
preparing for management,
lowercase/uppercase characters
1055–1057
(regular expressions), matching,
187–188 preparing for NETCONF
management, 1095–1096
ls command, 31–34, 39, 143–144
updating files with additional
LSP, PCEP
hosts/variables, 1057–1058
PCC, 874–876, 879–880
verifying management, 1057
PCE, 876–880
verifying operational data,
lspci command, Linux, 90 1058–1060
lvdisplay command, Linux, 132–133 IOS XR with Ansible
LVM (Logical Volume Manager), NETCONF, 1096–1098
128–135
preparing for management,
1073–1074
M preparing for NETCONF
management, 1096–1098
MAC (Message Authentication Code), verifying operational data,
493–494 1074–1078
machine learning, Python, 378–382 ITIL 4 management practices, 3–5
man command, 34 NETCONF, verifying operational
managing data, 1098–1103
CMDB, 12 networks
configuration management automation defined, 3–5
IOS XE programmability, 886 device management with
Open NX-OS programmability, NETCONF/YANG, 975–978
885 FCAPS, 3
devices, DNA Center, 934 NX-OS with Ansible
file security management, Linux collecting show output with
ACL, 148–155 nxos_command, 1086–1088

Z01_Abuelenain_Index_p1121-p1196.indd 1155 27/03/21 6:37 pm


1156 managing

configuring with nx-os_* beginnings/endings of words,


modules, 1093–1095 regular expressions (regex),
configuring with nx-os_config 188–189
modules, 1086–1088 uppercase/lowercase characters,
interactive commands, regular expressions (regex),
1088–1089 187–188
NETCONF, 1098 MBR (Master Boot Records), 27
preparing for management, media directory, Linux, 37
1084–1085 Meeting Server (Cisco), 943
preparing for NETCONF membership operators, Python,
management, 1098 285–286
verifying management, Meraki API, 922, 923
1085–1086 Captive Portal API, 923
verifying operational data, Dashboard API, 922–931
1086–1089
Location Scanning API, 923
package management software, 95
MV Sense API, 923
DNF, 95, 117
Webhook Alerts API, 922
RPM, 95, 97–101
merge keys, YAML, 624–625
YUM, 95, 101–117
messages, HTTP
state management, HTTP, 483–487
CRLF, 415, 418
user/group management, Linux,
format of, 415
136–138
headers
changing passwords, 141
client request header fields,
creating groups, 141
422–425
creating new users, 138–141
entity header fields, 416,
deleting groups, 141–142 427–430
deleting users, 141 general header fields, 416,
getting user information, 136 418–422
modifying user details, 142 overview of, 416–418
setting user passwords, request header fields, 416
138–141 response header fields, 416
manual software compilation/ server response header fields,
installation, Linux, 96–97 425–427
map() function, 1054–1055 HTTP/2, 504–505
mappings, YAML, 618–620 MAC, 493–494
matching start lines, 415
anything/everything with .* notation, whitespaces, 416
regular expressions (regex), 190

Z01_Abuelenain_Index_p1121-p1196.indd 1156 27/03/21 6:37 pm


modeling data, YANG 1157

messages layer HEAD method, 398


NETCONF, 693, 695–696 OPTIONS method, 407–408
hello messages, 696–698 POST method, 399–402
rpc messages, 698–699 Postman, 443–445
rpc-reply messages, 699–701 Python and HTTP, 465
RESTCONF, 742–743, 759 PUT method, 402–405
constructing messages, 745 TRACE method, 408
content parameter, 771 microkernel kernels, Linux, 25
DELETE method, 770–771 microservice architectures, 782
depth parameter, 771 migrations, Django, 338–339
editing data, 759–763 minus sign (-)
error reporting, 746 -= operator, Python, 284
fields parameter, 771, 773–777 assignment operator, Python, 281
filter parameter, 771 mkdir command, 49, 51, 134–135
GET method, 760–763 mkfs command, Linux, 125–126,
HEAD method, 763 133–134
HTTP headers, 745–746 mnt directory, Linux, 37
insert parameter, 771 model-based industry-standard API
OPTIONS method, 759–760 IOS XE programmability, 885
PATCH method, 767–770 IOS XR programmability, 886
point parameter, 771 Open NX-OS programmability, 884
POST method, 763–765 model-driven telemetry
PUT method, 765–767 rules of thumb, 1113–1114
query parameters, 771–777 SNMP, 1113
request messages, 743–744 syslog, 1113
response messages, 744–745 modeling data, YANG, 639–640, 642
retrieving data, 759–763 importance of, 640–642
start-time parameter, 771 modules, 642–644
stop-time parameter, 771 augmentation, 656–658
with-defaults parameter, 771 built-in data types, 647–648
methods, HTTP, 389 cloning, 665
CONNECT method, 407 derived data types, 648–649
DELETE method, 405–406 deviations, 658–662
GET method, 398 home of, 664–666
Bash shells, 447–454 IETF YANG modules, 670–671
Postman, 445–446 native (vendor-specific) mod-
ules, 666–669

Z01_Abuelenain_Index_p1121-p1196.indd 1157 27/03/21 6:37 pm


1158 modeling data, YANG

OpenConfig YANG modules, from-import statements,


671–673 334–335
structure of, 644–646 import statements, 333–334
verifying downloaded modules, YANG data modeling, 642–644
665–666 augmentation, 656–658
nodes, 649 built-in data types, 647–648
container nodes, 647–648 cloning, 665
grouping, 654–656 derived data types, 648–649
leaf nodes, 649–651 deviations, 658–662
leaf-list nodes, 651–652 home of, 664–666
list nodes, 647–648 IETF YANG modules, 670–671
pyang, 673–679, 683–687 native (vendor-specific)
pyangbind, 679–682 modules, 666–669
YANG 1.1, 662–663 OpenConfig YANG modules,
models.py files, Django, 343 671–673
modifying user details, Linux user/ structure of, 644–646
group management, 142 verifying downloaded modules,
modules 665–666
Ansible Modulo Operator (%), 274, 281
control functions, monitoring networks, streaming
1001–1002 telemetry, 1113–1114
debug modules, 999 monolithic kernels, Linux, 25
file modules, 1003 more command, 42–43, 44
ios_command module, mounting
1058–1061 file systems, 126–128
iosxr_command, parameters, volumes, LVM, 134–135
1001 moving
network modules, 1003 directories, Linux, 49, 51
return values, 1001–1002 files, Linux, 47, 48
structure of, 1000 MPLS FIB, SR, 828–830
utility modules, 1003 MPLS LSP, PCEP, 864–867
Python multi-level inheritance, OOP, 257
application development, multiple inheritance, OOP, 257
333–336
multiplexing frames, HTTP/2, 505–506
classes, 335–336
mv command, 47, 48, 50–51
constructors, 335–336
MV Sense API (Meraki), 923

Z01_Abuelenain_Index_p1121-p1196.indd 1158 27/03/21 6:37 pm


NETCONF 1159

N distinct startup capability, 733


rollback-on-error capability,
NaC (Network as Code), 12 732–733
namespaces, XML, 559–561 URL capability, 733–734
NAPALM libraries, network validate capability, 733
automation, 354–359, 371–375 writable-running capability, 732
native (vendor-specific) YANG XPath capability, 735
modules, 666–669 <close-session> operations, 721–722
native application hosting, 1115–1116 <commit> operations, 722–724
ncclient, NETCONF, 735–739 configuration validation, 724–725
negative/positive values, arithmetic connections, 694
operators, Python, 282 content layer, 693, 725–730
nested code blocks with conditional YANG, 725–729
statements, Python control flow,
295–296 <copy-config> operations, 719
nested for loops, 303–304 data delivery, 694
nested lists, Python, 289–290 data integrity/confidentiality, 694
nesting format, XML, 561–562 datastores
nesting relationships, XML, 555–556 configuring, 712–720
NETCONF, 689 operations, 720–721
Ansible and <delete-config> operations, 719–720
configuring, 1103–1107 <discard-changes> operations,
722–724
IOS XE management, 1095–1096
<edit-config> operations, 712–719
IOS XR management,
1096–1098 <get> operations, 702–703
NX-OS management, 1098 <get-config> operations, 702–703
verifying operational data, hello messages, 696–698, 973–974
1098–1103 high-level operations, 691–692
architecture, 692–693 IOS XE, 918–922
authentication, 694 IOS XR, 916–918
<cancel-commit> operations, <kill-session> operations, 721–722
722–724 <lock> operations, 720–721
candidate configuration operations, messages layer, 693, 695–696
722–724 hello messages, 696–698
capabilities, 731 rpc messages, 698–699
candidate configuration rpc-reply messages, 699–701
capability, 732
ncclient, 735–739
confirmed commit capability,
732 netconf_get module

Z01_Abuelenain_Index_p1121-p1196.indd 1159 27/03/21 6:37 pm


1160 NETCONF

configuring, 1103–1107 over SSH, 694–695


verifying operational data, overview, 689–692
1098–1103 Python, ncclient, 735–739
NETCONF/YANG, network reliability, 694
programmability, 973–978
RESTCONF and, 740–742
network programmability, 960,
rpc messages, 691, 698–699
973–978
rpc-reply messages, 691, 699–701
NX-OS, 905–916
session operations, 721–722
operations layer, 693, 701–702
transport layer, 692–693
<cancel-commit> operations,
722–724 NETCONF over SSH,
694–695
candidate configuration
operations, 722–724 transport protocol requirements,
693–694
<close-session> operations,
721–722 <unlock> operations, 720–721
<commit> operations, 722–724 <validate> operations, 724–725
configuration validation, Working Group, 689–690
724–725 XML attributes, 558
<copy-config> operations, 719 YANG, 725–729
datastore configurations, NETCONF/YANG
712–720 configuring, 1103–1107
datastore operations, 720–721 netconf_get module, 1103–1107
<delete-config> operations, verifying operational data,
719–720 1098–1103
<discard-changes> operations, Netmiko libraries, Jinja2 templates,
722–724 364–367
<edit-config> operations, network modules, Ansible, 1003
712–719
NetworkManager, 168–169
<get> operations, 702–703
connections
<get-config> operations,
attributes, 169–170
702–703
creating, 171–174
<kill-session> operations,
721–722 deleting, 171–174
<lock> operations, 720–721 listing, 169
session operations, 721–722 interfaces, listing, 171
subtree filters, 703–710 networks
<unlock> operations, 720–721 abstraction, defined, 9–13
<validate> operations, 724–725 Ansible. See also seperate entry,
15–16
XPath filters, 710–712

Z01_Abuelenain_Index_p1121-p1196.indd 1160 27/03/21 6:37 pm


networks 1161

automation Network Programmability and


architectures, 353–354 Automation toolbox, 14–15
Jinja2 templates, 363–375 Ansible. See also seperate
entry, 15–16
NAPALM libraries, 354–359,
371–375 Linux, 16–17
Nornir libraries, 359–363, protocols, 18–19
367–369, 371–375 Python, 15
CAPEX, 2 virtualization, 17
cleaning up, 1110 YANG, 17
engineers OPEX, 2
automation, 19–20 overlay networks, 9, 821
career paths, questions, programmability, 253–254
1118–1119 CLI, 958–959, 962–967
FCAPS, 3 gNMI, 961–962
IBN, 13–14 gRPC, 961–962
IP VPN, JSON schemas, 597–598, Linux shells, 960, 967–973
601–602, 607–609
NETCONF/YANG, 973–978
Linux, 16–17, 158–159
network programmability, 960
adding/removing IP addresses
RESTCONF, 961
from interfaces, 161–162
RESTCONF/YANG, 978–987
configuration files, 174–179
SNMP, 959–960
DNS, 179–181
vendor/API matrix, 957–958
ip command, 158–167
protocols, 18
NetworkManager, 168–171
encoding, 18
ping command, 164–167,
178–179, 181 transport protocols, 18–19
routing tables, 163–168 Python, 15
scripting, 174–179 SDN, 13, 819
sysctl command, 167–168 BGP-LS, 843
toggling interface state, 161 BGP-LS, lab topologies,
845–846
managing
BGP-LS, link NLRI, 856–857
defined, 3–5
BGP-LS, node NLRI, 854–855
devices with NETCONF/
YANG, 973–978 BGP-LS, NPF-XR, 845, 849,
851–854
devices with RESTCONF/
YANG, 978–987 BGP-LS, peering, 843–844,
847–849
FCAPS, 3
BGP-LS, prefix NLRI, 858–859
monitoring, streaming telemetry,
1113–1114 BGP-LS, routing, 846–847

Z01_Abuelenain_Index_p1121-p1196.indd 1161 27/03/21 6:37 pm


1162 networks

BGP-LS, routing types VPN, IP VPN, 597–598, 601–602,


(overview), 850–854 607–609
controllers, 821–823 YANG, 17
network requirements, Neutron ML2 (OpenStack), Open
819–821 NX-OS programmability, 885
overlay networks, 821 newgrp command, Linux, 138,
PCEP, call flows, 861–864 146–148
PCEP, IOS XR configurations, Nexus switches
867–880 authentication, 401–402, 463
PCEP, LSP delegation, 864–867 static routing
PCEP, PCC, 860–861, 867–870, DELETE method, 405–406
874–880 POST method, 399–401
PCEP, PCE, 860–861, 869–874, PUT method, 402–405
876–880
NLRI, BGP-LS
PCEP, RFC, 860–861
link NLRI, 856–857
PCEP, state synchronization, 863
node NLRI, 854–855
SR, Adj-SID, 824, 827, 839–842
prefix NLRI, 858–859
SR, data plane verification,
nodes
830–831
XPath, 574
SR, forwarding, 832
YAML, 617
SR, IETF drafts, 823
YANG data modeling, 649
SR, lan topologies, 825
container nodes, 647–648
SR, MPLS FIB for NPF-XR,
828–830 grouping, 654–656
SR, Node-SID, 824 leaf nodes, 649–651
SR, NPF-XR, 835 leaf-list nodes, 651–652
SR, Prefix-SID, 824, 827, list nodes, 647–648
834–836 Node-SID, 824
SR, segments, 824, 825–827 Nornir libraries, network automation,
SR, SR algorithm, 827 359–363, 367–369, 371–375
SR, SRGB, 824, 827, 831 northbound API, 883, 933
SR, SRLB, 824 not in operator, Python, 286
SR, SR-MPLS, 824 NOT operator (~), Python, 281, 285
SR, SR-TE, 832–843 notifications, DNA Center, 935
underlay networks, 821–822 NPF-XR
underlay networks, 9, 821–822 BGP-LS, 845, 849, 851–854
virtualization, 17 SR, 835
VLAN, awareness, 8–9 SR-TE, 836–843

Z01_Abuelenain_Index_p1121-p1196.indd 1162 27/03/21 6:37 pm


objects 1163

NSX, 13 configuring with nx-os_config


null values, JSON, 593 modules, 1086–1088
number data types, Python, 273–276 interactive commands,
1088–1089
numbers, JSON, 593
nx-os_config modules
NX-API CLI
configuring NX-OS,
Open NX-OS programmability, 884
1086–1088
use cases, 893–898
Jinja2 templates, 1091–1093
NX-API REST
loops, 1090–1091
Open NX-OS programmability, 884
variables, 1090–1091
use cases, 898–905
programmability, 884–885
NX-OS
SSH setup, 537–540, 547–548
Ansible
use cases, 887–892
collecting show output with
nxos_command, 1086–1088
configuring with nx-os_* O
modules, 1093–1095
OAuth protocol, HTTP/1.1
configuring with nx-os_config
authentication, 474–475
modules, 1090–1093
access tokens, 481–483
interactive commands,
1088–1089 API resource server calls, 483
preparing for management, authorization grants, 477–481
1084–1085 Bearer Tokens, 475–476
preparing NX-OS for client registration, 476–477
NETCONF management, workflows, 476
1098
objects
verifying management,
JSON objects
1085–1086
defined, 593
verifying operational data,
1086–1089 key/pair values, 592
Bash shells, 887–891 out of range objects and data
validation, 613–614
Guest shells, 887, 891–892
referencing external JSON
Jinja2 templates, 367–371
schemas, 606–607
NETCONF, 905–916
repetitive objects, 598–602
nxos_command
simple JSON object example,
collecting show output, 592
1086–1088
typos and data validation,
configuring with nx-os_* 611–612
modules, 1093–1095
unexpected keys and data
validation, 612–613

Z01_Abuelenain_Index_p1121-p1196.indd 1163 27/03/21 6:37 pm


1164 objects

Python objects, serializing with <discard-changes> operations,


YAML, 628–629 722–724
octal notation, file permissions, <edit-config> operations,
145–146 712–719
one-dimensional variables, 218 <get> operations, 702–703
one-time automations, 1111 <get-config> operations,
OOP (Object-Oriented Programming), 702–703
256 <kill-session> operations,
abstraction, 257 721–722
encapsulation, 257 <lock> operations, 720–721
inheritance, 256–257 session operations, 721–722
polymorphism, 257 subtree filters, 703–710
OpenConfig YANG modules, <unlock> operations, 720–721
671–673 <validate> operations, 724–725
OpenFlow, IOS XE programmability, XPath filters, 710–712
886 RESTCONF, 743
Open NX-OS operations resource, RESTCONF,
Bash shells, 887–891 756–758
NETCONF, 905–916 OR operator (|)
programmability, 884–885 Python, 281, 285
use cases, 887–892 regular expressions (regex), 186
OpenSSH, 510, 522 operators
OpenStack Neutron ML2, Open Python, 281
NX-OS programmability, 885 arithmetic operators, 281–283
operations layer, assignment operators, 284
NETCONF, 693, 701–702 bitwise operators, 281–283
<cancel-commit> operations, comparison operators,
722–724 284–285
candidate configuration identity operators, 284–285
operations, 722–724
logical operators, 284–285,
<close-session> operations, 297–298
721–722
membership operators,
<commit> operations, 722–724 285–286
configuration validation, XPath operator values, 577
724–725
OPEX (Operating Expenses), 2
<copy-config> operations, 719
opt directory, Linux, 37
datastores, 712–721
OPTIONS method, 407–408,
<delete-config> operations, 759–760
719–720

Z01_Abuelenain_Index_p1121-p1196.indd 1164 27/03/21 6:37 pm


PCEP (Path Computation Element Protocol) 1165

orchestration, 375–376 yum search command, 103–104


automation versus, 6–7 yum-config-manager command,
defined, 6–7 111–112
Docker, 376–378 pair/key values, JSON objects, 592
Kubernetes, 378–382 parent/child relationships, XML,
555–556
tools (overview), 7
parentheses ( ( ) ), regular expressions
output/input redirection, Linux,
(regex), 185
57–59
partitions, /dev directory, 121–125
>> notation, 61–62
passwords
piping (|), 58, 65–67
authentication, 517, 522–523,
stderr, 59, 62–65
525–526
stdin, 59, 61
user/group management, Linux
stdout, 59, 61, 62–65
changing passwords, 141
tee command, 66–67
setting user passwords,
output, Linux scripting, 208 138–141
echo command, 208–210 PATCH method, RESTCONF,
printf command, 210–213 767–770
overlay networks, 9, 821 patches, 22
pattern validation, XML, 569–570
P PAWS API, 944
PCC (Path Computation Clients),
package management software 860–861
DNF, 95, 117 LSP configuration, 874–880
RPM, 95, 97–101 SR-TE configuration, 867–870
YUM, 95, 101 PCE (Path Computation Elements)
commands list, 102–103 LSP configuration, 876–880
sudo yum remove httpd PCEP, 860–861
command, 109 SR-PCE, 874
sudo yum update command, SR-TE configuration, 869–874
110
PCEP (Path Computation Element
yum info command, 104–105 Protocol)
yum install command, call flows, 861–864
106–109
IOS XR configurations, 867–880
yum list command, 103
lab topologies, 867
yum repolist all command,
LSP delegation, 864–867
110–111

Z01_Abuelenain_Index_p1121-p1196.indd 1165 27/03/21 6:37 pm


1166 PCEP (Path Computation Element Protocol)

PCC, 860–861 ping command, Linux, 164–167,


LSP configuration, 874–880 178–179, 181
SR-TE configuration, 867–870 pipes (|), 58, 65–67, 281
PCE, 860–861 | (OR operator)
LSP configuration, 876–880 Python, 281, 285
SR-PCE, 874 regular expressions (regex),
186
SR-TE configuration, 869–874
|= operator, Python, 284
peering, 867
pipelining, HTTP/1.1, 396
RFC, 860–861
platforms, API, 882
state synchronization, 863
playbooks, Ansible, 990, 997–1000
peer authentication, 496–497
conditional statements with loops
peering
and variables, 1032–1033
BGP-LS, 843–844, 847–849
Jinja2 templates, 1040–1043
PCEP, 867
variables, defining, 1005–1006
percentage symbols (%)
+ (plus signs)
%= operator, Python, 284
+ assignment operator, Python, 281
Modulo Operator, 274, 281
+= operator, Python, 284
performance, Git, 312
regular expressions (regex), 186, 189,
periods (.), 190, 192
.* notation, regular expressions point parameter, RESTCONF, 771
(regex), 190
polymorphism, OOP, 257
.. notation, Linux directories, 37
positive/negative values, arithmetic
regular expressions (regex), 185, 189 operators, Python, 282
permissions POSIX (Portable Operating System
file permissions, changing with SFTP, Interface), Linux scripting, 210
544–545 POST (Power-On Self-Tests), 27
file security management, Linux, POST method
143–144, 150–152
Flask, 350–352
octal notation, 145–146
HTTP client requests, 399–402
symbolic notation, 144–145
Postman, 443–445
persistent connections, HTTP/1.1,
Python and HTTP, 465
395–396
RESTCONF, 763–765
person_in_list() function, Python,
307–308 Postman, 436–437
PFS (Perfect Forward Secrecy), 490 HTTP
pgrep command, Linux system GET request messages, 447–454
maintenance, 78 POST method, 443–445
pinfo command, 35 installing, 438

Z01_Abuelenain_Index_p1121-p1196.indd 1166 27/03/21 6:37 pm


programmable interfaces 1167

interface, 438–441 NX-API REST, use cases,


usage, 441–446 898–905
web/API development, 345 Open NX-OS, Bash shells,
887–891
pound signs, #! (hashbangs), 205–208
Open NX-OS, Guest shells, 887,
predefined entries, XML, 557
891–892
predicates, XML expressions, 577
Open NX-OS, NETCONF,
prefix NLRI, BGP-LS, 858–859 905–916
prefixes, XML namespaces, 560–561 Open NX-OS, programmabil-
Prefix-SID, 824, 827, 834–836 ity, 884–885
print_persons() function, Python, Open NX-OS, use cases,
307–309 887–892
printf command, Linux, 210–213 platforms, 882
proc directory, Linux, 37 RESTful API, 883
processes, Linux, 73–74, 80–81 RPC-based API, 883
product environments, replicating, southbound API, 883
312 webhooks, 882
programmable interfaces, 881–882 westbound API, 883
API collaboration platforms, 942
classifications, 882–883 Cisco collaboration portfolio,
eastbound API, 883 942–944
endpoints, 882 collaboration API, 944–954
IOS XE, gNMI insecure mode, DNA Center, 931–933
815 device management, 934
IOS XE, NETCONF, 918–922 Eastbound API, 933
IOS XE, programmability, event notifications, 935
885–886
Integration API, 935–936
IOS XR, NETCONF, 916–918
Intent API, 934, 936–941
IOS XR, programmability,
Northbound API, 933
886–887
Southbound API, 933
NETCONF on IOS XE,
918–922 webhooks, 935
NETCONF on IOS XR, Westbound API, 933
916–918 Meraki API, 922, 923
NETCONF on NX-OS, Captive Portal API, 923
905–916 Dashboard API, 922–931
northbound API, 883 Location Scanning API, 923
NX-API CLI, use cases, MV Sense API, 923
893–898
Webhook Alerts API, 922

Z01_Abuelenain_Index_p1121-p1196.indd 1167 27/03/21 6:37 pm


1168 programming

programming bytecode interpreters, 264


API, 7–8 code execution, 263–269
algorithms, 258–259 code testing/verification, 269
computer science concepts, 255 compiling code, 265–266
defined, 7–8, 249–250 complex numbers, 276
IOS XE, 885–886 data structures, 286–295
IOS XR, 886–887 data types, 270
Network Programmability and data types, numbers, 273–276
Automation toolbox, 14–15 data types, strings, 276–280
Ansible. See also seperate dictionaries, 290–292
entry, 15–16
executable Python files, 265
Linux, 16–17
float() function, 275
protocols, 18–19
floating point data, 275
Python, 15
format() function, 280
virtualization, 17
fundamentals, 260
YANG, 17
installing, 260–263
networks, 253–254
int() function, 275
CLI, 958–959, 962–967
integer operations, 275
gNMI, 961–962
lexical analyzers, 263
gRPC, 961–962
lists, 286–290
Linux shells, 960, 967–973
Modulo Operator (%), 274
NETCONF/YANG, 973–978
numeric data, 269
network programmability, 960
operators, 281–286
RESTCONF, 961
sets, 294–295
RESTCONF/YANG, 978–987
simple Python program, 264
SNMP, 959–960
slicing string indexes, 278–279
vendor/API matrix, 957–958
square brackets ([ ]), 278
OOP, 256
str.lower() function, 279–280
abstraction, 257
str.replace() function, 279–280
encapsulation, 257
str.strip() function, 279–280
inheritance, 256–257
str.upper() function, 279–280
polymorphism, 257
sum() function, 249–250
Open NX-OS, 884–885
tokenizers, 263
pseudocode, 251–253
tuples, 292–293
Python
variables, 270–273
bytecode, 265–267
scripting languages vs scripting,
bytecode generators, 264 250–253

Z01_Abuelenain_Index_p1121-p1196.indd 1168 27/03/21 6:37 pm


protocols 1169

service providers, SDN, 819 SR, Node-SID, 824


BGP-LS, 843 SR, NPF-XR, 835
BGP-LS, lab topologies, SR, Prefix-SID, 824, 827,
845–846 834–836
BGP-LS, link NLRI, 856–857 SR, segments, 824, 825–827
BGP-LS, node NLRI, 854–855 SR, SR algorithm, 827
BGP-LS, NPF-XR, 845, 849, SR, SRGB, 824, 827, 831
851–854 SR, SRLB, 824
BGP-LS, peering, 843–844, SR, SR-MPLS, 824
847–849
SR, SR-TE, 832–843
BGP-LS, prefix NLRI, 858–859
underlay networks, 821–822
BGP-LS, routing, 846–847
web application development,
BGP-LS, routing types 250–251
(overview), 850–854
Protobuf, gRPC, 786–790
controllers, 821–823
example of, 788–789
network requirements,
in Python, 790–798
819–821
protocols, 18
overlay networks, 821
encoding, 18
PCEP, call flows, 861–864
gRPC
PCEP, IOS XR configurations,
867–880 gNMI, 798–799
PCEP, lab topologies, 867 gNMI, anatomy of, 799–801
PCEP, LSP delegation, 864–867 gNMI, Capabilities RPC,
810–811
PCEP, PCC, 860–861, 867–870,
874–880 gNMI, Get RPC, 801–807
PCEP, PCE, 860–861, 869–874, gNMI, insecure mode in IOS
876–880 XE, 815
PCEP, peering, 867 gNMI, managing network
elements, 814–818
PCEP, RFC, 860–861
gNMI, Python metaclasses,
PCEP, state synchronization,
815–816
863
gNMI, Python sample Get
SR, Adj-SID, 824, 827, 839–842
script, 816–818
SR, data plane verification,
gNMI, Set RPC, 807–810
830–831
gNMI, Subscribe RPC,
SR, forwarding, 832
811–814
SR, IETF drafts, 823
history of, 782–784
SR, lan topologies, 825
managing network elements,
SR, MPLS FIB for NPF-XR, 814–818
828–830

Z01_Abuelenain_Index_p1121-p1196.indd 1169 27/03/21 6:37 pm


1170 protocols

principles of, 782–784 push phase, Git workflows, 317


Protobuf, example of, 788–789 PUT method, 402–405, 765–767
Protobuf, Python, 790–798 pvdisplay command, Linux, 130–131,
server sample, 794–797 133
as a transport, 784–786 pwd command, 29, 138–140
Protobuf, gRPC, 786–790 pyang, YANG data modeling,
673–679, 683–687
example of, 788–789
pyangbind, YANG data modeling,
Python, 790–798
679–682
Python installations, 790–791
Python, 15
SCP
Ansible, 991–992
CentOS, 549–550
code execution, 263–269
SFTP comparisons, 550
bytecode, 265–267
SFTP, 540–541
bytecode generators, 264
fetching/uploading files, 543
bytecode interpreters, 264
help, 541–542
code testing/verification, 269
local/remote directory
compiling code, 265–266
operations, 542–543
executable Python files, 265
logins, 541
lexical analyzers, 263
SCP comparisons, 550
numeric data, 269
SSH Authentication Protocol,
514–516 simple Python program, 264
host-based authentication, tokenizers, 263
517–518 code testing/verification, 269
password authentication, 517 comparison operators, 284–285
public key authentication, compiling code, 265–266
516–517 complex numbers, 276
SSH Connection Protocol, 518–521 control flow
SSH-TRANS, 513–514 elif statements, 297–298
transport protocols, 18–19, 781–782 if-else statements, 296–300
ps command, Linux system for loops, 301–304, 306
maintenance, 74–77
nested code blocks with
pseudocode, 251–253 conditional statements,
PSK (Pre-Shared Keys), 489 295–296
public keys while loops, 304–306
authentication, 516–517 data structures, 286
copying onto servers, 524–525 dictionaries, 290–292
pull phase, Git workflows, 317 lists, 286–290

Z01_Abuelenain_Index_p1121-p1196.indd 1170 27/03/21 6:37 pm


Python 1171

sets, 294–295 map() function, 1054–1055


tuples, 292–293 person_in_list() function,
data types, 270 307–308
numbers, 273–276 print_persons() function,
307–309
strings, 276–280
range() function, 302–303
dictionaries, 290–291, 583–585
representations, 307
deleting, 292
set.add() function, 294
functions, 292
set.difference() function, 294–295
if-else statements, 299–300
set.pop() function, 294
dict.items() function, 292
set.remove() function, 294
dict.keys() function, 292, 307–308
set.union() function, 294–295
dict.values() function, 292
set.update() function, 294
DRY principle, 311, 336
split() function, 1051–1054
exit() function, 272
str.lower() function, 279–280
float() function, 275
str.replace() function, 279–280
floating point data, 275
str.reverse() function, Python,
format() function, 280
292–293
funcname() function, 307
str.strip() function, 279–280
functions, 306–307
str.upper() function, 279–280,
calling in code blocks, 307–309 292–293
defining in code blocks, sum() function, 249–250
307–309
validate_person() function,
dict.items() function, 292 307–308, 309
dict.keys() function, 292, fundamentals, 260
307–308
gNMI
dict.values() function, 292
metaclasses, 815–816
exit() function, 272
sample Get script, 816–818
float() function, 275
gRPC and Protobuf, 790–798
format() function, 280
HTTP
funcname() function, 307
requests packages, 464–467
input() function, 298
socket modules, 455–457
int() function, 275, 1049–1055
TCP over Python, 455–457
join() function, 1050–1051
urllib packages, 458–463
list.append() function, 288–289
installing, 260–263
list.pop() function, 288–289
JSON schemas, data validation,
list.reverse() function, 289 609–610
list.sort() function, 289 machine learning, 382–384

Z01_Abuelenain_Index_p1121-p1196.indd 1171 27/03/21 6:37 pm


1172 Python

modules | operator, 281, 285


application development, |= operator, 284
333–336 += operator, 284
classes, 335–336 > operator, 285
constructors, 335–336 >= operator, 285
from-import statements, >> (signed right shift) operator,
334–335 281
import statements, 333–334 >>= operator, 284
NETCONF, ncclient, 735–739 [ ], square brackets, 278
network automation [=] operator, 284
architectures, 353–354, ~ operator, 281, 285
371–375
and operator, 281, 285
Jinja2 templates, 363–375
arithmetic operators, 281–283
NAPALM libraries, 354–359,
assignment operators, 284
371–375
bitwise operators, 281–283
Nornir libraries, 359–363,
367–369, 371–375 identity operators, 284–285
network device management in operator, 286
NETCONF/YANG, 976–978 integer operations, 275
RESTCONF/YANG, 984–987 is not operator, 285
objects, serializing with YAML, is operator, 285
628–629 logical operators, 284–285
operators, 281 logical operators, if-else
& operator, 281 statements, 297–298
&= operator, 284 membership operators, 285–286
**= operator, 284 not in operator, 286
*= operator, 284 NOT operator, 281, 285
^ operator, 281 OR operator, 281, 285
^= operator, 284 orchestration, 375–376
= operator, 284 Docker, 376–378
== operator, 285 Kubernetes, 378–382
!= operator, 285 protoc installations, 790–791
/= operator, 284 PyYAML, 626–628
< operator, 285 requests packages, 464–467
<= operator, 285 RESTCONF, 777–779
<< operator,281 sets, 294–295
-= operator, Python, 284 slicing, lists, 286–287
% operator, 274, 281 slicing string indexes, 278–279

Z01_Abuelenain_Index_p1121-p1196.indd 1172 27/03/21 6:37 pm


regular expressions (regex) 1173

socket modules, 455–457


tuples
Q
deleting, 293 query parameters, RESTCONF,
functions, 292–293 771–777
joining, 293 question mark (?), regular expressions
urllib packages, 458–463 (regex), 186, 189, 191–192
variables, 270–271
deleting, 272–273 R
dynamic data type allocation,
271–272 range() function, Python, 302–303
scope, 272 read command, Linux, 214–217
web/API development record protocol, TLS 1.3, 499, 503
Django, 337–345 Red Hat, Linux distributions, 26
Flask, 345–352 redirecting input/output, Linux,
57–59
XML files, processing, 580
| (piping), 58, 65–67
dictionaries, 583–585
>> notation, 61–62
element mergers, 585–587
stderr, 59, 62–65
element name/attribute
extraction, 581–582 stdin, 59, 61
properties/methods, 580–581 stdout, 59, 61, 62–65
rerunning processing for tee command, 66–67
updated documents, 587–588 regexp, XML content validation, 569
script creation, 580–581 regular expressions (regex)
value extraction, 582–583 * metacharacter, 185, 189–190
YAML \ metacharacter, 186
loading multiple documents, \< metacharacter, 185, 188–189
632–633 \> metacharacter, 185, 188–189
PyYAML, 626–628 ^ metacharacter, 185, 187
saving data streams to files, 629 { }, 185
serializing Python objects, {N, M} metacharacter, 186, 189–192
628–629
{N} metacharacter, 186, 189–192
sorting data streams, 630–631
$ metacharacter, 185, 187
yaml.dump() method, 628–631
. metacharacter, 185, 189
yaml.load() method, 631–632
.* notation, 190
yaml.load_all() method, 632–633
( ) (capture groups), 186
yaml.scan() method, 633–635
( ) (parentheses), 185
PyYAML, 626–628
| OR operator, 186

Z01_Abuelenain_Index_p1121-p1196.indd 1173 27/03/21 6:37 pm


1174 regular expressions (regex)

+ metacharacter, 186, 189, 190, 192 setting up, 315–316


? metacharacter, 186, 189, 191–192 updating local repositories,
[ ] (square brackets), 185 314–315
[first_literal - last_literal] software, 95–96
metacharacter, 185 EPEL repositories, 111–112
[literals] metacharacter, 185 listing, 110–111
grep command, 184–193 LocalRepo repositories,
matching uppercase/lowercase 112–117
characters, 187–188 request header fields, HTTP, 416
printing lines without patterns, request messages, RESTCONF, 740,
192–193 743–744
repetition metacharacters, 185–186, request targets, CONNECT method
190–191 (HTTP), 407
testing, 186 request packages, Python and HTTP,
relative paths, Linux directories, 38–39 464–467
remote subnets, Linux routing tables, resources
166–167 Linux resource utilization, 83–85
remote/local directory operations, RESTCONF, 746–747
SFTP, 542–543 API resource, 747–749
removing Linux data resource, 753–758
directories, 50–51 datastore resource, 749–750
files, 47, 48 schema resource, 750–753
routing table entries, 168 YANG library version resource,
renaming Linux 758
directories, 50–51 response header fields, HTTP, 416
files, 47, 48 response messages, RESTCONF, 740,
repetition metacharacters, regular 744–745
expressions (regex), 185–186, REST framework, 392–394
190–191 REST API, 322, 392–393, 945–946,
repetitive objects, JSON schemas, 948–954
598–602 RESTCONF, 739
replicating product environments, 312 architecture, 742–743
repositories content layer, 743
Docker, 318 editing data, 763–771
Git, 312–313 error reporting, 746
cloning, 316–317 HTTP, 740
fetching remote repository headers, 745–746
updates, 314–315
response messages, 740

Z01_Abuelenain_Index_p1121-p1196.indd 1174 27/03/21 6:37 pm


right arrows (>) 1175

messages layer, 742–743, 759 schema resource, 750–753


constructing messages, 745 YANG library version resource,
content parameter, 771 758
with-defaults parameter, 771 response messages, 744–745
DELETE method, 770–771 RESTCONF/YANG, network
programmability, 978–987
depth parameter, 771
retrieving data, 759–763
editing data, 763–771
transport layer, 742, 743
error reporting, 746
RESTful API, 883
fields parameter, 771, 773–777
resuming stopped processes, 80–81
filter parameter, 771
reusing
GET method, 760–763
automations, 1111
HEAD method, 763
code, application development, 312
HTTP headers, 745–746
RFC 2616, HTTP headers, 416
insert parameter, 771
RFC 3986, HTTP, 393–394
OPTIONS method, 759–760
RFC 6265, HTTP state management,
PATCH method, 767–770
484
point parameter, 771
RFC 6749, HTTP, OAuth protocol,
POST method, 763–765 475–476
PUT method, 765–767 RFC 6750, HTTP, OAuth protocol
query parameters, 771–777 with Bearer Tokens, 475–476
request messages, 743–744 RFC 7230, HTTP headers, 416–417
response messages, 744–745 RFC 7231, HTTP/1.1 server status
retrieving data, 759–763 codes, 409–410
start-time parameter, 771 RFC 7457, TLS, 488
stop-time parameter, 771 RFC 7540, HTTP, 388
NETCONF and, 740–742 RFC 8446, TLS, 487
network programmability, 961, RFC, PCEP, 860–861
978–987 right arrows (>)
operations layer, 743 > Jinja2 operator, 1019
overview, 739–742 > Python operator, 285
Python, 777–779 >= (right arrow, equal sign)
request messages, 740, 743–744 assignment operator, Jinja2, 1019
resources, 746–747 assignment operator, Python,
API resource, 747–749 285
data resource, 753–758 >> signed right shift operator,
Python, 281
datastore resource, 749–750
>>= operator, Python, 284

Z01_Abuelenain_Index_p1121-p1196.indd 1175 27/03/21 6:37 pm


1176 rm command

rm command, 47, 48 gNMI, Python sample Get


rmdir command, 50–51 script, 816–818
rollback-on-error capability, gNMI, Set RPC, 807–810
NETCONF, 732–733 gNMI, Subscribe RPC, 811–814
root directory (/:), Linux, 36–37 history of, 782–784
rotating Linux system logs, 91 managing network elements,
routing (static) 814–818
200 OK responses principles of, 782–784
DELETE method, 405–406 Protobuf, example of, 788–789
POST method, 394–401 Protobuf, Python, 790–798
PUT method, 403–404 server sample, 794–797
Nexus switches as a transport, 784–786
DELETE method, 405–406 server-streaming RPC, 785
POST method, 399–401 Set RPC, gNMI, 807–810
PUT method, 403–404 Subscribe RPC, gNMI, 811–814
routing tables, Linux, 163–166 unary RPC, 785
forwarding interfaces, 167 RPC-based API, 883
remote subnets, 166–167 rpc messages, 691, 698–699
removing entries, 168 rpc-reply messages, 691, 699–701
viewing, 163 RPM (RPM Package Manager), 95,
97–101
RPC (Remote Procedure Calls)
RSA keys
bidirectional RPC, 785
generating/verifying, SSH NX-OS
Capabilities RPC, gNMI, 810–811
setups, 538–539
client-streaming RPC, 785
Linux network programmability,
Get RPC, gNMI, 801–807 971–973
gRPC rules of thumb
gNMI, 798–799 API, 1118
gNMI, anatomy of, 799–801 application hosting, 1115–1116
gNMI, Capabilities RPC, automation, 1109–1110
810–811
complexity, 1111–1112
gNMI, Get RPC, 801–807
cost/benefit analysis, 1112
gNMI, insecure mode in IOS
reusing automations, 1111
XE, 815
cleaning up networks, 1110
gNMI, managing network
elements, 814–818 containers, 1114–1115
gNMI, Python metaclasses, databases, 1117
815–816 documentation, 1111

Z01_Abuelenain_Index_p1121-p1196.indd 1176 27/03/21 6:37 pm


scripting, Linux 1177

model-driven telemetry, 1113–1114 arrays


search engines, 1117 adding/removing elements,
software development methodologies, 224–226
1116–1117 associative arrays, 222
run directory, Linux, 37 concatenating, 221–226
ryslogd command, Linux, 91–93 declaring, 222–224
defined, 222
S indexed arrays, 222–224
awk programming language,
saving YAML data streams, 629 194–197
scalars, YAML, 620–621 Bash scripting, 184
scale command, Linux, 221–222 Bash shells, 206–207, 213–214
schema resource, RESTCONF, case-in constructs, 232–234
750–753 comments, 207–208
schemas, JSON, 595 conditional statements, 226
annotation, 596 == (double equal sign), 229
basic schema without content, = (equal sign), 229
596–597
case-in constructs, 232–234
data validation, 609–614
if-then constructs, 226–232
definitions in, 598–601
Expect programming language,
external schemas, referencing, 245–246
602–609
functions, 240–244
IP VPN, 597–598, 601–602,
GNU Bash Manual, 184
607–609
if-then constructs, 226–232
keywords, 596
input, 213
properties of, 597–598
Arguments.bash script,
purpose of, 595–596
213–214
repetitive objects, 598–602
read command, 214–217
structure of, 595–598
loops, 234–235
validation keywords, 596–597
for-do loops, 235–237
SCI, Linux kernels, 24
until-do loops, 239–240
scope, Python variables, 272
while-do loops, 237–239
SCP (Secure Copy Protocol)
networks, 174–179
CentOS, 549–550
output, 208
SFTP comparisons, 550
echo command, 208–210
scripting, Linux, 183
printf command, 210–213
Arguments.bash script, 213–214
POSIX, 210
arithmetic operations, 220–222

Z01_Abuelenain_Index_p1121-p1196.indd 1177 27/03/21 6:37 pm


1178 scripting, Linux

prigramming languages vs scripting, variables, 217–218


250–253 declaring, 218–219
regular expressions (regex), 184–193 one-dimensional variables, 218
* metacharacter, 185, 189–190 value assignments, 218–219
\ metacharacter, 186 web application development,
\< metacharacter, 185, 188–189 250–251
\> metacharacter, 185, 188–189 SDLC (Software Development Life
^ metacharacter, 185, 187 Cycle), 1116
{ }, 185 SDN (Software-Defined Networking),
13, 819
{N, M} metacharacter, 186,
189–192 BGP-LS, 843
{N} metacharacter, 186, lab topologies, 845–846
189–192 link NLRI, 856–857
$ metacharacter, 185, 187 node NLRI, 854–855
. metacharacter, 185, 189 NPF-XR, 845, 849, 851–854
.* notation, 190 peering, 843–844, 847–849
( ) (capture groups), 186 prefix NLRI, 858–859
( ) (parentheses), 185 routing, 846–847
| OR operator, 186 routing types (overview),
+ metacharacter, 186, 189, 190, 850–854
192 controllers, 821–823
? metacharacter, 186, 189, network requirements, 819–821
191–192 overlay networks, 821
[ ] (square brackets), 185 PCEP
[first_literal - last_literal] call flows, 861–864
metacharacter, 185
IOS XR configurations,
[literals] metacharacter, 185 867–880
grep command, 184–193 lab topologies, 867
matching uppercase/lowercase LSP delegation, 864–867
characters, 187–188
PCC, 860–861
printing lines without patterns,
PCC, LSP configuration,
192–193
874–880
repetition metacharacters,
PCC, SR-TE configuration,
185–186, 190–191
867–870
testing, 186
PCE, 860–861
scale command, 221–222
PCE, LSP configuration,
sed command, 197–205 876–880
shells, 183, 205–208 PCE, SR-PCE, 874

Z01_Abuelenain_Index_p1121-p1196.indd 1178 27/03/21 6:37 pm


serializer.py files, Django 1179

PCE, SR-TE configuration, encryption keys, 488–489


869–874 asymmetric keys, 490
peering, 867 DH protocol, 490–492
RFC, 860–861 ephemeral keys, 490
state synchronization, 863 generation/exchanges, 488–492
SR HKDF, 492
Adj-SID, 824, 827, 839–842 key exchange algorithm, 490
data plane verification, KM, 492
830–831
PFS, 490
forwarding, 832
PSK, 489
IETF drafts, 823
symmetric keys, 489
lab topologies, 825
GCM, 495
MPLS FIB for NPF-XR,
Git, 312
828–830
Linux, 135
Node-SID, 824
ACL, 148–155
NPF-XR, 835
file security management,
Prefix-SID, 824, 827, 834–836
143–148
segments, 824, 825–827
system security, 155–158
SR algorithm, 827
user/group management,
SRGB, 824, 827, 831 136–142
SRLB, 824 MAC, 493–494
SR-MPLS, 824 peer authentication, 496–497
SR-TE, 832–843 TLS, 487–488
underlay networks, 821–822 0-RTT, 502–503
search engines, rules of thumb, 1117 HTTPS, 503
security TLS 1.3, 498–499
AEAD, 495–496 TLS 1.3, alert protocol, 499
AES-CCM protocol, 495 TLS 1.3, handshake protocol,
AES-GCM protocol, 495 499–502
CCM, 495 TLS 1.3, record protocol,
ciphers, 492 499, 503
block ciphers, 492–493 workflows, 499–500
CBC, 492–493 sed command, Linux, 197–205
CMAC, 494 Segment Routing. See SR
CTR mode, 492–493 segments, 824
symmetric ciphers, 492 sequences, YAML, 618–620
digital signatures, 496–497 serializer.py files, Django, 343

Z01_Abuelenain_Index_p1121-p1196.indd 1179 27/03/21 6:37 pm


1180 server response header fields, HTTP

server response header fields, HTTP, controllers, 821–823


425–427 network requirements, 819–821
servers overlay networks, 821
application web servers, running with PCEP
Django, 338–339
call flows, 861–864
Docker servers, 322
IOS XR configurations,
Git servers, setting up, 313–314 867–880
HTTP client/server connections, lab topologies, 867
394–395
LSP delegation, 864–867
public keys, copying onto servers,
PCC, 860–861
524–525
PCC, LSP configuration,
SFTP logins, 541
874–880
status codes, HTTP, 408–409
PCC, SR-TE configuration,
1xx information status codes, 867–870
411
PCE, 860–861
2xx successful status codes,
PCE, LSP configuration,
411–412
876–880
3xx redirection status codes, 412
PCE, SR-PCE, 874
4xx server error status codes,
PCE, SR-TE configuration,
413–414
869–874
5xx client error status codes,
peering, 867
414
RFC, 860–861
Cisco devices, 414
state synchronization, 863
RFC 7231, 409–410
SR
server-streaming RPC, 785
Adj-SID, 824, 827, 839–842
service layer API, IOS XR
programmability, 886 data plane verification,
830–831
service provider programmability,
SDN, 819 forwarding, 832
BGP-LS, 843 IETF drafts, 823
lab topologies, 845–846 lab topologies, 825
link NLRI, 856–857 MPLS FIB for NPF-XR,
828–830
node NLRI, 854–855
Node-SID, 824
NPF-XR, 845, 849, 851–854
NPF-XR, 835
peering, 843–844, 847–849
Prefix-SID, 824, 827, 834–836
prefix NLRI, 858–859
segments, 824, 825–827
routing, 846–847
SR algorithm, 827
routing types (overview),
850–854 SRGB, 824, 827, 831

Z01_Abuelenain_Index_p1121-p1196.indd 1180 27/03/21 6:37 pm


software 1181

SRLB, 824 file comparison operators,


SR-MPLS, 824 230–232
SR-TE, 832–843 functions, 244
underlay networks, 821–822 integer comparison operators,
229–230
services, Linux, 74, 81–83
Linux interface configuration,
session channels, SSH Connection
969–970
Protocol, 519–520
scripting, 206–207, 213–214
session operations, NETCONF,
721–722 string comparison operators,
228–229
Set RPC, gNMI, 807–810
string operators, 227–228
set.add() function, Python, 294
Linux shells, 183
set.difference() function, Python,
294–295 network programmability, 960,
967–973
setfacl command, Linux, 151–155
scripts, 205–208
set.pop() function, Python, 294
SSH, Linux network programmability,
set.remove() function, Python, 294
971–973
sets, Python, 294–295
shred command, 48
settings.py files, Django, 339–341
signatures, digital, 496–497
set.union() function, Python, 294–295
signed right shift (>>) operator,
set.update() function, Python, 294 Python, 281
SFTP (Secure File Transfer Protocol) single inheritance, OOP, 257
fetching/uploading files, 543 single sources of truth. See SSoT
help, 541–542 Slackware, Linux distributions, 26
local/remote directory operations, slicing, Python
542–543
lists, 286–288
logins, 541
string indexes, 278–279
SCP comparisons, 550
SNMP (Simple Network Management
SSH (Secure Shell), 540–541 Protocol)
sg command, Linux, 146–147 model-driven telemetry, 1113
shells network programmability, 959–960
Bash shells socket modules, Python and HTTP,
Arguments.bash script, 213–214 455–457
arithmetic operations, 220–222 soft links, Linux, 55–57
arithmetic operators, 229 software
CLI programmable interface compiling, manually, Linux, 96–97
creation, 963–967 dependencies, 95
Expect programming language, dependency hell, 1114–1115
245–246

Z01_Abuelenain_Index_p1121-p1196.indd 1181 27/03/21 6:37 pm


1182 software

development methodologies, [literals], regular expressions (regex),


1116–1117 185
engineers Python
automation, 19–20 lists, 286–287
career paths, questions, strings, 278
1118–1119 regular expressions (regex), 185
installing on Linux, 94–96 SR (Segment Routing)
package management software, 95 Adj-SID, 824, 827, 839–842
DNF, 95, 117 data plane verification, 830–831
RPM, 95, 97–101 forwarding, 832
YUM, 95, 101–117 IETF drafts, 823
repositories, 95–96 lab topologies, 825
EPEL repositories, 111–112 MPLS FIB for NPF-XR, 828–830
listing, 110–111 Node-SID, 824
LocalRepo repositories, NPF-XR, 835
112–117 Prefix-SID, 824, 827, 834–836
rules of thumb, 1116–1117 segments, 824, 825–827
SDLC, 1116 SR algorithm, 827
SDN, 13 SRGB, 824, 827, 831
sort command, 59–61 SRLB, 824
stdin, 59–61 SR-MPLS, 824
stdout, 61 SR-TE
sorting YAML data streams, Adj-SID, 839–842
630–631 BGP, 836–839
source code, Linux software data plane verification, 842–843
installations, 94
NPF-XR, 836–843
sources of truth, 11–12
PCEP PCC configuration,
automation, reusing automations, 839–842
1111
PCEP PCE configuration,
finding, 1110–1111 869–874
southbound API, 883, 933 policy components, 833–834
space characters in value fields, Prefix-SID, 834–836
XML, 562
process of, 832–833
split() function, 1051–1054
SRGB (Segment Routing Global
square brackets ([ ]) Blocks), 824, 827, 831
[=] operator, Python, 284 SRLB (Segment Routing Local
[first_literal - last_literal], regular Blocks), 824
expressions (regex), 185 SR-PCE, 874

Z01_Abuelenain_Index_p1121-p1196.indd 1182 27/03/21 6:37 pm


statements (conditional) 1183

srv directory, Linux, 37 SSH1, 510–512


SSH (Secure Shell) SSH2, 512
Authentication Protocol, 514–516 IOS XE configurations, 527
host-based authentication, IOS XR configurations,
517–518 532–533
password authentication, 517, SSH-TRANS, 513–514
522–523, 525–526 tunneling, 520
public key authentication, verifying sessions, 533–534
516–517
SSoT (Single Sources of Truth),
Bash shells, 539–540, 548–549 11–12, 1110–1111
Connection Protocol, 518–521 start lines, HTTP messages, 415
debugging, 528–531, 533–534 start tags, XML, 555
key-based authentication, 523–525 start-time parameter, RESTCONF,
Linux network programmability, 771
971–973 stat command, 62–63
NETCONF over SSH, 694–695 state management, HTTP, 483–487
OpenSSH, 510, 522 state synchronization, PCEP, 863
overview, 509–510 statements (conditional)
protocol setup flow, 510 Ansible, 1016–1019
public keys, copying onto servers, checking for substrings in vari-
524–525 ables, 1021–1022
remote access requirements, 510 checking for variables,
SCP 1019–1021
CentOS, 549–550 combining multiple conditional
SFTP comparisons, 550 statements, 1022–1024
setting up, 521 conditional statements with
loops, 1024–1027
CentOS, 521–526
conditional statements with
Cisco devices, 545–549
loops and variables,
IOS XE, 526–531, 545–546 1027–1033
IOS XR, 532–536, 546–547 Jinja2 templates, 1045–1049
NX-OS, 537–540, 547–548 AND/OR logic, 1022–1024
SFTP, 540–541 Jinja2 templates, 1045–1049
fetching/uploading files, 543 Linux scripting, 226
help, 541–542 == (double equal sign), 229
local/remote directory = (equal sign), 229
operations, 542–543
case-in constructs, 232–234
logins, 541
if-then constructs, 226–232
SCP comparisons, 550

Z01_Abuelenain_Index_p1121-p1196.indd 1183 27/03/21 6:37 pm


1184 statements (conditional)

nested code blocks with conditional string operators, Bash shells,


statements, Python control flow, 227–228
295–296 string variables, Ansible, 1006
static routing strings, JSON, 593
200 OK responses str.lower() function, Python, 279–280
DELETE method, 405–406 str.replace() function, Python, 279–280
POST method, 394–401 str.reverse() function, Python,
PUT method, 403–404 292–293
Nexus switches str.strip() function, Python, 279–280
DELETE method, 405–406 str.upper() function, Python,
POST method, 399–401 279–280, 292–293
PUT method, 402–405 stylesheets, XSLT, 578–579
stderr, Linux, 59, 62–65 su command, 29–30
stdin, Linux, 59–61 subnets (remote), Linux routing
tables, 166–167
stdout, Linux, 59, 61, 62–65
Subscribe RPC, gNMI, 811–814
stopping jobs, 80–81
subtree filters, NETCONF, 703–710
stop-time parameter, RESTCONF,
771 sudo command, Linux, 136
storage, Linux, 119 sudo yum remove httpd command,
Linux, 109
/dev directory, 119–120
sudo yum update command, Linux, 110
contents of, 120
sum() function, Python, 249–250
device file types, 120–121
switches (Nexus)
fdisk command, 121–125
authentication, 401–402, 463
file system creation, 125–126
static routing
hard disk partitions, 121–125
DELETE method, 405–406
mkfs command, 125–126
POST method, 399–401
mounting file systems, 126–128
PUT method, 402–405
unmounting file systems, 127
symbolic notation, file permissions,
LVM, 128–135
144–145
streaming telemetry, 1113–1114
symlinks, Linux, 56–57
streams, HTTP/2, 505
symmetric ciphers, 492
string comparison operators, Bash
symmetric keys, 489
shells, 228–229
sys directory, Linux, 37
string data types, Python, 276–277
sysctl command, Linux, 167–168
concatenating, 277
syslog, model-driven telemetry, 1113
formatting, 280
syslog messages, Linux, 93–94
indexes, 277–279
system calls, Linux, 24

Z01_Abuelenain_Index_p1121-p1196.indd 1184 27/03/21 6:37 pm


templates, Jinja2 1185

system daemons, Linux, 24 defined, 555


system information, Linux end tags, 555
cat/proc/cpuinfo command, 87–88 predefined entries, 557
date command, 85–86 prefixes, 560–561
dmesg command, 90 start tags, 555
dmidecode command, 88–89 using multiple times, 558–559
lspci command, 90 values, 555
timedatectl command, 86 YAML, 617, 621–624
update command, 86–87 tail command, Linux system logs, 91
system logs, Linux, 91 tar archiving utility, Linux, 67, 70–73
journald command, 93–94 TCP over Python, 455–457
lastlog command, 91 TE (Traffic Engineering), SR-TE
rotation, 91 Adj-SID, 839–842
ryslogd command, 91–93 BGP, 836–839
tail command, 91 data plane verification, 842–843
system maintenance, Linux, 73 NPF-XR, 836–843
jobs, 74 PCEP PCC configuration, 839–842
displaying status, 80 PCEP PCE configuration, 869–874
stopping, 80–81 policy components, 833–834
kill command, 78–80, 81 Prefix-SID, 834–836
pgrep command, 78 process of, 832–833
processes, 73–74, 80–81 tee command, 66–67
ps command, 74–77 telemetry
services, 74, 81–83 IOS XE programmability, 886
systemctl command, 81–83 IOS XR programmability, 887
threads, 73 model-driven telemetry, 1113–1114
system security, Linux, 155–158 Open NX-OS programmability, 885
systemctl command, Linux system streaming telemetry, 1113–1114
maintenance, 81–83 templates, Jinja2, 363–364
Ansible, 1034–1040
T conditional statements,
1045–1049
tags loops, 1040–1043
XML playbooks, 1040–1043
child/parent relationships, variables, 1042–1043
555–556 IOS XE, 367–371
creating, 557 IOS XR, 367–371

Z01_Abuelenain_Index_p1121-p1196.indd 1185 27/03/21 6:37 pm


1186 templates, Jinja2

NAPALM libraries, 371–375 tmp directory, Linux, 37


Netmiko libraries, 364–367 toggling interface state, Linux, 161
Nornir libraries, 367–369, 371–375 tokenizers, Python code execution, 263
NX-OS, 367–371 top command, Linux resource
nx-os_config modules, 1091–1093 utilization, 83–85
Terminal, 29 touch command, 46, 48
testing TRACE method, 408
Python code, 269 Traffic Engineering. See TE
transactions, HTTP, 389
regular expressions (regex), 186
client requests, 397–398
repetition metacharacters, 190–191
CONNECT method, 407
threads, Linux, 73
DELETE method, 405–406
thumb, rules of
GET method, 398
API, 1118
GET method, Bash shells,
application hosting, 1115–1116
447–454
automation, 1109–1110
GET method, Postman, 445–446
complexity, 1111–1112 HEAD method, 398
cost/benefit analysis, 1112 OPTIONS method, 407–408
reusing automations, 1111 POST method, 399–402,
cleaning up networks, 1110 443–445, 465
containers, 1114–1115 PUT method, 402–405
databases, 1117 TRACE method, 408
documentation, 1111 server status codes, 408–409
model-driven telemetry, 1113–1114 1xx information status codes,
search engines, 1117 411
software development 2xx successful status codes,
methodologies, 1116–1117 411–412
time stamps, Linux files, 41 3xx redirection status codes, 412
timedatectl command, Linux, 86 4xx server error status codes,
413–414
TLS (Transport Layer Security),
487–488 5xx client error status codes, 414
0-RTT, 502–503 Cisco devices, 414
HTTPS, 503 RFC 7231, 409–410
transport layer
TLS 1.3, 498–499
NETCONF, 692–693
alert protocol, 499
over SSH, 694–695
handshake protocol, 499–502
transport protocol
record protocol, 499, 503
requirements, 693–694
workflows, 499–500
RESTCONF, 742, 743

Z01_Abuelenain_Index_p1121-p1196.indd 1186 27/03/21 6:37 pm


until-do loops 1187

transport protocols, 18–19 two asterisks (**), assignment


gRPC operator, Python, 281
gNMI, 798–799 two dot notation (..), Linux
directories, 37
gNMI, anatomy of, 799–801
two equal signs (==)
gNMI, Capabilities RPC,
810–811 conditional statements, 229
gNMI, Get RPC, 801–807 Jinja2, 1019
gNMI, insecure mode in IOS Python, 285
XE, 815 two semicolons (;;), case-in constructs,
gNMI, managing network 233–234
elements, 814–818
gNMI, Python metaclasses,
815–816
U
gNMI, Python sample Get UDS API, 945
script, 816–818 unary RPC, 785
gNMI, Set RPC, 807–810 unbuffered/buffered access, Linux /
gNMI, Subscribe RPC, dev directory, 120
811–814 underlay networks, 9, 821–822
history of, 782–784 Unified Communications, 942
managing network elements, Cisco Business Edition, 942
814–818
Cisco Webex Cloud Calling, 942
principles of, 782–784
Cisco Webex Contact Center, 943
Protobuf, example of, 788–789
Cisco Webex teams, 942
Protobuf, Python, 790–798
Contact Center, 942–943
server sample, 794–797
CUCM, 942
as a transport, 784–786
AXL API, 944
requirements for efficent transport,
CER API, 944
781–782
CUCM Serviceability API, 945
truth, sources of, 11–12
PAWS API, 944
automations, 1111
UDS API, 945
finding, 1110–1111
Unified Contact Center (Cisco), 943
TSP API (Transport Service Provider
API), 945 Unified Contact Center (Cisco), 943
tunneling, SSH, 520 <unlock> operations, NETCONF,
720–721
tuples, Python
unmounting Linux file systems, 127
deleting, 293
unstructured data, CLI, 19
functions, 292–293
until-do loops, 239–240
joining, 293

Z01_Abuelenain_Index_p1121-p1196.indd 1187 27/03/21 6:37 pm


1188 update command, Linux

update command, Linux, 86–87 usr/local directory, Linux, 37


updating usr/sbin directory, Linux, 37
IOS XE with Ansible hosts/variables, UTF-8 encoding, HTTP/1.1
1057–1058 authentication, 472–473
local Git repositories, 314–315 utility modules, Ansible, 1003
remote Git repositories, fetching
updates, 314–315
uploading files via SFTP, 543
V
uppercase/lowercase characters, validate capability, NETCONF, 733
matching, regular expressions <validate> operations, 724–725
(regex), 187–188
validate_person() function, Python,
URI (Universal Resource Identifiers), 307–308, 309
389, 431, 432–436
validating
URL (Uniform Resource Locators),
data, JSON schemas, 609–614
431, 432
JSON schemas, 596–597
API, 945
NETCONF configurations, 724–725
NETCONF, 733–734
XML, 562–563
urllib packages, Python and HTTP,
458–463 DTD, 563–565, 574
urls.py files, Django, 343 XSD, 565–574
URN (Uniform Resource Names), value assignments
431–432 lists, Python, 286–288
user space (userland), Linux, 23–24 variables, 218–219
useradd command, Linux, 138–140 value fields (XML), space characters
userdel command, Linux, 141 in, 562
user/group management, Linux, values, XML, 555
136–138 var directory, Linux, 37
changing passwords, 141 variables
creating groups, 141 Ansible, 999
creating new users, 138–141 Boolean variables, 1006
deleting groups, 141–142 checking for substrings with
deleting users, 141 conditional statements,
1021–1022
getting user information, 136
checking with conditional
modifying user details, 142
statements, 1019–1021
setting user passwords, 138–141
conditional statements
usermod command, Linux, 142 with loops and variables,
usr directory, Linux, 37 1027–1033
usr/bin directory, Linux, 37 defining from external files,
1007–1009

Z01_Abuelenain_Index_p1121-p1196.indd 1188 27/03/21 6:37 pm


virtualenv tool 1189

defining in inventory files, IOS XR with Ansible


1009–1011 verifying management,
defining in playbooks, 1074–1075
1005–1006 verifying operational data,
dictionary variables, 1007 1074–1078
importing from external files, NETCONF
1007–1009 configuring, 1103–1107
Jinja2 templates, 1042–1043 operational data, 1098–1103
list variables, 1007 NX-OS with Ansible
setting dynamically, collecting show output with
1011–1013 nxos_command, 1086–1088
string variables, 1006 configuring with nx-os_*
types of, 1006–1007 modules, 1093–1095
Jinja2 templates, 1042–1043 configuring with nx-os_config
Linux scripting, 217–218 modules, 1086–1088
declaring, 218–219 interactive commands,
1088–1089
one-dimensional variables, 218
verifying management,
value assignments, 218–219
1085–1086
nx-os_config modules, 1090–1091
verifying operational data,
Python, 270–271 1086–1089
deleting, 272–273 Python code, 269
dynamic data type allocation, YANG modules, downloaded,
271–272 665–666
scope, 272 version command, Ansible, 991–992
vendor/API matrix, network version control, application
programmability, 957–958 development, 311
vendor-specific (native) YANG vgdisplay command, Linux, 132,
modules, 666–669 133–134
verifying viewing
data planes Linux files, 41–46
SR, 830–831 routing tables, Linux, 163
SR-TE, 842–843 views.py files, Django, 343
Docker, 320–322 virtual environments
IOS XE with Ansible creating with virtualenv tool,
ios_command module, 332–333
1058–1060 Flask installations, 345–346
verifying management, 1057 virtualenv tool, 331
verifying operational data, installing, 331
1058–1060

Z01_Abuelenain_Index_p1121-p1196.indd 1189 27/03/21 6:37 pm


1190 virtualenv tool

virtual environments, creating, urls.py files, 343


332–333 views.py files, 343
virtualization Flask
defined, 8–9 accessing in-memory employee
Docker containers, 317–318 data, 347–349
Network Programmability and installing in virtual
Automation toolbox, 17 environments, 345–346
single sources of truth, 11–12 retrieving ID-based data,
VLAN, awareness, 8–9 349–350
VLAN (Virtual Local-Area simple applications, 346–347
Networks), awareness, 8–9 front end development, 336
volumes, Linux Postman, 345
logical volumes, 132–133 Webex Board (Cisco), 943
mounting, 134–135 Webex Cloud Calling (Cisco), 942
physical volumes, 130–131 Webex Contact Center (Cisco), 943
volume groups, 132, 133–134 Webex devices, xAPI, 946
VPN (Virtual Private Networks), IP Webex Meetings (Cisco), 943
VPN and JSON schemas, 597–598, REST API, 945–946, 948–954
601–602, 607–609
TSP API, 945
URL API, 945
W XML API, 945
Webex Room Series (Cisco), 944
web application development,
250–251 Webex Support (Cisco), 943
web/API development, 336–337 Webex Teams (Cisco), 942, 945–946,
948–954
back end development, 336
Webhook Alerts API (Meraki), 922
Django, 337
webhooks, 882, 933, 935
application web servers,
338–339 well-formed XML documents, 562
creating applications, 341–345 westbound API, 883, 933
demo applications, 343–345 while loops, control flow, 304–306
installing, 337–338 while-do loops, 237–239
migrations, 338–339 whitespaces, HTTP messages, 416
models.py files, 343 Wind River, Linux distributions, 26
serializer.py files, 343 with-defaults parameter, RESTCONF,
771
settings.py files, 339–341
writable-running capability,
starting new projects, 337–338
NETCONF, 732

Z01_Abuelenain_Index_p1121-p1196.indd 1190 27/03/21 6:37 pm


XML (Extensible Markup Language) 1191

X space characters in value fields, 562


tags
x11 channels, SSH Connection child/parent relationships,
Protocol, 520 555–556
xAPI (Experience API), 946 creating, 557
XML (Extensible Markup Language) defined, 555
API, 945 end tags, 555
attributes, 558, 568 predefined entries, 557
AXL API, 944 prefixes, 560–561
basic XML document example, 554 start tags, XML, 555
child/parent relationships, 555–556 using multiple times, 558–559
comments, 558 values, 555
data types, 567–568 usage, 553–554
declarations, 566–567 validation, 562–563
DTD, 563 DTD, 563–565, 574
example of, 563–564 XSD, 565–574
joint XML/DTD files, 564–565 values, 555
formatting rules, 561–562 well-formed XML documents, 562
history of, 553–554 XPath, 574, 575
leading spaces in XML documents, expressions, 575–576
555 expressions, absolute path, 576
namespaces, 559–561 expressions, absolute path and
nesting multiple outputs, 577
format, 561–562 expressions, anywhere
selection, 576
relationships, 555–556
expressions, path definitions,
overview, 553–554
578
predefined entries, 557
expressions, predicates, 577
Python and XML processing, 580
logical operator values, 577
dictionaries, 583–585
nodes, 574–575
element mergers, 585–587
XSD, 565
element name/attribute
attribute validation, 570–571
extraction, 581–582
attributes, 568
properties/methods, 580–581
complex elements, 570–573
rerunning processing for
updated documents, 587–588 content validation, predefined
values, 568–569
script creation, 580–581
content validation, regexp, 569
value extraction, 582–583

Z01_Abuelenain_Index_p1121-p1196.indd 1191 27/03/21 6:37 pm


1192 XML (Extensible Markup Language)

data types, 567–568 example of, 565–566


declarations, 566–567 pattern validation, 569–570
DTD comparisons, 574 XSLT (XML Stylesheet Language
element validation, 567 Transformation), 578, 579
example of, 565–566 elements of, 578
pattern validation, 569–570 stylesheets, 578–579
XSLT, 578, 579 xz archiving utility, Linux, 67, 69–70,
72–73
elements of, 578
stylesheets, 578–579
YAML versus, 615–616 Y-Z
XOR operator (^), Python, 281
YAML (YAML Ain’t Markup
XPath, 574 Language), 615
expressions, 575–576 anchors, 624–625
absolute path, 576 collections, 618–620
absolute path and multiple out- comments, 616
puts, 577
configuration files, building,
anywhere selection, 576 635–637
path definitions, 578 data readability, 616
predicates, 577 data representation, 615
logical operator values, 577 data streams
NETCONF saving to files, 629
capabilities, 735 sorting, 630–631
filters, 710–712 data types, 616
nodes, 574–575 example of, 625–626
syntax elements, 575 files
XSD (XML Schema Definition), 565 creating, 616
attribute validation, 570–571 extensions, 616
attributes, 568 rules for creating, 616
complex elements, 570–573 Jinja templates, 635–637
content validation JSON versus, 615–616
predefined values, 568–569 mappings, 618–620
regexp, 569 merge keys, 624–625
data types, 567–568 multiple documents, loading,
declarations, 566–567 632–633
DTD comparisons, 574 nodes, 617
element validation, 567 performance, 616

Z01_Abuelenain_Index_p1121-p1196.indd 1192 27/03/21 6:37 pm


YANG (Yet Another Next Generation) 1193

purpose of, 616 modules, deviations, 658–662


Python modules, home of, 664–666
PyYAML, 626–628 modules, IETF YANG modules,
saving data streams to files, 670–671
629 modules, native (vendor-
serializing Python objects, specific) modules, 666–669
628–629 modules, OpenConfig YANG
sorting data streams, 630–631 modules, 671–673
yaml.dump() method, 628–631 modules, structure of, 644–646
yaml.load() method, 631–632 modules, verifying downloaded
modules, 665–666
yaml.load_all() method,
632–633 nodes, 649
yaml.scan() method, 633–635 nodes, container nodes,
647–648
scalars, 620–621
nodes, grouping, 654–656
sequences, 618–620
nodes, leaf nodes, 649–651
speed, 616
nodes, leaf-list nodes, 651–652
starting/closing documents, 616–617
nodes, list nodes, 647–648
structure of, 617–618
pyang, 673–679
tags, 617, 621–624
pyang, JTOX drivers, 683–687
usability, 616
pyangbind, 679–682
XML versus, 615–616
YANG 1.1, 662–663
yaml.dump() method, 628–631
JSD, 595
yaml.load() method, 631–632
NETCONF/YANG
yaml.load_all() method, 632–633
configuring, 1103–1107
yaml.scan() method, 633–635
netconf_get module, 1103–1107
YANG (Yet Another Next
Generation), 17 network programmability,
973–978
content layer, NETCONF, 725–729
verifying operational data,
data modeling, 639–640, 642
1098–1103
importance of, 640–642
RESTCONF
modules, 642–644
data resource, 753–756
modules, augmentation,
schema resource, 750–753
656–658
YANG library version resource,
modules, built-in data types,
758
647–648
RESTCONF/YANG, network
modules, cloning, 665
programmability, 978–987
modules, derived data types,
YANG 1.1, 662–663
648–649

Z01_Abuelenain_Index_p1121-p1196.indd 1193 27/03/21 6:37 pm


1194 YUM (Yellowdog Updater Modified)

YUM (Yellowdog Updater Modified), yum install command, 106–109


95, 101 yum list command, 103
commands list, 102–103 yum repolist all command,
sudo yum remove httpd command, 110–111
109 yum search command, 103–104
sudo yum update command, 110 yum-config-manager command,
yum info command, 104–105 111–112

Z01_Abuelenain_Index_p1121-p1196.indd 1194 27/03/21 6:37 pm

You might also like