Filtering outbound BGP announcements in Cisco IOS

We previously looked at a sample BGP setup for a Cisco 6500 series router. What if you have multiple BGP peers and want to restrict which prefixes or IP blocks you announce to which peers. Simple. We can use the prefix-list command.

What you announce to each BGP peer will effect the traffic that comes in. So sometimes filtering what you announce can help shape your inbound traffic usage, or it can be used to limit one of your peers to very little traffic so you have a backdoor option during a high load event or DDoS.

Lets look at a sample BGP config:

router bgp 17500
bgp log-neighbor-changes
neighbor 200.10.20.1 remote-as 1000
neighbor 200.10.20.1 ebgp-multihop 5
neighbor 200.10.20.1 update-source GigabitEthernet5/8
neighbor 100.5.10.1 remote-as 2000
neighbor 100.5.10.1 ebgp-multihop 5
neighbor 100.5.10.1 update-source GigabitEthernet4/8
!
address-family ipv4
neighbor 200.10.20.1 activate
neighbor 200.10.20.1 next-hop-self
neighbor 200.10.20.1 send-community
neighbor 200.10.20.1 soft-reconfiguration inbound
neighbor 200.10.20.1 prefix-list PeerA-out out
neighbor 200.10.20.1 filter-list 1 in
neighbor 200.10.20.1 filter-list 15 out
neighbor 100.5.10.1 activate
neighbor 100.5.10.1 next-hop-self
neighbor 100.5.10.1 send-community
neighbor 100.5.10.1 soft-reconfiguration inbound
neighbor 100.5.10.1 prefix-list PeerB-out out
neighbor 100.5.10.1 filter-list 1 in
neighbor 100.5.10.1 filter-list 15 out

My ASN is 17500 and I have two BGP uplinks, one to AS 1000 (we’ll call this Peer A) and one to AS 2000 (we’ll call this Peer B). I am announcing the following prefixes:

190.45.60.0/24
209.88.40.0/24
20.10.180.0/24

As you can see, for each peer, I have included a statement with

    prefix-list “LIST-NAME” out

This statement restricts what my ASN will broadcast OUT to my peers. Lets say I want to BGP announce all three prefixes to Peer A, but I only want to announce 190.45.60.0/24 to Peer B. This is what those respective prefix-list’s will look like:

ip prefix-list PeerA-out seq 1 permit 190.45.60.0/24
ip prefix-list PeerA-out seq 2 permit 209.88.40.0/24
ip prefix-list PeerA-out seq 3 permit 20.10.180.0/22
ip prefix-list PeerA-out seq 100 deny 0.0.0.0/0
ip prefix-list PeerB-out seq 1 permit 190.45.60.0/24
ip prefix-list PeerB-out seq 100 deny 0.0.0.0/0

Thats all there is to it.

How is FreeBSD different then Linux

This article gives a basic overview of the major differences between FreeBSD and Linux with regards to IP networking, application installs, and starting/stopping services. The assumption is the reader has a good basic understanding of Linux to start of with. We will cover three areas: 1) IP networking, 2) package installation, and 3) starting/stopping services both manually and automated.

IP Networking

I have covered IP settings in previous articles pertaining to Centos and Debian. Debian uses the /etc/system/interfaces file, and Centos uses the /etc/sysconfig/networking-scripts/if-eth0 file.

FreeBSD is different. Everything is in /etc/rc.conf – not just IP settings but everything pertaining to the entire system is in /etc/rc.conf. Thats sounds great right? Basically, FreeBSD has /etc/defaults/rc.conf which contains everything for default settings, but whatever it sees in /etc/rc.conf at bootup overrides the default. Here is the sample rc.conf syntax for basic IP settings:

ifconfig_em0="208.50.100.5 netmask 255.255.255.0 up"
defaultrouter="208.50.100.1"

And for IPv6 add the additional lines:

ipv6_enable="YES"
ipv6_network_interfaces="lo0 em0"
ipv6_ifconfig_em0="2610:bf00:50:100::5/64"
ipv6_defaultrouter="2610:bf00:50:100::1"

In this case our network interface is em0 – we know that from bootup or by looking at the output of dmesg command. Name resolution is still controlled by /etc/resolv.conf as it is in Linux. If you want to add IPv4 aliases, the rc.conf syntax is:

