Tuesday, February 26, 2019

Using ansible to write directly to postgresql

Lately I've been playing with ansible to create an inventory for network equipment. Actually I want to maintain an inventory and keep it updated.

The concept is to connect to a network device, "get facts" and write the results directly to a database. In this case I've been using postgresql primarily for its "inet" variable type.

Anyway, this is how I did it. I used the shell option in an Ansible task and passed data from "facts" directly to psql command.


- name: Writing facts to database
shell: "psql -U george -d inventory -c 'UPDATE device SET (osversion,osimage,model,hostname,serialnum) = ($${{ansible_net_version}}$$,$${{ ansible_net_image.split('/')[-1] }}$$,$${{ ansible_net_model }}$$,$${{ ansible_net_hostname }}$$,$${{ansible_net_serialnum}}$$) WHERE ipaddress = $${{ inventory_hostname }}$$'"


The best way to make it work seems to be by using "$$" around variables

Monday, August 21, 2017

EVE-NG - A GNS3 alternative for your network simulations

A few months ago I had been searching for GNS3 alternatives. Although GNS3 has helped me a lot the last few years, I needed another, more flexible tool, to run my network simulations. After quite a bit of testing, I decided to abandon GNS3 for EVE-NG.



Actually EVE-NG is the new generation of an older tool, which you may have heard of, known as UnetLab. I had tried UnetLab once in the past, but my experience wasn't that good, so I continued with GNS3. But now things have changed..

The major advantage of EVE-NG against GNS3 is that EVE-NG doesn't need client application to be running on your computer. You can install EVE-NG on a remote server and you'll be able to access it from anywhere, just using your browser. Of course you can still install it on your laptop or desktop computer without any issue.

It's a very powerful platform which supports many different vendor appliances, which, in my opinion, certainly deserves your time to give it a try.

Wednesday, June 1, 2016

BGP Best Path Selection Mnemonic

From Wendell Odom’s CCNP ROUTE 642-902 Official Certification Guide:

Hint:
* Up to AS Path higher values win
* After AS Path lower values win


N WLLA OMNI

N = next hop reachability
W = weight
L = local preference
L = locally injected in the BGP process
A = AS path length

O = origin (igp < egp < incomplete)
M = MED
N = neighbor type (ebgp < ibgp)
I = IGP metric to BGP next-hop

And my own contribution to this list:

ORCA

O = Oldest route wins
R = Router-ID, lowest wins
C = Cluster list, shortest wins
A = Address of the BGP neighbor, lowest wins

Of course there are several options that can affect the order of the above process.
For details check on Cisco: BGP Best Path Selection Algorithm


Sunday, February 28, 2016

Order of operations using NAT - Why do we need a static route when using Outside NAT?

After reading several docs online and trying to understand the reason we need a static route, I decided to lab it to better understand and verify the result.

My lab environment runs on GNS3 and I noticed a behavior that wasn't mentioned anywhere else, so I decided to post my findings here

We have the following topology.



No routing protocols running between the routers. We need to ping R3 router from R2 and the opposite, only by using NAT on R1.

Initial Configurations
R2
interface Ethernet0/0
 ip address 20.0.0.2 255.255.255.0
 
R3
interface Ethernet1/1
 ip address 30.0.0.3 255.255.255.0

R1
interface Ethernet0/0
 ip address 20.0.0.1 255.255.255.0
 ip nat inside

interface Ethernet1/1
 ip address 30.0.0.1 255.255.255.0
 ip nat outside
 ip nat inside source static 20.0.0.2 30.0.0.2
 ip nat outside source static 30.0.0.3 20.0.0.3
R1#sh ip nat tran

Pro Inside global      Inside local       Outside local      Outside global

--- ---                ---                20.0.0.3           30.0.0.3

--- 30.0.0.2           20.0.0.2           ---                ---

We start by pinging R3 from R2, so R1 performs Inside to Outside NAT translation. As we expected, ping is successful and correct addresses are displayed in the console of each router

R2#ping 30.0.0.3 rep 1
Type escape sequence to abort.
Sending 1, 100-byte ICMP Echos to 30.0.0.3, timeout is 2 seconds:
!
Success rate is 100 percent (1/1), round-trip min/avg/max = 6/6/6 ms
R2#
R3#
*Feb 28 14:39:58.928: ICMP: echo reply sent, src 30.0.0.3, dst 30.0.0.2, topology BASE, dscp 0 topoid 0
R3#
R2#
*Feb 28 14:39:58.931: ICMP: echo reply rcvd, src 30.0.0.3, dst 20.0.0.2, topology BASE, dscp 0 topoid 0
R2#

Now let's try the opposite. We ping R2 from R3, so R1 performs Outside to Inside NAT translation.

R3#ping 20.0.0.2 rep 1
Type escape sequence to abort.
Sending 1, 100-byte ICMP Echos to 20.0.0.2, timeout is 2 seconds:
.
Success rate is 0 percent (0/1)
R2#
*Feb 28 14:40:34.232: ICMP: echo reply sent, src 20.0.0.2, dst 20.0.0.3, topology BASE, dscp 0 topoid 0
R2#

We see that ping fails, although the packet can reach R2. That means there must me an error in the return path. We enable "debug ip nat" and "debug ip packet" on R1 and retry pinging R2 from R3, trying to find the cause of the failure.

R1#
*Feb 28 14:46:40.686: IP: s=30.0.0.3 (Ethernet1/1), d=20.0.0.2, len 100, input feature, Virtual Fragment Reassembly(33), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 14:46:40.686: IP: s=30.0.0.3 (Ethernet1/1), d=20.0.0.2, len 100, input feature, Virtual Fragment Reassembly After IPSec Decryption(49), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 14:46:40.686: IP: s=30.0.0.3 (Ethernet1/1), d=20.0.0.2, len 100, input feature, NAT Outside(76), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 14:46:40.686: IP: s=30.0.0.3 (Ethernet1/1), d=20.0.0.2, len 100, input feature, MCI Check(90), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 14:46:40.687: NAT: s=30.0.0.3->20.0.0.3, d=20.0.0.2 [24]
*Feb 28 14:46:40.687: IP: s=20.0.0.3 (Ethernet1/1), d=20.0.0.2 (Ethernet0/0), len 100, output feature, NAT Inside(8), rtype 1, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 14:46:40.687: IP: s=20.0.0.3 (Ethernet1/1), d=20.0.0.2 (Ethernet0/0), len 100, output feature, NAT ALG proxy(59), rtype 1, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 14:46:40.687: IP: s=20.0.0.3 (Ethernet1/1), d=20.0.0.2 (Ethernet0/0), g=20.0.0.2, len 100, forward
*Feb 28 14:46:40.688: IP: s=20.0.0.3 (Ethernet1/1), d=20.0.0.2 (Ethernet0/0), len 100, sending full packet
*Feb 28 14:46:40.692: IP: s=20.0.0.2 (Ethernet0/0), d=20.0.0.3, len 100, input feature, Virtual Fragment Reassembly(33), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 14:46:40.692: IP: s=20.0.0.2 (Ethernet0/0), d=20.0.0.3, len 100, input feature, Virtual Fragment Reassembly After IPSec Decryption(49), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 14:46:40.692: IP: s=20.0.0.2 (Ethernet0/0), d=20.0.0.3, len 100, input feature, MCI Check(90), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 14:46:40.692: IP: tableid=0, s=20.0.0.2 (Ethernet0/0), d=20.0.0.3 (Ethernet0/0), routed via RIB
*Feb 28 14:46:40.692: IP: s=20.0.0.2 (Ethernet0/0), d=20.0.0.3 (Ethernet0/0), len 100, output feature, NAT Inside(8), rtype 1, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 14:46:40.693: IP: s=20.0.0.2 (Ethernet0/0), d=20.0.0.3 (Ethernet0/0), len 100, rcvd 3
*Feb 28 14:46:40.693: IP: s=20.0.0.2 (Ethernet0/0), d=20.0.0.3, len 100, stop process pak for forus packet
R1#

If we check the debugs carefully, we notice that there is only one line mentioning NAT. We see NAT info only in line #5. It triggers only in the direction from R3 to R2 and there is no trigger in the return direction. That leads us to research for the reason. Looking toward the bottom of the debug output we notice line #13

*Feb 28 14:46:40.692: IP: tableid=0, s=20.0.0.2 (Ethernet0/0), d=20.0.0.3 (Ethernet0/0), routed via RIB

We see that R1 believes 20.0.0.2 and 20.0.0.3 are on the same interface/segment, so there is no reason to perform any NAT action

And what is the solution? As mentioned in several blogs and docs, it is a matter of order of operations and you can solve it by adding a static route for 20.0.0.3 pointing toward R3 and R1. There are two possible ways to add that static route. Of course you can add the static route yourself, or you can use the "add-route" knob in the "ip nat outside" command. Any of these should have the same result.

So, let's pick the "add-route" option and see what happens
R1# conf t
R1(config)# ip nat outside source static 30.0.0.3 20.0.0.3 add-route
R1(config)# do sh ip route | b Gateway
Gateway of last resort is not set

      20.0.0.0/8 is variably subnetted, 3 subnets, 2 masks
C        20.0.0.0/24 is directly connected, Ethernet0/0
L        20.0.0.1/32 is directly connected, Ethernet0/0
L        20.0.0.3/32 is directly connected, Ethernet0/0   <========
      30.0.0.0/8 is variably subnetted, 3 subnets, 2 masks
C        30.0.0.0/24 is directly connected, Ethernet1/1
L        30.0.0.1/32 is directly connected, Ethernet1/1
L        30.0.0.2/32 is directly connected, Ethernet1/1
As you can see above there is no static route for 20.0.0.3. But we notice a connected route, which probably overwhelms our static route. And this is where things are getting different from anything I've read online. I started thinking where could this static route come from and I remembered the alias option of the "ip nat inside/outside" command. Whenever you perform NAT, the device by default installs aliases for the involved IP addresses and you can verify that with the command "sh ip alias"
R1#sh ip alias
Address Type             IP Address      Port
Interface                20.0.0.1
Dynamic                  20.0.0.3   <========
Interface                30.0.0.1
Dynamic                  30.0.0.2   <========
So, why not use the "no-alias" knob to see what happens? We modify out NAT statements on R1 to include the "no-alias" option and check the result.
R1# conf t
R1(config)# ip nat inside source static 20.0.0.2 30.0.0.2 no-alias
R1(config)# ip nat outside source static 30.0.0.3 20.0.0.3 no-alias add-route

R1(config)# do sh ip alias
Address Type             IP Address      Port
Interface                20.0.0.1
Interface                30.0.0.1

R1(config)# do sh ip route | b Gateway
Gateway of last resort is not set

      20.0.0.0/8 is variably subnetted, 3 subnets, 2 masks
C        20.0.0.0/24 is directly connected, Ethernet0/0
L        20.0.0.1/32 is directly connected, Ethernet0/0
S        20.0.0.3/32 [1/0] via 30.0.0.3
      30.0.0.0/8 is variably subnetted, 2 subnets, 2 masks
C        30.0.0.0/24 is directly connected, Ethernet1/1
L        30.0.0.1/32 is directly connected, Ethernet1/1
Now our routing table seems ok, so let's retry pinging R2 from R3
R3#ping 20.0.0.2 rep 1
Type escape sequence to abort.
Sending 1, 100-byte ICMP Echos to 20.0.0.2, timeout is 2 seconds:
!
Success rate is 100 percent (1/1), round-trip min/avg/max = 7/7/7 ms
R2#
*Feb 28 15:19:09.776: ICMP: echo reply sent, src 20.0.0.2, dst 20.0.0.3, topology BASE, dscp 0 topoid 0
R3#
*Feb 28 15:19:09.778: ICMP: echo reply rcvd, src 20.0.0.2, dst 30.0.0.3, topology BASE, dscp 0 topoid 0
As you can see, the ping is successful and the debug output depicts the NAT operation in both directions.
R1#
*Feb 28 15:19:09.772: IP: s=30.0.0.3 (Ethernet1/1), d=20.0.0.2, len 100, input feature, Virtual Fragment Reassembly(33), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 15:19:09.772: IP: s=30.0.0.3 (Ethernet1/1), d=20.0.0.2, len 100, input feature, Virtual Fragment Reassembly After IPSec Decryption(49), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 15:19:09.772: IP: s=30.0.0.3 (Ethernet1/1), d=20.0.0.2, len 100, input feature, NAT Outside(76), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 15:19:09.773: IP: s=30.0.0.3 (Ethernet1/1), d=20.0.0.2, len 100, input feature, MCI Check(90), rtype 0, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 15:19:09.773: NAT: s=30.0.0.3->20.0.0.3, d=20.0.0.2 [39]
*Feb 28 15:19:09.773: IP: s=20.0.0.3 (Ethernet1/1), d=20.0.0.2 (Ethernet0/0), len 100, output feature, NAT Inside(8), rtype 1, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 15:19:09.773: IP: s=20.0.0.3 (Ethernet1/1), d=20.0.0.2 (Ethernet0/0), len 100, output feature, NAT ALG proxy(59), rtype 1, forus FALSE, sendself FALSE, mtu 0, fwdchk FALSE
*Feb 28 15:19:09.774: IP: s=20.0.0.3 (Ethernet1/1), d=20.0.0.2 (Ethernet0/0), g=20.0.0.2, len 100, forward
*Feb 28 15:19:09.774: IP: s=20.0.0.3 (Ethernet1/1), d=20.0.0.2 (Ethernet0/0), len 100, sending full packet
*Feb 28 15:19:09.777: NAT*: s=20.0.0.2, d=20.0.0.3->30.0.0.3 [39]
After all this research I'm not sure if all this is normal behavior or it appears only in the IOS release/platform I'm running. If anyone can verify my findings are correct, I'd be more than happy to know..

Saturday, January 23, 2016

Open Telnet links from Chrome/Chromium Linux

Credit for all the following instructions to the author of the post  Open Telnet and SSH links from Chrom/Chromium Linux.
I just copy it here for my own reference.
1. Install putty. You can use any other terminal apps too. Change the Exec in the below desktop file accordingly
apt-get install putty
2. Create a telnet.desktop file on /$HOME/.local/share/applications
vi telnet.desktop
[Desktop Entry]
Version=1.0
Name=Telnet
GenericName=Telnet
Comment=Telnet Client
Exec=/usr/bin/putty %U
TryExec=/usr/bin/putty
Terminal=false
Type=Application
Categories=TerminalEmulator;Network;Telnet;Internet;BBS;
MimeType=x-scheme/telnet
X-KDE-Protocols=telnet
Keywords=Terminal;Emulator;Network;Internet;BBS;Telnet;Client;
3. Register the handler as
xdg-mime default telnet.desktop x-scheme-handler/telnet

Monday, November 16, 2015

Connection between GNS3 VM and another VM running Tacacs+ on VirtualBox

Scenario:

  • Host machine running Ubuntu and VirtualBox
  • VM#1 guest Lubuntu and GNS3 v1.3.7
  • VM#2 guest Ubuntu server and tacacs+
In order to make VM#1 and VM#2 communicate do the following:
  1. Create a new Host-only network by editing VirtualBox preferences
  2. Add a new network adapter on each VM using the Host-only network adapter and select the previously created Host-only network
  3. Change the Promiscuous mode setting to "Allow all" in both VMs
  4. Run GNS3 as an Administrator 
  5. In  GNS3 add a new cloud element and configure it using the ethernet interface pointing to the Host-only adapter
  6. Connect the cloud element to router in GNS3
  7. Configure static IP addresses or use a DHCP server (select respective option in VirtualBox)
  8. "No shut" the respective ports on all devices involved
  9. You should be able to ping from the router toward the tacacs server and the opposite


Notes
  1. Always run GNS3 as Administrator. Otherwise nothing will work.
  2. Don't forget to enable Promiscuous mode. Without it I could receive IPs from the DHCP server, but ping wasn't working.
  3. You can avoid using the Host-only network and use your normal lan interface where your ADSL router is connected. That way your GNS3 VM will be able to connect to the internet.





Friday, November 6, 2015

BGP Notes


  • BGP connection is a TCP connection on port 179
  • Only the TCP server needs to approve the source of the packet it receives. Neighbor update-source is actually required only on one side, as long as correct IP addresses are being used
  • When two routers attempt a BGP connection simultaneously, only one is preserved, the one from the router with the highest BGP router ID
  • You can use the command "debug ip packet detail XXX" where XXX is an ACL matching the src/dst we are interested in
  • iBGP learned routes are not advertised to other iBGP peers
  • iBGP packets have TTL=255 while eBGP packets have TTL=1 by default
  • If you see a message "... Active open failed - no route to peer..." it can be an indication of eBGP multihop missing
  • Cisco eBGP performs the following independently
    1. Neighbor is directly connected on a known subnet
    2. Sends packets with TTL=1
  • In order to form a neighborship between directly connected router using Loopbacks, you can use eBGP multihop, which actually disables #1 from the above. Alternatively you can use "neighbor disable-connected-check" to do the same.
  • eBGP multihop command defaults to TTL=255
  • BGP authentication is implemented through TCP option 19
  • Unique BGP router ID within the BGP domain is required, in order to avoid traffic blackholes. That is due to loop prevention algorithm.