Tag Archives: linux

Configuring TACACS+ Server on Ubuntu 14.04LTS

It’s all change in the office so far this year, which is quite good as I’m involved in more projects, and who doesn’t enjoy a few projects 😉

The latest thing I was asked to look into was to create a new TACACS+ server as our current server on a HP Proliant BL460c G1 Blade is going to be decommissioned so we need to give it a new home! It was decided that it should be virtualized as there isn’t a need to have a physical server for something that can be slimmed down dramatically. With that being said this post will go over how to configure a TACACS+ server and configure TACACS+ authentication on a Juniper device.

TACACS+ is an improvement on its first version TACACS, as TACACS+ is an entirely new protocol and is not compatible with its predecessors, TACACS and XTACACS. TACACS+ uses TCP. Since TACACS+ uses the authentication, authorisation, and accounting (AAA) architecture, these separate components of the protocol can be segregated and handled on separate servers. TACACS+ allows you to set granular access policies for users and groups, commands, location, subnet, or even device type. The TACACS+ protocol also provides detailed logging of users and what commands have been run on specific devices. In addition, the protocol can run on either Windows or UNIX/Linux.

Although TACACS+ was developed by Cisco Systems, it is actually an open standard as defined by RFC1482 and has been incorporated into a number of different vendors including Alcatel/Lucent, Arbor, Brocade/Foundry, Cisco/Linksys, Extreme, HP/3Com, Huawei, IBM, Juniper/Netscreen, Netgear and any others.

The setup I had for testing was a simple one; I had 2 EXSi Ubuntu 14.04LTS hosts, one as the TACACS+ server with the second being used as Jump-box to access a Juniper SRX220 that will be configured for TACACS authentication.

With all that talk out of the way, let’s get cracking 🙂

You will run sudo/root privileges

Server Configuration

Fortunately, with the newer version of Ubuntu, from apt-get repository you can easily download the tacacs+ package it will also install libtacacs+1

[email protected]:~$ sudo apt-get install tacacs+
[sudo] password for marquk01: 
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
The following NEW packages will be installed
  libtacacs+1 tacacs+

Having installed the package now we can run the command ps -ef | grep tac_plus and it will show us the location of the configuration file and if the process is running:

[email protected]:~$ ps -ef | grep tac_plus
root      1220     1  0 11:37 ?        00:00:00 /usr/sbin/tac_plus -C /etc/tacacs+/tac_plus.conf
marquk01 22730  2682  0 13:55 pts/0    00:00:00 grep --color=auto tac_plus

As the process is running there’s a few useful binary files that are important to know, these can be seen when you type tac and hit TAB.

[email protected]:~$ tac
tac  tac_plus  tac_pwd

The important files are tac_plus and tac_pwd:

  • tac_plus is the TACACS+ daemon. You can run daemon via the cli
  • tac_pwd is used to generate a Data Encryption Standard (DES) or Message-Digest 5 (MD5) hash from clear text. DES is the defualt, to generate a MD5 hash you need to add -m flag.

We will need to configure the tac_plus.conf file, but firstly we will need to back-up the original file to refer back to if there is any issues

[email protected]:~$ sudo cp /etc/tacacs+/tac_plus.conf /etc/tacacs+/tac_plus.conf.old

I’ll explain from top-down of what my file looks like. The default file has more parameters than I used, as my file doesn’t need too much complexity. My example will also show you how to configure the basis Accounting, Secret Key, Users and Groups. Logically when I look at the layout of the file as I have, it doesn’t make sense… However, all the information is there soooooo it doesn’t matter :p lol


Firstly we’ll need to set the file that the accounting information will be written to. By default this is /var/log/tac_plus.acct, however you can have this file where you like if you don’t want you use the default file and path.

You have to create this file yourself. This can be done by running the command sudo touch /var/log/tac_plus.acct

# Created by Henry-Nicolas Tourneur([email protected])
# See man(5) tac_plus.conf for more details

# Define where to log accounting data, this is the default.

accounting file = /var/log/tac_plus.acct

Secret Key

The Server and Client need to have a matching key so the AAA packets can be encrypted. This key can be anything you wish however, if you’re going to have a key with white-space, key-words, or special characters, you’ll need to use quotation marks

# This is the key that clients have to use to access Tacacs+

key = testing123


You’ll need to define the users that will have access to the device. Each user needs to be associated to a group and have their password defined. The password has to be set as either a MD5 or DES hash. By using tac_pwd use can get your hashed output:

[email protected]:~$ tac_pwd
Password to be encrypted: lab123

There is an additional stanza service = junos-exec that defines an additional group. This is Juniper specific and I’ll explain this later. I created two users kmarquis; will have permission to do anything and second usertest; that will only have Read-Only access. Both have the same password. Usernames ARE case sensitive.