ifconfig_em0_alias0=”208.50.100.6 netmask 255.255.255.255″
ifconfig_em0_alias1=”208.50.128.7 netmask 255.255.255.255″
ifconfig_em0_alias2=”208.50.100.8 netmask 255.255.255.255″

Software Package Installation

In Linux, apt-get and yum are the common tools for adding packages. FreeBSD has a completely different way of doing this. There are two main ways to add software packages: 1) the ports repository, or 2) the sysinstall utility.

The ports repository is a large directly/file tree located in /usr/ports – under that directory there are categories, like /usr/ports/databases, and within the category directory you will find the individual packages, like /usr/ports/databases/mysql51-server. The install the package you go into the packages directory (i.e. /usr/ports/databases/mysql51-server) and run “make && make install”. This will download the most recent tarball, applying system specific patches, compile, and then install the package. If the package has configurable options, a TEXT GUI will pop-up asking you to make those optional selections.

Obviously, the ports to work you need to have the most recent /usr/ports or even have it at all. If you did not install it when creating the system, you can always add it later using the sysinstall utility – /usr/sbin/sysinstall.

sysinstall

sysinstall is a TEXT GUI system that allows you to do many things (too many for me to describe), one of those things is adding distributions. If you dont have /usr/ports installed, go into sysinstall, select “Configuration”, then select “Distributions”, then scroll down and select “Ports”. When you continue from there, it will ask where to install from and you can select the FreeBSD FTP servers to install over the network.

While inside the sysinstall utility you may notice that the utility itself can be used to install software packages. From the main screen, select “Configure”, then select “Packages”. You can now browse through the same category tree and select, for example, Databases -> Mysql 5.1 Server. When you continue through the process, you will again be asked from where to install and you can select the FreeBSD FTP servers.

A sysinstall package add is different then a ports add because the package is not compiled, rather, a pre-compiled package is downloaded and installed.

System Services – Starting, Stopping, Automation

Lastly, how do you start and stop services and set services for automatic start at bootup? Again, this is vastly different then Linux methods, but again, its all covered in /etc/rc.conf. First, the actual scripts for starting and stopping services that have been been added via ports or the sysinstall package system will always be located in /usr/local/etc/rc.d – the exception being core OS services which are located in /etc/rc.d – things like nfsserver or sendmail (on FreeBSD sendmail is a core base service).

So if you have installed apache22, starting and stopping is done by:

/usr/local/etc/rc.d/apache22 stop
or
/usr/local/etc/rc.d/apache22 start

What about automation? That is done in rc.conf as follows:

apache22_enable="YES"

99% of the time the name of the script located in /usr/local/etc/rc.d is the syntax for the above _enable statement, but there are cases where it differs. To be sure, open up the init script located in /usr/local/etc/rc.d and look for its “name” directive which is located near the top. The name is the service name. Oddly enough, mysql is a culprit of this. The mysql service name is mysql, but the init script in /usr/local/etc/rc.d is named mysql-server, so if you added mysql-server_enable=”YES” to /etc/rc.conf it would not work, it has to be mysql_enable=”YES”.

TCP/IP Networking in Linux without a GUI

There are a few major Linux distributions these days, Centos/RHES, Ubuntu, and Debian. They all differ slightly in how they natively handle IP configuration.

For starters, lets first understand the universal way to IP config ANY Linux OS (this also applies to BSD Unix and Solaris). This is done with the ifconfig and route command. ifconfig places an IP address on an interface and route places the default gateway in the routing table. When using ifconfig you just need to know the interface name, if you dont know the interface name, simple type the command:

ifconfig -a

This will display all the connected interfaces, so if you have two NICs on your server it may list an eth0 and eth1. For our example, lets assume we are connecting a Cat5 cable to eth0 and we want to configure the following network setup:

IP Address: 200.50.100.5
Netmask: 255.255.255.0
Default Gateway: 200.50.100.1

The IP configuration is handled by the following command:

ifconfig eth0 200.50.100.5 netmask 255.255.255.0 up

To add the default gateway, we use the following command:

route add default gw 200.50.100.1

Obviously, if you reboot the system these settings will be lost. So now lets look at how to manually config the IP settings for bootup. Both Debian and Ubuntu use the same setup, it involves editing the interfaces file. CentOS/RHES is a bit different, we’ll cover that one last.

For Ubuntu/Debian, edit the file /etc/network/interfaces and add the following lines:

auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 200.50.100.5
netmask 255.255.255.0
network 200.50.100.0
broadcast 200.50.100.255
gateway 200.50.100.1

The broadcast and network entries are technically not needed, but you might as well add them. After you save this file, use the ifup command to activate and bring up the eth0 interface:

ifup eth0

Finally, make sure you edit /etc/resolv.conf and add your DNS resolvers, the syntax is as follows:

nameserver 8.8.8.8
nameserver 4.4.4.2

Lets take a look at Centos/RHES and how they configure IP networking. Instead of using a singular config file, each interface has its own file located in /etc/sysconfig/network-scripts and the file name format is ifcfg-INT where INT is the name of your interface. In our example, our interface is eth0, so the file we will be editing is /etc/sysconfig/network-scripts/ifcfg-eth0 and the contents of that file is as below:

DEVICE=eth0
BOOTPROTO=static
BROADCAST=200.5.100.255
HWADDR=00:13:72:65:B0:AD
IPADDR=200.50.100.5
NETMASK=255.255.255.0
NETWORK=200.50.100.0
ONBOOT=yes

Again, some of the above lines are not required, HWADDR, NETWORK, and BROADCAST are not required but definitely add them if you know them. The HWADDR is the interfaces MAC Address, which you can find out by typing “ifconfig eth0″. The default gateway setting in CentOS/RHES is handled in a separate file. Edit the file /etc/sysconfig/network and add the following lines:

NETWORKING=yes
HOSTNAME=foobar.domain.com
GATEWAY=200.50.100.1

Once the files are edited, you again run the command “ifup eth0″ to bring up the interface. The default gateway and hostname settings will be active on reboot, otherwise you have to restart networking for those changes to take effect, this is done by running:

/etc/init.d/network restart

Configuring SSL VPN on Cisco ASA

Starting a few years ago, Cisco began to phase out their support of the long standing VPN Client software which used IPsec. Basically, they didn’t make a 64-bit version to run on Windows 7 and 8, so unless you use XP, its very hard to use the old Cisco VPN client software. The replacement is AnyConnect, which can be launched via the web. AnyConnect does not use IPsec for the vpn tunnel, it uses SSL. The downside is it requires additional licensing, most ASA’s only come with 1 SSLVPN user license, and 10 IPSec.

Here is how you configure a typical ASA (running IOS 8.3) to use webvpn and AnyConnect.

Assumptions:

1. The outside or public WAN IP of the ASA is 200.50.75.1
2. The inside or local access range is 192.168.1.0/24
3. The VPN IP pool that we will create is 10.100.1.0/24

Here is the complete config with some comments.

Create and apply a nonat access list:
ASA(config)# access-list nonat extended permit ip 192.168.1.0 255.255.255.0 10.100.1.0 255.255.255.0
ASA(config)# nat (inside) 0 access-list nonat


Define a split tunnel access list:

ASA(config)# access-list splitvpn standard permit 192.168.1.0 255.255.255.0

Define the Group Policy for the WebVPN:

ASA(config)# group-policy SSLVPN_POLICY internal
ASA(config)# group-policy SSLVPN_POLICY attributes
ASA(config-group-policy)# vpn-tunnel-protocol svc webvpn
ASA(config-group-policy)# webvpn
ASA(config-group-webvpn)# split-tunnel-policy tunnelspecified
ASA(config-group-webvpn)# split-tunnel-network-list value splitvpn
ASA(config-group-webvpn)# split-dns value foobar.com
ASA(config-group-webvpn)# dns-server value X.X.X.X

In the above case, foobar.com would be your local DNS search suffix. The X.X.X.X would be the IP of your local DNS server if you used one, if not you can leave it out or insert a public DNS server IP like 8.8.8.8.

Define a DHCP pool for the clients to use:
ASA(config)# ip local pool vpnpool 10.100.1.1-10.100.1.254 mask 255.255.255.0

Define a local user to use for the VPN:
ASA(config)# username johndoe password ABC123 privilege 0
ASA(config)# username johndoe attributes
ASA(config-username)# vpn-group-policy SSLVPN_POLICY

Enable WebVPN:
ASA(config)# webvpn
ASA(config-webvpn)# enable outside
ASA(config-webvpn)# svc image disk0:/anyconnect-win-2.5.2014-k9.pkg 1
ASA(config-webvpn)# svc image disk0:/anyconnect-macosx-i386-2.5.2014-k9.pkg 2
ASA(config-webvpn)# svc enable

The above location/filename of the AnyConnect software may vary, to verify just type the “dir” command from the main prompt to see a file listing showing the exact filename versions.

Define the tunnel group:
ASA(config)# Tunnel-group SSLVPN_TUNNEL type remote-access
ASA(config)# Tunnel-group SSLVPN_TUNNEL general-attributes
ASA(config-tunnel-general)# default-group-policy SSLVPN_POLICY
ASA(config-tunnel-general)# address-pool vpnpool


Link the tunnel group to WebVPN:

ASA(config)# webvpn
ASA(config-webvpn)# tunnel-group-list enable
ASA(config-webvpn)# exit
ASA(config)# tunnel-group SSLVPN_TUNNEL webvpn-attributes
ASA(config-tunnel-webvpn)# group-alias AnyConnect enable

Basic Cisco Router Config with BGP Uplink

Do you have your own /24 IP subnet and want to setup a BGP router? This article will gave a basic overview of the key components required. The syntax used is for an IOS 12.2 Cisco 6500 series, but is applicable to a 7600 series, a 7200 series, or even a 1800 or 2800 series router.

Assumptions:

1. The /24 subnet we are announcing is 200.50.75.0/24.
2. The IPv4 WAN Subnet from our upstream BGP provider is 128.64.12.128/30.
3. Upstream BGP peer’s AS is 1000, and our AS is 17500

So to begin, we assume our BGP uplink is delivered to us via a basic Cat5 handoff. This handoff has a static WAN subnet of 128.64.12.128/30 – our side of the WAN is 128.64.12.130 and the provider’s side of the WAN is 128.64.12.129. That also means our default GW is 128.64.12.129.

We connect this Cat5 uplink to FastEthernet7/1 on our 6500. Now we need to go into the 6500 series router, config the WAN link, then do all the BGP configs so we can start using our /24 subnet.

We login with enable access and go to configuration mode:

Cisco6500# config -t

We know setup the WAN link:

Cisco6500(config)# interface FastEthernet7/1
Cisco6500(config)# desc BGP Uplink
Cisco6500(config)# ip address 128.64.12.130 255.255.255.252
Cisco6500(config)# no shutdown

We set the default route:

Cisco6500(config)# ip route 0.0.0.0 0.0.0.0 128.64.12.129 250

At this point our router is live and we should be able to ping out to the internet. In order to use our own /24 and AS we need to setup a BGP session with our upstream, let get started:

Cisco6500(config)# router bgp 17500

The above effectively “creates” the BGP service on our end acting as AS 17500, we now need to config it. We are inside the router statement, so every command from this point on effects only the BGP config. We have to exit out to return to the main config.

Cisco6500(config-router)# bgp log-neighbor-changes
Cisco6500(config-router)# neighbor 128.64.12.129 remote-as 1000
Cisco6500(config-router)# neighbor 128.64.12.129 ebgp-multihop 5
Cisco6500(config-router)# neighbor 128.64.12.129 password ABC123

Quick recap of the above. We are telling our BGP service about our first neighbor or “peer”. The peer address 128.64.12.129 is the WAN side IP of our upstream, we specify that our peers AS is 1000, we specify a BGP session password (this is optional, and must be configured to match on the other end), the ebgp-multihop 5 entry is also potentially optional, but I like to add it just in case there are any hops between myself and my peer.

Now we configure the IPv4 portion of the BGP config. In order to do that, we go one more level down in the config by entering the following:

Cisco6500(config-router)# address-family ipv4

This puts you into a sub-config menu, and your prompy will change. From here we can add the IP details of our BGP session:

Cisco6500(config-router-af)# neighbor 128.64.12.129 activate
Cisco6500(config-router-af)# neighbor 128.64.12.129 next-hop-self
Cisco6500(config-router-af)# neighbor 128.64.12.129 send-community
Cisco6500(config-router-af)# neighbor 128.64.12.129 soft-reconfiguration inbound
Cisco6500(config-router-af)# neighbor 128.64.12.129 filter-list 1 in
Cisco6500(config-router-af)# neighbor 128.64.12.129 filter-list 15 out

The first line activates IPv4 on the session. The next three lines are pretty basic and normal. The soft-reconfiguration line is required if you want to be able to do soft resets of the BGP session to grab updates from the other side or vice versa. The last two lines are tricky, but basically, the control what we will allow in and what we allow out from our router. I will describe these filter lists below after we are down with the main BGP config. The following lines finish out out IPv4 portion of the config:

Cisco6500(config-router-af)# no auto-summary
Cisco6500(config-router-af)# no synchronization
Cisco6500(config-router-af)# network 200.50.75.0 mask 255.255.255.0

The last line here is our IPv4 announcement. Now we exit out of the address-family sub-config, and the bgp router sub-config:

Cisco6500(config-router-af)# exit
Cisco6500(config-router)# exit
Cisco6500(config)#

This returns us to the menu config menu. At this point our BGP session is 95% percent complete, just a few loose ends to finish up. Mainly, we have to create those in and out filter lists rules for the BGP prefixes we will allow in and out. We add the following:

Cisco6500(config)# ip as-path access-list 1 permit .*
Cisco6500(config)# ip as-path access-list 15 permit ^$
Cisco6500(config)# ip as-path access-list 15 permit ^(17500_)+$

Access list 1 basically permits everything in, which is want we want. Access list 15 permits our AS 17500 to go out. Last but not least, we need to locally null route our IP announcement:

Cisco6500(config)# ip route 200.50.75.0 255.255.255.0 Null0 250
Cisco6500(config)# exit
Cisco6500(config)# write mem

At this point our BGP router is live, you can verify with the following command:

Cisco6500# sh ip bgp summary
BGP router identifier 128.64.12.130, local AS number 17500
BGP table version is 27807253, main routing table version 27807253
187089 network entries using 18895989 bytes of memory
203251 path entries using 9756048 bytes of memory
48641 BGP path attribute entries using 2724008 bytes of memory
39260 BGP AS-PATH entries using 1076272 bytes of memory
58 BGP community entries using 1392 bytes of memory
0 BGP route-map cache entries using 0 bytes of memory
61132 BGP filter-list cache entries using 733584 bytes of memory
BGP using 33187293 total bytes of memory
8 received paths for inbound soft reconfiguration
BGP activity 4186733/3980758 prefixes, 6186177/5962957 paths, scan interval 60 secs

Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
128.64.12.129 4 1000 10948679 267030 27806888 0 0 7w2d 174293

With your BGP router live and running, you can start using your IP space on any interface by simply assign a subnet of your choosing, for example:

Cisco6500(config)# interface FastEthernet7/2
Cisco6500(config)# desc Mail Server
Cisco6500(config)# ip address 200.50.75.1 255.255.255.248
Cisco6500(config)# no shutdown

This creates a 200.50.75.0/29 subnet on interface 7/2 with 200.50.75.1 acting as the default gateway. Simply connect a server to that port and it will be live with a usable IP in the .2 through .6 (.7 is reserved for the broadcast).

Enabling SSH Access on Cisco ASA Appliances

It is very important to access your ASA via SSH and not telnet. Even if you only enable access from your inside interface, this will protect from clear text password scanning on your local network via an undetected malware bot.

For this example, we are enabling SSH on our inside interface network (192.168.100.0/24).

To get started, enter configuration mode:

asa# config t

Make sure you have an enable password set, in the case TEXT is your clear text enable password:

asa(config)# enable password TEXT

Now we create a local user for SSH login, in this case the username is admin with password ABC123:

asa(config)# aaa authentication ssh console LOCAL
asa(config)# username admin password ABC123 privilege 15

Allow access from our inside network:

asa(config)# ssh 192.168.100.0 255.255.255.0 inside

And finally, generate an RSA key:

asa(config)# domain-name foobar.com
asa(config)# crypto key generate rsa modulus 1024

Its an important to note, you have to specify a domain name in order to generate a functional RSA key. Also, if you wanted to enable SSH access from the outside, you would use the following line:

asa(config)# ssh 75.100.5.45 255.255.255.255 outside

In this case, I am only allowing SSH from a singular IP address of 75.100.5.45 for say a home office.