# We also can define local users and specify a file where data is stored.
# That file may be filled using tac_pwd
user = kmarquis {
    name = "Keeran Marquis"
    member = admin
    login = des kBeC6JDjU8icY
		service = junos-exec {
			local-user-name = remote-admin

user = test {
    name = "Test User"
    member = read-only
    login =  des kBeC6JDjU8icY
        service = junos-exec {
            local-user-name = remote-read-only


As you can guess, groups are where you define the level of access and what commands will be used by the group. The commands, for my example, are used to define actions that are largely accepted by most vendors with the expectation of Juniper (from my knowledge but correct me if I’m wrong), although I wont be confirming the configuration works in this post. I have checked with a Cisco device and they worked as expected.

We have a few parameters that are important remember:

  • default service: defines the default permission that the user will have. By default, if this statement isn’t used or left blank, it’s denied. Meaning that each permitted command users of this group will have to be listed. If you want the default permission to allow, then the statement permit is needed
  • service: define services which the group is authorised to execute, these could be commands that the group is authorised to execute. Authorisation must be configured on both the client and the daemon to operate correctly.
  • cmd: This is where you list a command and set an action, it will be either be a permit or deny. Additionally by having the .* this means that any command after the first word is affected. i.e my example below, all show commands will be permitted

In my example I have two groups, admin and read-only, the admin group will have full access permitted and the read-only group, as the name suggests, will have read-only access and will be denied from any configuration, clear or restart commands.

# We can also specify rules valid per group of users.
group = admin {
	default service = permit
	service = exec {
		priv-lvl = 15

group = read-only {
	service = exec {
		priv-lvl = 15
	cmd = show {
		permit .*
	cmd = write {
		permit term
	cmd = dir {
		permit .*
	cmd = admin {
		permit .*
	cmd = terminal {
		permit .*
	cmd = more {
		permit .*
	cmd = exit {
		permit .*
	cmd = logout {
		permit .*

My completed tac_plus file can be seen here.

For more in-depth detail and additional parameters that can be configured in this file, you can find them via the man pages using the command man tac_plus or online Ubuntu tac_plus Manual Documentation

Once you’re happy with everything you can run service tacacs_plus check to make sure the syntax is correct and if you get any errors you will need to restart the daemon using service tacacs_plus restart

TACACS+ Daemon Commands
Additional commands that will be useful to remember:

service tacacs_plus check
service tacacs_plus status
service tacacs_plus stop
service tacacs_plus start
service tacacs_plus restart

With that we have a TACACS+ server configured 🙂

Before getting into the configuration of the SRX, I stated earlier that there’s a Juniper Specific stanza in tac_plus.conf file. When authenticating users against a TACACS+ server on juniper devices and you’ll need to apply Juniper Networks Vendor-Specific TACACS+ Attributes.

These attributes can be either:

  1. Specified in the tac_plus.conf file by using regular expressions to list all the commands that the user has permitted or denied. A user will need to be created on the device with that user being referred under the local-user-name statement. The stanza would look something:
    service = junos-exec {
    	local-user-name = xxx
    	allow-commands =  .*
    	allow-configurations = .*
    	deny-commands = 
    	deny-configuration = 
    	user-permissions = 
  2. Configure a class that has states all the permitted or denied permissions, this class will be linked to a user. Both need to be configured on the device. Once this has been created you’ll need to refer, said user, under the local-user-name

The Junos OS retrieves these attributes through an authorization request of the TACACS+ server after authenticating a user. For my example, I went with the latter. Now we’ll jump onto the SRX220 and get that sorted with TACACS+ AAA configuration.

Juniper Configuration

Firstly, you will have to set the TACACS+ server with its secret key. For standard practice and force of habit, I have set the single connection and forced the source-address of the SRX. By using the single connection statement, this means that instead of multiple TCP sessions connecting to the device from a server, a single session is maintained between them. In addition, for best practice an authentication order should be set so that if there was an issue or loss of connectivity to the TACACS+ server, you’ll be able to fall back to locally defined users.

authentication-order [ tacplus password ];
tacplus-server { {
        secret "$9$SszyMXVb2aGiYgi.fzCAIEcyvWX7-w24"; ## SECRET-DATA

With the TACACS+ server we’re able log different events that take place on the device and get those commands sent to the server. From my experience the accounting events that you would most want logged are logins, configuration changes and interactive commands. This is set under system accounting stanza

accounting {
    events [ login change-log interactive-commands ];
    destination {

Next, under the system login stanza, you need to create a class that has a list of permission available to the user(s) that are going to be associated to it. The user(s) are what are used in the tac_plus.conf file. In my example I created two classes, one with all permission super-user-local and the other user with read-only and basic troubleshooting options (ie ping, traceroute, telnet etc) read-only-user-local. These associated this classes with 2 users remote-admin and remote-read-only

login {
    class read-only-user-local {
        permissions [ network view view-configuration ];
    class super-user-local {            
        permissions all;
    user remote {
        full-name "TACACS User";
        uid 2001;
        class super-user-local;
    user remote-read-only {
        full-name "TACACS read-only user";
        uid 2002;
        class read-only-user-local;
You can learn more about the different permissions flags available here on Juniper TechLibrary


To confirm the configuration is working as expected, I will ssh onto the SRX220 with both the admin user kmarquis and the read-only user test. With both users, I will log in and try to configure the description This is a test on a random port. As you can see below I had no problem with user kmarquis. However, when I logged in with the test user I wasn’t able to enter the configuration mode as the permission wasn’t granted, and for that user the command isn’t even recognized. I ran a show command and you will see that none of the passwords are shown. Again this is due to the permission level granted.

Admin AccessRead Only Access
[email protected]:~$ ssh -l kmarquis
--- JUNOS 12.1X47-D30.4 built 2015-11-13 14:16:02 UTC
[email protected]> configure 
Entering configuration mode
[email protected]# set interfaces ge-0/0/5 description "This is a test" 

[email protected]# commit and-quit 

[email protected]>
[email protected]:~$ ssh -l test
--- JUNOS 12.1X47-D30.4 built 2015-11-13 14:16:02 UTC
[email protected]> configure
unknown command.

[email protected]> show configuration 
## Last commit: 2016-02-01 12:56:23 UTC by kmarquis
version 12.1X47-D30.4;
system {
    host-name v6-testing;
    authentication-order [ tacplus password ];
    root-authentication {
        encrypted-password /* SECRET-DATA */; ## SECRET-DATA

If we check the /var/log/tac_plus.acct file we’ll be able to see all the permitted commands by each user. This is additional confirmation that the users have successfully authenticated against the TACACS+ server and their related permissions authorised to the device.

Feb  1 12:55:38      kmarquis        ttyp0      start   task_id=1       service=shell   process*mgd[38808]      cmd=login
Feb  1 12:55:41      kmarquis        ttyp0      stop    task_id=2       service=shell   process*mgd[38808]      cmd=show configuration 
Feb  1 12:55:44      kmarquis        ttyp0      stop    task_id=3       service=shell   process*mgd[38808]      cmd=edit 
Feb  1 12:56:01      kmarquis        ttyp0      stop    task_id=4       service=shell   process*mgd[38808]      cmd=set: [interfaces ge-0/0/5 de$
Feb  1 12:56:01      kmarquis        ttyp0      stop    task_id=5       service=shell   process*mgd[38808]      cmd=set interfaces ge-0/0/5 desc$
Feb  1 12:56:05      kmarquis        ttyp0      stop    task_id=6       service=shell   process*mgd[38808]      cmd=commit and-quit 
Feb  1 12:56:27      kmarquis        ttyp0      stop    task_id=7       service=shell   process*mgd[38808]      cmd=exit 
Feb  1 12:56:27      kmarquis        ttyp0      stop    task_id=1       service=shell   elapsed_time=49 process*mgd[38808]      cmd=logout
Feb  1 12:56:34      test    ttyp0      start   task_id=1       service=shell   process*mgd[38845]      cmd=login
Feb  1 12:56:44      test    ttyp0      stop    task_id=2       service=shell   process*mgd[38845]      cmd=show configuration 
Feb  1 12:56:53      test    ttyp0      stop    task_id=3       service=shell   process*mgd[38845]      cmd=show system uptime 
Feb  1 12:56:56      test    ttyp0      stop    task_id=4       service=shell   process*mgd[38845]      cmd=exit 
Feb  1 12:56:56      test    ttyp0      stop    task_id=1       service=shell   elapsed_time=22 process*mgd[38845]      cmd=logout

And with that all, we have a fully configured and working AAA TACACS+ server 🙂

Extra Treat 🙂
I have included the set commands below:

set system tacplus-server secret "$9$SszyMXVb2aGiYgi.fzCAIEcyvWX7-w24"
set system tacplus-server single-connection
set system tacplus-server source-address

set system authentication-order tacplus
set system authentication-order password

set system accounting events login
set system accounting events change-log
set system accounting events interactive-commands
set system accounting destination tacplus

set system login class super-user-local permissions all
set system login class read-only-user-local permissions network
set system login class read-only-user-local permissions view
set system login class read-only-user-local permissions view-configuration

set system login user remote-read-only full-name "TACACS read-only user"
set system login user remote-read-only uid 2005
set system login user remote-read-only class read-only-user-local
set system login user remote-admin full-name "TACACS User"
set system login user remote-admin uid 2006
set system login user remote-admin class super-user-local
Extra Extra Treat 😀
P.S. If you want to see what configuration could be used on a Cisco device I have added it below. Although I didn’t test it myself, this is the config we have in production and it works :p

aaa new-model
aaa authentication login default group tacacs+ local enable
aaa authorization exec default group tacacs+ local none 
aaa authorization commands 0 default group tacacs+ local none 
aaa authorization commands 1 default group tacacs+ local none 
aaa authorization commands 15 default group tacacs+ local none 
aaa accounting exec default start-stop group tacacs+
aaa accounting commands 0 default start-stop group tacacs+
aaa accounting commands 1 default start-stop group tacacs+
aaa accounting commands 15 default start-stop group tacacs+
aaa session-id common


Configure TACACS+ Ubuntu 14.04LTS
TACACS+ Accounting
TACACS+ Authenication
TACACS+ Advantages

Share this:

Configuring NTP Server on Ubuntu

As part of a few changes happening I’ve been asked to look into how difficult would it be to configure our own local NTP server. From looking at very useful Ubuntu Man Pages and finding great articles on The Geek Stuff (one of my favourites sites) and Blogging Dragon, it appears that it’s more straightforward than I expected! Soooo this post will note down how to install and configure a NTP Server.

Network Time Protocol (NTP) is a network protocol for clock synchronization between servers, network devices and desktops. NTP is defined in RFC5905 and is described as:

Network Time Protocol version 4 (NTPv4), which is widely used to synchronize system clocks among a set of distributed timeservers and clients…. The NTP subnet model includes a number of widely accessible primary time servers synchronized by wire or radio to national standards. The purpose of the NTP protocol is to convey timekeeping information from these primary servers to secondary time servers and clients via both private networks and the public Internet.

For this test, I’m using ESXi Ubuntu 14.04LTS host as the local NTP server and will be configuring both a Juniper SRX220 and another ESXi Ubuntu 14.04LTS host as a NTP clients. The local NTP server’s IP address is

You will need root and/or sudo privileges

With all the background done, let’s get cracking 😀

As always, when getting anything from Ubuntu’s apt-get repository we’ll need to make sure to run update; to get all the newest version of packages currently installed and run dist-upgrade; to ensure the most important packages are updated as it has a “smart” conflict resolution system.

sudo apt-get update
sudo apt-get dist-upgrade

Having ensured the server’s packages are up to date, we can install the ntp and ntpdate packages by using apt-get install ntp ntpdate

sudo apt-get install ntp ntpdate

Before making any changes we need to make sure that the default time zone to Universal Time Coordinated (UTC). This is because UTC is regarded as the primary time standard by which the world regulates clocks and time. You can check/change the default time zone by running the command dpkg-reconfigure tzdata. You will be prompted to these screens where you can select the time zone: Screen #1 and Screen #2.

Once the time zone has been set, you will get the output below confirming the Time Zone:

[email protected]:~$ sudo dpkg-reconfigure tzdata

Current default time zone: 'Etc/UTC'
Local time is now:      Mon Jan 11 14:56:57 UTC 2016.
Universal Time is now:  Mon Jan 11 14:56:57 UTC 2016.

Next create a backup of the ntp.conf file

sudo cp /etc/ntp.conf /etc/ntp.conf.old

Use a text editor (I prefer nano) to open up the ntp.conf file and find the following lines below:

# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
# on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for
# more information.
server 0.ubuntu.pool.ntp.org
server 1.ubuntu.pool.ntp.org
server 2.ubuntu.pool.ntp.org
server 3.ubuntu.pool.ntp.org

You can comment them out, delete, keep or replace the lines. The lines are specifying multiple servers to act as a timeserver, which is helpful when one of the timeservers fail. You can use regional pool ntp severs from ntp.org’s Regional Pools. In my example, as I live in the UK, I’ve used the regional pool of servers closest to the UK

server 0.uk.pool.ntp.org iburst dynamic
server 1.uk.pool.ntp.org iburst dynamic
server 2.uk.pool.ntp.org iburst dynamic
server 3.uk.pool.ntp.org iburst dynamic

The sytax iburst and dynamic are optional commands but can be useful to have set, depending on your environment.

  • iburst: After every poll a burst of eight packets is sent instead of one. When the server is not responding, packets are sent at 16 seconds intervals. When the server responds, packets are sent every 2 seconds. This means that after reboot or restart ntp synchronizations are established quicker.
  • dynamic: This option tells NTP it can try a configured server again later if it’s unavailable at some point, which can be useful when the server doesn’t always have Internet connectivity.
You can see my full example ntp.conf file here

Having saved and close the updated ntp.conf file, we’ll need to restart the daemon running service ntp restart

[email protected]:~$ sudo service ntp restart
 * Stopping NTP server ntpd                 [ OK ] 
 * Starting NTP server ntpd                 [ OK ]

After restarting the daemon, the server will take around 10-15 minutes for NTP to synchronize with the timeservers and it will automatically set the system clock. By using the command ntpq -p we’ll be able to check the status of the NTP servers that we are synchronized with

[email protected]:~$  ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
 time.rdg.uk.as4    2 u   21   64    3    3.138    0.047   0.506
 resntp-a-vip.lo     3 u   22   64    3    1.723    2.038   0.526
 2a03:b0c0:1:d0:      3 u   19   64    3    2.870    1.632   0.337
 neon.trippett.o    2 u   26   64    3    2.928    1.863   0.473
 golem.canonical   2 u   24   64    3    9.211    3.418   0.387

The table below explains the different parameters from the ntpq -p output:

Parameters Function
Remote Specifics the hostname of the timeserver
Refid This is a 32-bit code identifying the particular reference clock.
St (Stratus) This indicates your physical GPS closeness to the timeserver. Anything under 3 is seen as good
When Number of Seconds passed since the last poll or time check
Poll This is the minimum interval between transmitted messages, in seconds as a power of two. For instance, a value of six indicates a minimum interval of 64 seconds.
Reach How well a clock can maintain a constant frequency.
Delay Provides the capability to launch a message to arrive at the reference clock at a specified time. Relative to a selected reference clock.
Offset The time difference between two clocks, relative to a selected reference clock. Represents the amount to adjust the local clock to bring it into correspondence with the reference clock.
Jitter Short-term variations in Frequency with components greater than 10 Hz. The estimated time error of the system clock measured as an exponential average of RMS time differences.

You will be able start, stop, restart and/or check ntp status by using these commands

service ntp status
service ntp start
service ntp stop
service ntp restart

And with that we have a NTP server configured!

Enabling NTP Client

For testing, I configured a Juniper SRX220 to be the NTP client. It’s quite straightforward to enable ntp on a SRX; you’ll need to set and commit the commands to below and with that you will have NTP enabled. Simple Right! 🙂

set system ntp server prefer
set system ntp server version 4

For verification of NTP on the SRX we can run show ntp associations, show ntp status and show system uptime

show ntp associationsshow system uptimeshow ntp status
[email protected]> show ntp associations no-resolve 
     remote           refid      st t when poll reach   delay   offset  marquk01
*     3 -    8   64    1    1.849    2.498   0.160
[email protected]> show system uptime 
Current time: 2016-01-11 10:15:27 UTC
System booted: 2016-01-08 10:02:36 UTC (3d 00:12 ago)
Protocols started: 2016-01-08 10:05:13 UTC (3d 00:10 ago)
Last configured: 2016-01-11 10:13:34 UTC (00:01:53 ago) by marquk01
10:15AM  up 3 days, 13 mins, 2 users, load averages: 0.05, 0.11, 0.04
[email protected]> show ntp status                     
status=0664 leap_none, sync_ntp, 6 events, event_peer/strat_chg,
version="ntpd 4.2.0-a Fri Nov 13 15:40:48 UTC 2015 (1)",
processor="octeon", system="JUNOS12.1X47-D30.4", leap=00, stratum=4,
precision=-17, rootdelay=13.781, rootdispersion=2.340, peer=31708,
reftime=da3dff68.c47f84ec  Mon, Jan 11 2016 10:16:08.767, poll=6,
clock=da3dff6b.8ee12a6f  Mon, Jan 11 2016 10:16:11.558, state=3,
offset=0.000, frequency=0.000, jitter=0.213, stability=0.000

And on the Ubuntu host, it’s exactly the same as I described above, but in the /etc/ntp.conf file you’ll need to set the server as your local NTP server

# Use servers from the NTP Pool Project. Approved by Ubuntu Technical Board
# on 2011-02-08 (LP: #104525). See http://www.pool.ntp.org/join.html for
# more information.
#server 0.ubuntu.pool.ntp.org
#server 1.ubuntu.pool.ntp.org
#server 2.ubuntu.pool.ntp.org
#server 3.ubuntu.pool.ntp.org

server prefer iburst dynamic

We can then run ntpq -p to check the ntp server is the local server!

[email protected]:~$ ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
*  3 u   28   64    1    0.454    0.380   0.315

For more in-depth detailed information on how to use NTP pools see ntp.org and the Ubuntu Man page for more detail on ntp.conf file.

Share this:

Useful tcpdump Commands

Tcpdump is a network debugging tool that runs under the command line. It allows the user to intercept and display TCP/UDP/IP and other packets being transmitted or received over a network to which the computer is attached. Running tcpdump by it’s self will begin recording traffic that is seen on the wire printing the output to the screen.

I found this list by @r_paranoid on their website Rationally Paranoid. Very Very useful set of tcpdump commands that can assist with troubleshooting and/or when a packet capture is needed.

See the list of interfaces on which tcpdump can listen:

tcpdump -D

Listen on interface eth0:

tcpdump -i eth0

Listen on any available interface (cannot be done in promiscuous mode. Requires Linux kernel 2.2 or greater):

tcpdump -i any

Be verbose while capturing packets:

tcpdump -v

Be more verbose while capturing packets:

tcpdump -vv

Be very verbose while capturing packets:

tcpdump -vvv

Be verbose and print the data of each packet in both hex and ASCII, excluding the link level header:

tcpdump -v -X

Be verbose and print the data of each packet in both hex and ASCII, also including the link level header:

tcpdump -v -XX

Be less verbose (than the default) while capturing packets:

tcpdump -q

Limit the capture to 100 packets:

tcpdump -c 100

Record the packet capture to a file called capture.cap:

tcpdump -w capture.cap

Record the packet capture to a file called capture.cap but display on-screen how many packets have been captured in real-time:

tcpdump -v -w capture.cap

Display the packets of a file called capture.cap:

tcpdump -r capture.cap

Display the packets using maximum detail of a file called capture.cap:

tcpdump -vvv -r capture.cap

Display IP addresses and port numbers instead of domain and service names when capturing packets (note: on some systems you need to specify -nn to display port numbers):

tcpdump -n

Capture any packets where the destination host is Display IP addresses and port numbers:

tcpdump -n dst host

Capture any packets where the source host is Display IP addresses and port numbers:

tcpdump -n src host

Capture any packets where the source or destination host is Display IP addresses and port numbers:

tcpdump -n host

Capture any packets where the destination network is Display IP addresses and port numbers:

tcpdump -n dst net

Capture any packets where the source network is Display IP addresses and port numbers:

tcpdump -n src net

Capture any packets where the source or destination network is Display IP addresses and port numbers:

tcpdump -n net

Capture any packets where the destination port is 23. Display IP addresses and port numbers:

tcpdump -n dst port 23

Capture any packets where the destination port is is between 1 and 1023 inclusive. Display IP addresses and port numbers:

tcpdump -n dst portrange 1-1023

Capture only TCP packets where the destination port is is between 1 and 1023 inclusive. Display IP addresses and port numbers:

tcpdump -n tcp dst portrange 1-1023

Capture only UDP packets where the destination port is is between 1 and 1023 inclusive. Display IP addresses and port numbers:

tcpdump -n udp dst portrange 1-1023

Capture any packets with destination IP and destination port 23. Display IP addresses and port numbers:

tcpdump -n "dst host and dst port 23"

Capture any packets with destination IP and destination port 80 or 443. Display IP addresses and port numbers:

tcpdump -n "dst host and (dst port 80 or dst port 443)"

Capture any ICMP packets:

tcpdump -v icmp

Capture any ARP packets:

tcpdump -v arp

Capture either ICMP or ARP packets:

tcpdump -v "icmp or arp"

Capture any packets that are broadcast or multicast:

tcpdump -n "broadcast or multicast"

Capture 500 bytes of data for each packet rather than the default of 68 bytes:

tcpdump -s 500

Capture all bytes of data within the packet:

tcpdump -s 0

Additionally cyberciti.biz has a great man page on tcpdump commands

Share this:

IPv6 and Junos – Stateless Address Autoconfiguration (SLAAC)

From my research and testing, I’ve notice there are a few ways you can set IPv6 addresses to hosts. Essentially you have 3 methods; manually setting a Static IP address, Using Stateful Dynamic Address allocation via a DHCPv6 server, or by using Stateless Dynamic Address allocation. The first two methods are pretty standard as addressing with IPv4 is done this way however, the last method is new method that comes with IPv6 and this is actually known as Stateless Address Autoconfiguration (SLAAC). SLAAC, as its name suggestions, allows a host to auto configure itself without any manual intervention.

RFC4862 describe the SLAAC as

The IPv6 stateless autoconfiguration mechanism requires no manual configuration of hosts, minimal (if any) configuration of routers, and no additional servers. The stateless mechanism allows a host to generate its own addresses using a combination of locally available information and information advertised by routers. Routers advertise prefixes that identify the subnet(s) associated with a link, while hosts generate an “interface identifier” that uniquely identifies an interface on a subnet. An address is formed by combining the two. In the absence of routers, a host can only generate link-local addresses. However, link-local addresses are sufficient for allowing communication among nodes attached to the same link.

In essence, when using SLAAC to get the full 128-bit IPv6 address, it uses the 64-bit prefix that is advertised by the host or router for the first half, then in conjunction with the EUI-64 process, is able to allocation the second 64-bit of the address.

The EUI-64 process in a nutshell, is the method of extending the 48-bit MAC Address and making it into a 64-bit value. This is done by splitting the 48-bit address into two 24-bit halves and adding the 16-bit hex value 0xFFFE in middle to create the last 64-bits

Configuring SLAAC

Enabling SLAAC with Junos is pretty straightforward. For my example, I’ve got an EX4200 connected to an Ubuntu 14.04LTS ESXi host in Vlan 200.

Before enabling the switch, the host’s interface has to be set to auto

[email protected]:~$ cat /etc/network/interfaces
# This is an autoconfigured IPv6 interface
iface eth0 inet6 auto

auto eth1
iface eth1 inet6 auto

Once that’s done, to make sure no address was learnt as I configured the switch, the interface was disabled using ifdown.

With the switch configuration, under the protocol router-advertisement stanza, the interface and the prefix (first 64-bits) that will be advertised need to be set. Additionally I enabled a traceoption to see the process from the switch’s perspective.

Interface ConfigurationEnabling SLAAC
[email protected]# show interfaces vlan unit 200 
family inet6 {
    address 2001:192:168:2::1/64;
{master:0}[edit protocols router-advertisement]
[email protected]# show 
traceoptions {
    file RA.log;
    flag all;
interface vlan.200 {
    prefix 2001:192:168:2::/64;


With that SLAAC has been enabled, simple isn’t it 🙂

Now, back on the host, I re-enabled the interface using ifup. By using ifconfig we can see that the IPv6 address has been auto configured onto the host.

[email protected]:~$ ifconfig -a eth1
eth1      Link encap:Ethernet  HWaddr 00:0c:29:4f:26:c5  
          inet addr:  Bcast:  Mask:
          inet6 addr: 2001:192:168:2:20c:29ff:fe4f:26c5/64 Scope:Global
          inet6 addr: fe80::20c:29ff:fe4f:26c5/64 Scope:Link
          RX packets:4 errors:0 dropped:0 overruns:0 frame:0
          TX packets:40 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:563 (563.0 B)  TX bytes:2334 (2.3 KB)

By looking closer at the ifconfig output, we can see how the EUI-64 process has been used to allocate the IPv6 address, as well as its link-local address:

eth1      Link encap:Ethernet  HWaddr 00:0c:29:4f:26:c5  
          inet6 addr: 2001:192:168:2:20c:29ff:fe4f:26c5/64 Scope:Global
          inet6 addr: fe80::20c:29ff:fe4f:26c5/64 Scope:Link

On the switch, by running the commands: show ipv6 neighbours, we can see the hosts’ link-local and SLAAC allocated addresses, both discovered by the Neighbour Discovery Protocol (NDP). And show ipv6 router-advertisement, which shows how many RA’s and RS’ have been sent and received by the switch.

IPv6 NeighborsRouter Advertisements
[email protected]> show ipv6 neighbors 
IPv6 Address                 Linklayer Address  State       Exp Rtr Secure Interface
                             00:0c:29:4f:26:c5  stale       1110 no no      vlan.200    
fe80::20c:29ff:fe4f:26c5     00:0c:29:4f:26:c5  stale       1039 no no      vlan.200
[email protected]> show ipv6 router-advertisement 
Interface: vlan.200
  Advertisements sent: 4, last sent 00:04:45 ago
  Solicits received: 2, last received 00:04:46 ago
  Advertisements received: 0

When we look further at the traceoption, we can see the request from the host sent out Router Solicitation (RS) via its link-local address, to the destination of ff02::2 for the presence of routers (in this case a switch) on the link. The switch replies by sending a Router Advertisement (RA) to ff02::1 with the Router’s presence and link prefixes, MTU, and hop limits.

{Apr  7 06:29:13.002388 background dispatch running job ipv6_ra_delete_interface_config_job for task Router-Advertisement
Apr  7 06:29:13.002436 task_job_delete: delete background job ipv6_ra_delete_interface_config_job for task Router-Advertisement
Apr  7 06:29:13.002473 background dispatch completed job ipv6_ra_delete_interface_config_job for task Router-Advertisement
Apr  7 06:29:48.645889 ipv6_ra_receive_solicit: received solicit from fe80::20c:29ff:fe4f:26c5
Apr  7 06:29:48.646013 ipv6_ra_receive_solicit: task Router-Advertisement src fe80::20c:29ff:fe4f:26c5 dst ff02::2 hdr 0x26fc000 count 16 intf 0x283c0e8
Apr  7 06:29:48.646086 task_timer_reset: reset Router-Advertisement_ipv6ra
Apr  7 06:29:48.646137 task_timer_set_oneshot_latest: timer Router-Advertisement_ipv6ra interval set to 0.426219
Apr  7 06:29:49.073743 task_job_create_foreground: create job ipv6 ra for task Router-Advertisement
Apr  7 06:29:49.073857 foreground dispatch running job ipv6 ra for task Router-Advertisement
Apr  7 06:29:49.073978 ipv6_ra_send_advertisement: sending advertisement for ifl 73 to ff02::1
Apr  7 06:29:49.074018 (519322) sending advertisement for ifl 73
Apr  7 06:29:49.074106 	ifa 0x28383f0 2001:192:168:2::1/64
Apr  7 06:29:49.074942 	--> sent 56 bytes
The ff02::1 and ff02::2 addresses are well-known IPv6 Multicast addresses that a host sends out to a RS, to all devices within the all-host multicast group for ff02::2, and for a router, the address ff02::1 is used to reply RS with RA. Although this process could be compared to the IPv4 broadcast address, its important to remember that broadcasts are not accepted by any IPv6 protocol.

SLAAC is a really useful way of easily enabling IPv6 across your network and let the host and devices auto configure themselves. In addition, as the EUI-64 process is key to SLAAC, as long as you keep a record of the MAC Addresses of each device, you’ll always be able to know what address goes with what device. Of course, there will be situations where Static or DHCP addressing will be more suitable however; if you need to quickly enable your network with IPv6 then SLAAC is the way to go!

Share this:

Configuring BGP using Bird on Ubuntu 14.04LTS

As part of the QFX testing I’ve been doing at work, I’ve had to do the testing of running BGP between a switch and server. Although one of my seniors advised I could just test BGP between two switches, as BGP is BGP, and should work whether it’s a switch or server, the protocol is the same and should simply work. However, given the chance to learn something new, I went with it and thought this would be the perfect chance for a new post! I found out that our production servers use EXaBGP daemon. I looked into the configuration and the specs for EXaBGP…. Let just say was pretty lost very quickly (being polite)! I then started looking into alternative daemons and found BIRD. I had heard of BIRD before and from my research it didn’t look as complex as EXaBGP.

The BIRD project was developed as a school project at the Faculty of Mathematics and Physics at Charles University in Prague, with major contributions from developers Martin Mares, Pavel Machek, Ondrej Zajicek, Libor Forst and Ondrej Filip. Designed for a UNIX based system, BIRD is an open source daemon that runs an Internet protocol suite. It can run a number of Dynamic Routing Protocols: BGP, OSPF, RIP, Static Routing, Both IPv4 and IPv6 and can hold Multiple Routing Tables.

I had found a perfect post from mindless.gr that went into detail on how to configure a simple IPv4/IPv6 BGP session using BIRD, which was exactly what I needed.

With that in mind, this post will detail how to configure a simple IPv4 BGP session using BIRD on Ubuntu 14.04LTS

Let’s get Cracking 😛

You will need sudo and root privileges

You will be able to make the changes here with sudo privileges. You need to install the BIRD package, which is nicely available via Ubuntu’s Advanced Packaging Tool apt-get install bird

[email protected]:~$ apt-get install bird6

By default any modern Linux distribution will have IP Forwarding disabled; we’ll need the server to basically act as a router and we’ll need to have IP Forwarding enabled. Running the command sysctl net.ipv4.ip_forward=1 will enable IPv4 forwarding. You can also make this a permanent change so that on boot, IP forwarding will always been enabled. You will need to edit /etc/sysctl.conf file. Check below for what you need to look out for and uncomment:

[email protected]:~$ cat /etc/sysctl.conf
# Uncomment the next line to enable packet forwarding for IPv4

# Uncomment the next line to enable packet forwarding for IPv6
#  Enabling this option disables Stateless Address Autoconfiguration
#  based on Router Advertisements for this host

Backup the original bird.conf by running something like cp bird.conf bird.old.conf (always need to cover your ass :p lol)

The config file looks quite complex at first appearance (when this was written I didn’t have a clue about any of it!!). If you want more detailed information about the config file and the different options available you can find them on the Bird Internet Routing Daemon: User’s Guide Page

For my example, I needed a simple configuration that had the server advertise 4 routes (3 x /24 and /22) and accept all routes. This was the same setup on the switch side, which is a Juniper QFX5100.

To edit the bird.conf file, you’ll need it to be root. I tried a sudo nano however I got Permission Denied! So I sudo -s down to root and edited the conf file

[email protected]:~$ sudo -s
[sudo] password for marquk01: 
[email protected]:~# nano /etc/bird/bird.conf
Bird.confSwitch Configuration
[email protected]:~$ sudo cat /etc/bird/bird.conf
[sudo] password for marquk01: 
 *	This is an example configuration file.

# Yes, even shell-like comments work...

# Configure logging
log syslog all;

# Override router ID
router id;

# This pseudo-protocol performs synchronization between BIRD's routing
# tables and the kernel. If your kernel supports multiple routing tables
# (as Linux 2.2.x does), you can run multiple instances of the kernel
# protocol and synchronize different kernel tables with different BIRD tables.
protocol kernel {
#	learn;			# Learn all alien routes from the kernel
	persist;		# Don't remove routes on bird shutdown
	scan time 20;		# Scan kernel routing table every 20 seconds
#	import none;		# Default is import all
	export all;		# Default is export none
#	kernel table 5;		# Kernel table to synchronize with (default: main)

# This pseudo-protocol watches all interface up/down events.
protocol device {
	scan time 10;		# Scan interfaces every 10 seconds

# Static routes (again, there can be multiple instances, so that you
# can disable/enable various groups of static routes on the fly).
protocol static static_bgp {
	route via;
	route via;
	route via;
	route via;
	route via;

#BGP Configuration
protocol bgp {
        import all;
        export where proto = "static_bgp";

        local as 3000;
        neighbor as 4000;
set interfaces xe-0/0/4 description "km-vm3 10GB"
set interfaces xe-0/0/4 enable
set interfaces xe-0/0/4 unit 0 family inet address
set routing-options static route reject
set routing-options static route reject
set routing-options static route reject
set routing-options static route reject
set routing-options autonomous-system 4000
set protocols bgp enable
set protocols bgp local-as 4000
set protocols bgp group test local-address
set protocols bgp group test family inet unicast
set protocols bgp group test neighbor export BGP-Export
set protocols bgp group test neighbor peer-as 3000
set policy-options policy-statement BGP-Export from protocol static
set policy-options policy-statement BGP-Export then accept

Having configured the switch and the server, I needed to enable to the bird daemon. This was done by running the command invoke-rc.d bird start

[email protected]:~$ invoke-rc.d bird start

To enter the bird client, you will need to run the command birdc and from there you’re able to run a verification command to check that routes are being advertised and received from server to the switch.

[email protected]:~$ sudo birdc
[sudo] password for marquk01: 
BIRD 1.4.0 ready.

From the bird client, you can run show route to see the RIB table and to check the BGP status you will run show protocols all bgp1

show routeshow protocols all bgp1
bird> show route      via on eth1 [bgp1 11:35:14] * (100) [AS4000i]      via on eth1 [bgp1 11:35:14] * (100) [AS4000i]      via on eth1 [bgp1 11:35:14] * (100) [AS4000i]      via on eth1 [bgp1 11:35:14] * (100) [AS4000i]      via on eth1 [static_bgp 13:50:05] ! (200)      via on eth1 [static_bgp 11:35:09] ! (200)      via on eth1 [static_bgp 11:35:09] ! (200)      via on eth1 [static_bgp 11:35:09] ! (200)
bird> show protocols all bgp1
name     proto    table    state  since       info
bgp1     BGP      master   up     11:35:14    Established   
  Preference:     100
  Input filter:   ACCEPT
  Output filter:  (unnamed)
  Routes:         4 imported, 4 exported, 4 preferred
  Route change stats:     received   rejected   filtered    ignored   accepted
    Import updates:              4          0          0          0          4
    Import withdraws:            0          0        ---          0          0
    Export updates:              9          4          0        ---          5
    Export withdraws:            0        ---        ---        ---          0
  BGP state:          Established
    Neighbor address:
    Neighbor AS:      4000
    Neighbor ID:
    Neighbor caps:    refresh AS4
    Session:          external AS4
    Source address:
    Hold timer:       52/90
    Keepalive timer:  18/30

On the switch, we can check when the BGP session is up and can see what routes that are being adverted and what routes are being received:

show bgp summaryshow route advertising-protocol bgpshow route receive-protocol bgp
[email protected]> show bgp summary group test    
Groups: 1 Peers: 1 Down peers: 0
Table          Tot Paths  Act Paths Suppressed    History Damp State    Pending
                       4          4          0          0          0          0
Peer                     AS      InPkt     OutPkt    OutQ   Flaps Last Up/Dwn State|#Active/Received/Accepted/Damped...             3000         79         79       0       1       33:43 4/4/4/0              0/0/0/0
[email protected]> show route advertising-protocol bgp

inet.0: 13 destinations, 13 routes (13 active, 0 holddown, 0 hidden)
  Prefix                  Nexthop              MED     Lclpref    AS path
*           Self                                    I
*           Self                                    I
*           Self                                    I
*           Self                                    I
[email protected]> show route receive-protocol bgp                                                          

inet.0: 13 destinations, 13 routes (13 active, 0 holddown, 0 hidden)
  Prefix                  Nexthop              MED     Lclpref    AS path
*                               3000 I
*                               3000 I
*                               3000 I
*                               3000 I

You can enable BIRD for IPv6 as well. The editing and process is exactly the same however you’ll need to edit the /etc/bird/bird6.conf file with the appropriate IPv6 addressing. To enter the IPv6 BIRD client you’ll use the command birdc6.

Being able to spin up VMs and have them configured as “dumb” BGP nodes is such a useful thing to have in a lab when you don’t have as many switches/routers as you need. From what I can see Bird can be a extremely useful tool for connecting BGP routes and I see that many Internet Exchange Points (IXPs) such as London Internet Exchange (LINX), London Network Access Point (LONAP), Deutscher Commercial Internet Exchange (DE-CIX), Amsterdam Internet Exchange (AMS-IX) and many more use BIRD for their Route Server. When I get a chance I will defiantly look into how to get the most out of BIRD!

You can find all the documentation and user guides on BIRD on the official website here

Share this: