Please consider donating: https://www.corelan.be/index.php/donate/


34,398 views

Juniper ScreenOS : default route manipulations and redistributions

The default route or “route of last resort” is an important route in most present inter-network connectivity configurations. It contains all public and private routes possible and is responsible for directing traffic to a next hop when no better route is found.  In most cases, it is used to allow networks to access the internet, but this is not the only scenario where a default route is used.  It can be used for example on child networks, that don’t have a direct connection to the internet, to aggregate all routing into one single route, pointing to an upstream router, which then separates internet traffic and private traffic. (Example : OSPF stub area’s and not-so-stubby area’s)

It is important to understand that the “0.0.0.0/0” notation does not always refer to the default route. In fact, in some/most routers, 0.0.0.0/0 refers to “all networks”, while “default-route” or “default” refer to the default route only. It depends on the router OS and configuration area where you are using the statement.  For example : 0.0.0.0/0 in a static route refers to the default route, where 0.0.0.0/0 in a route-map refers to all networks, either containing or not containing the default route. It’s fundamentally important to find out how your OS version behaves.  Based on that knowledge, you can start manipulating and redistributing the default route.

Before we start looking at setting and getting default routes, I’d like to stress the importance of a proper understanding of the routing decision table in screenos :

Routing decision table

Default decision table :

  • Check if source interface based routing is enabled in vrouter & look for active route *
  • Check if source based routing is enabled in vrouter & look for active route *
  • Look for active route in destination-based routing table

* If a working/active route is found, the packet is forwarded on the specified interface and/or next-hop. If no active route is found, the packet is sent to the next check

 

vrouter(trust-vr) route-lookup preference table(sorted by preference):
------------------------------------------------
route-lookup-method    preference
------------------------------------------------
SIBR-route-lookup      3
Source-IP-lookup       2
destination-IP-lookup  1

As you can see, the decision process prefers the look-up technique that has the highest value.

You can change the sequence of the decision table (SIBR – SBR – DBR) by modifying vrouter parameters. If you want to set destination routing as first route lookup, then you could assign preference 4 to destination-routing :

set vrouter trust-vr route-lookup preference destination-routing 4
 
How does screenOS determine which route is the active/preferred route ?
 

Determining the best/active route to a destination :

– Look at prefix (subnet + mask). The more specific the prefix, the more preferred the route will be. When multiple routes to the same destination network are found, look at preference.
– Preference : routes with lower preference value are preferred.  When multiple routes to the same destination network with the same preference are found, look at the metric value.
– Metric : the route containing the lowest metric value will win. When there are multiple routes to the same destination network with the same preference and metric are found, a route is selected at random (unless ECMP is enabled, see later)
If a route uses another vrouter as next-hop, then another sequence of route lookups is performed in order to determine the best (active) route.
 
The active/best route for a destination network can be found by looking at the routing table, looking for the route that has an asterisk (*) in front of the route, or by performing a get route ip
 

Equal Cost Multipath Routing

When ECMP routing is enabled, there could be multiple active routes to a destination network. This could be used to load balance traffic over 2 or more links (this number is configurable up to a max. of 4). This works well for applications that create only one session (such as ssh, telnet, smtp, …) but this does not work well for applications such as HTTP (because one HTTP interaction consists of multiple sessions… based on the routing setup, these sessions could be originating from different source IP addresses (when nat is used), which could break session-awareness features etc)

ECMP is disabled by default (=the max. number of equal cost routes is set to 1)

 

BGP route selection process

In BGP, the “best route” is selected based on BGP attributes.  First of all, the BGP router verifies that it has an active route towards the NEXT_HOP attribute that is part of the route advertisement. In other words : if a route is advertised, but the next_hop cannot be contacted because there is no known route to the IP address of the NEXT_HOP attribute, this route will not be active.

Next, BGP compares routes for the highest local_preference.  If this selection does not lead to a winner, the route with the shortest AS_PATH will become the active route.

If this does not provide a best route, the origin code is used.  (lowest origin code is preferred).

If multiple routes are available to the same upstream AS (so if multiple routes are advertised from the same neighboring AS), the MED (Multiple Exit Discriminator) value will help selecting the best route. (The connection with the lowest MED value will win).  

If the MED attribute is either not available or still does not lead to a unique best route, the BGP router will prefer eBGP routes over iBGP routes.

– iBGP routes :

  • the path with lowest IGP cost to the iBGP peer is preferred
  • The cluster list attribute is evaluated for the shortest length
  • the router ID’s are evaluated (peer with lowest router ID wins)
  • the peer ID values are evaluated.

-eBGP routes :

  • the router ID’s are evaluated (peer with lowest router ID wins)
  • the peer ID values are evaluated.

With BGP, you can use access-lists / route-maps to modify attributes, and you can also set the local preference for eBGP vs iBGP to influence the BGP route selection process.

Defining a default route

There are 4 common ways to get a default route in the local routing table in screenOS.   You can specify a default route via a static route, you can learn it from a dynamic routing protocol, it can be imported from another vrouter and it can be a connected route on f.i. DSL interfaces.

On top of that, you can have multiple default routes in your system (either in a single vrouter, in multiple vrouters, or multiple default routes in multiple vrouters).

Multiple default routes can be used for failover purposes, for Equal Cost Multipath routing (load balancing – however this does not work for all traffic), for policy based routing, etc. 
Unless you are using ECMP routing,  you probably still want to control the path that is used by your clients.  So that means that you need to be able to set/modify parameters in order to force one default route to be preferred over another, or use policy based routing to force certain traffic over one default route, and other traffic over another default route.  I have posted a document about pbr (policy based routing) earlier on this blog.

Default routes are important to redirect “all other traffic” to a specifiy gateway. It can include access to the internet, access to remote sites connected via VPN (policy based VPN’s), access to other private networks, etc.

Tip : Despite the fact that most ISP’s don’t route private network ranges, you may not want to take any risk at all. I usually set up my routing tables to include the 3 big RFC1918 networks, with a high cost/preference value, and route them to a null interface. That way

  • only packets to non-private network ranges will be sent to the default gateway
  • you must put in a better route to your private networks in the routing table before it will be reachable, allowing you to restrict which private networks are routeable and which ones aren’t.

So after setting up every juniper firewall basic config (vrouters, zones, interfaces), I usually put these 3 routes in the routing table :

set route 10.0.0.0/8 int null preference 250 permanent
set route 172.16.0.0/12 int null preference 250 permanent
set route 192.168.0.0/16 int null preference 250 permanent

Anyways, let’s continue with the default routes.

Static default route

Let’s start with the static default route. A basic static default route in screenos can be created using the following command :

set route 0.0.0.0/0 gateway default router>

There are a couple of options available when specifying a static route :

  • You can send traffic to a gateway, send traffic to a gateway using a specific interface, send traffic to an interface (e.g. tunnel interface or null) or send traffic to another vrouter
  • You can set description, metric, preference and tag. The metric and preference can be used to change the preference of the route. The rule of thumb is : if preference values are the same, the route with the lowest metric will win.    When you don’t specify a preference or metric value, then the default parameters will be used.  The default metric for a static route is 1, the default preference is 20, but can be changed as a parameter in the current vrouter. (set vr trust-vr preference static  20) This means that you can have different preferences for default routes in various vrouters.Note : the “tag” attribute can be used as a filter when redistributing routes. You basically can create a route map that matches on a certain tag.  Now if you want to redistribute the default route into OSPF or BGP, the tag will be pretty useless because the default route will only get advertised if you enable the advertisement of the default route. So the use of a tag on the default gateway is not very usefull.
  • You can set the route permanent or not.  You can only set the route permanent when specifying an outgoing interface. If you set the route permanent, the default route will stay active, even when the interface is down.  It’s important to use this statement wisely. If you don’t use permanent, you may end up with a routing loop, if you use permanent, you may loose connectivity if you have failover (track-ip, etc) configured.

You can use the “get route” command to see the active default route and to get more information about a specify route (by specifying the route id). The following commands are usefull to find info about static default routes :

  • get route
  • get route | incl 0.0.0.0/0
  • get route id 222 
  • get route proto static

Example : get route id 222

route in trust-vr:
------------------------------------------------
id:                   222
IP address/mask:      0.0.0.0/0
next hop (gateway):   1.1.1.1
preference:           20
metric:               1
outgoing interface:   ethernet0/0
vsys name/id:         Root/0
tag:                  5
flag:                 24000042/00100011
type:                 static
Redistributed to:
status:               active (for 40 days 1 hours 28 minutes 59 seconds)

(static route, preference 20, metric 1, tag 5, outgoing interface eth0/0, next-hop 1.1.1.1)

 

Learn default route from a dynamic routing protocol

When you have a dynamic routing protocol in place (I’ll use OSPF and BGP in this post), you can receive the default route from your peer.  The list of parameters that can be altered while receiving the default route depend on the dynamic routing protocol.

When using OSPF, you can only change the preference value for incoming OSPF routes, by setting the preferences in the vrouter (note : for OSPF, you have 2 options : type E1 and type E2.)  If you want to set type 1 routes to preference 30 and type 2 routes to preference 40, then you need to use the following commands.  Note that this setting will apply to ALL routes learned via OSPF, not just to the default route.

set vr trust-vr preference ospf 30
set vr trust-vr preference ospf-e2 40

Keep in mind that, by default, Type 1 routes are preferred over Type 2 routes.  Type 1 routes add the path cost through the OSPF cloud to the advertised metric. Type 2 just assume the advertised metric.  In case there is a tie situation, the path cost will win.  FYI : path cost for OSPF can be set on the interface level. General rule is to use a value that indicates a 100000/ available bandwidth, but you are free to determine your own values.  Suppose you want to set a path cost of 100 to OSPF on interface eth0/0, you this statement :

set int e0/0 proto ospf cost 100

Pay attention to the costs. If you set the costs to a very high value, traffic may start using routes that cross continent/area boundaries instead of using local backup paths.  It is recommended to set the metrics of backup paths to a value that is only one or two higher than the main link.

If you want to be able to further modify default route parameters and only default route parameters, you either need to use BGP, static routes, or imported routes. With OSPF, it’s all or nothing.

Unlike BGP or imported routes, you cannot create a route-map and access-list with OSPF to modify attributes of incoming routes (only for outgoing routes – see later). The only additional thing you can do is reject or accept the default route from the neighbor.

Suppose you want to reject the default route from being advertised to your OSPF router, in vrouter trust-vr, area 10, then use the following commands :

set vrouter trust-vr
set proto ospf
set area 0.0.0.10
set reject-default-route

When using BGP, you’ll have more control over the various parameters and routing behaviour. Apart from the fact that you can change the preference for iBGP and eBGP routes in the vrouter, and that you can accept/reject the default route from being learned from a BGP neighbor, you can also create access-lists and route-maps and modify BGP attributes that may impact the network traffic flow over one or more default routes. These route-maps/access-lists can be set up to work in both directions, so you can modify attributes for both incoming and outgoing routes.

The attributes that can be modified are shown here :

image

If you want to modify attributes for default routes (or for non default routes), you need to create an access-list (matching on “default-route”), a route-map, and set the attributes in the route-map.   (the AS Path attribute value refers to an as-path-access-list number that must be created in the bgp instance config and will allow you to AS prepend a route. I’ll show you how to do this for a default route later on in this document)

 

Import default route from another vrouter

There are a lot of good reasons why you want to use multiple vrouters in your firewall. Perhaps you want to run a dynamic routing protocol with your internet ISP and you want  to make sure the ISP cannot change your own internal routing table.  In that case, you probably would want to set up a dedicated vrouter for the communication with the ISP and another vrouter for your own internal routing.  Of course, in your internal (or trust) vrouter, you could create a static default route pointing to the internet vrouter, but you can also export the default route from the internet vrouter to the internal vrouter (or import the default from the internet vrouter into the internal vrouter. Either way, the default route will show up in the internal vrouter as an imported route)

This is how it works : In the internet vrouter :

set vrouter "internet-vr"
set access-list 1
set access-list 1 permit default-route 10
set route-map name "DefGWToTrust" permit 10
set match ip 1
exit
set export-to vrouter "trust-vr" route-map "DefGWToTrust" protocol connected

The result looks like this :

ssg5-> get route | incl 0.0.0.0/0
*       325          0.0.0.0/0            n/a     internet-vr  CI   30      1     Root
*       304          0.0.0.0/0         eth0/0     1.1.1.1      C    0      1         

ssg5-> get route id 325
route in trust-vr:
------------------------------------------------
id:                   325
IP address/mask:      0.0.0.0/0
next hop (vrouter):   internet-vr
preference:           30
metric:               1
description:
outgoing interface:   n/a
vsys name/id:         Root/0
source-vr:            internet-vr
tag:                  0
flag:                 24000822/00100000
type:                 imported(Source - connected)
Redistributed to:      BGP
status:               active (for 24 minutes 44 seconds)

route --> 0.0.0.0/0 in vr internet-vr:
id:                   304
IP address/mask:      0.0.0.0/0
next hop (gateway):   1.1.1.1
preference:           0
metric:               1
description:
outgoing interface:   ethernet0/0
vsys name/id:         Root/0
tag:                  0
flag:                 24000200/00100000
type:                 connected
Redistributed to:
status:               active (for 24 minutes 44 seconds)

One of the results of this setup is that, if the default route disappears from the internet-vr, it will no longer be exported to the trust-vr (and will thus disappear from the routing table). If you have redundant internet routing, this may come handy.

As you can see, the default route shows up as an Imported route in trust-vr. The preference value of this imported route can be altered in trust-vr (so you can manipulate the routing preference for imported routes  vs other routes available on the system)

 

The connected default route

If you are connected to an internet ISP over DSL or just using DHCP, the default route will show up as a connected route. Nothing special here, but you must keep in mind that connected routes have a preference of 0.  So they will be used at all times, even if you try to set a static default route.  You may still be able use ECMP (connected route + a static route) or use PBR to separate traffic over multiple/different default gateways, but you cannot overrule the default gateway in the vrouter if it is “connected”.  If you want to change this behaviour (so if you want to overcome the “connected = preference 0” problem, stay tuned… I will show you a way to fix this problem later on)

 

At this point, you should be able to define your default route and change preferences of the default route, forcing traffic to flow the way you want it to flow (with the exception of the connected default route issue – but we’ll tackle that one later on).Now it’s time to look at default route redistribution scenario’s 

 

Default Route Redistribution

In this blog post, the term “redistribution” applies to dynamic routing protocols. I’ll use OSPF and BGP to demonstrate how you can take the default route (static, learned from OSPF, learned from BGP, imported or connected) and redistribute it into OSPF or BGP.

Redistribute default route into OSPF

Regardless of where the default route originates from, it can be advertised into OSPF using one single statement. The syntax used is based on the OSPF Type you want to assign to the default route (Type 1 or Type 2)

Suppose you want to advertise the default route into OSPF, with metric 30 and OSPF type 1, then use the following commands

set vrouter trust-vr
set proto ospf
set advertise-def-route metric 30 metric-type 1

As you can see, the redistribution of the default route into OSPF applies to all OSPF areas on the system.

The default route will only get advertised if there is a valid default route in the current routing table. If you always want to advertise the default route, even if there is no default route, you can add the “always” keyword :

set advertise-def-route always metric 30 metric-type 1

If you want to stop the default route from being received from a remote neighbor via OSPF, you can use the following OSPF area configuration :

set vrouter trust-vr
set proto ospf
set area 0.0.0.1
set reject-default-route

(This is an area-specific configuration)

 

Redistribute default route into BGP

In BGP, there are 3 ways to advertise the default route. You can redistribute the default route to all peers by enabling default route injection on BGP level, you can only redistribute it to a specific peer by setting the redistribution in the peer configuration, or you can redistribute it and change attributes (e.g. AS Prepend the default route).

The basic redistribution of the default route into BGP works like this :

set vrouter trust-vr
set proto bgp 65111
set advertise-def-route

If you only want to advertise it to a specific peer, unset the advertise-def-route in BGP (or ask all other peers to set a reject-default-route in their BGP config – which is a good idea anyway) and set the advertisement on the peer definition :

set vrouter trust-vr
set proto bgp 65111
set neighbor 1.1.1.1 remote-as 65112
set neighbor 1.1.1.1 advertise-def-route

 Note : in Cisco IOS bgp configuration, you can advertise a default route to a neighbor using the following commands :
enable
conf t
router bgp 65110
neighbor 2.2.2.2 remote-as 65114
neighbor 2.2.2.2 default-originate

Keep in mind that this will advertise the default gateway to the neighbor, even if the default gateway route does not exist. If you want to only advertise the default route, you can use a route map (and e.g. see if a certain route exists before advertising the default-originate). This is beyond the scope of this post, but I may put a document on Cisco BGP routing somewhere in the future.

AS Prepending default route (and only the default route) while redistributing it into BGP

If you want to modify attributes while redistributing the default route into BGP, you have to create an access-list and route-map. If you want to AS Prepend the default route, you need to create an as-path-access-list as well.

This scenario may be useful if you have the following topology and desired behaviour :

  • The network consists of 3 locations.  Each location has a local internet connection and is connected over a WAN as well
  • The 3 locations exchange their routing information to each other over BGP
  • One of the locations (fw-a) has a local default gateway, and uses monitoring (track-ip) to see if the default route works or not
  • fw-b and fw-c both redistribute their default gateway into BGP.  If the internet connection on fw-a goes down, the default gateway originating from fw-b must be used, and the default gateway learned from fw-c must be used if both the local default gateway on fw-a is down, and the one from fw-b is not working either)  (so on fw-a, the default gateway from fw-b is preferred over the one originating from fw-c)

In this scenario, fw-b will advertise a default route (and this route will disappear if it’s not valid anymore), and fw-c will also advertise a default route, but it needs to be AS prepended so it is only used when the route originating from fw-b is gone

Let’s have a look at fw-c. Suppose the default route on fw-c is a static default route. You only want to AS prepend the default route, and you still want to redistribute the other static routes to BGP (without AS prepending them however).  The config on fw-c will look like this :

set vrouter trust-vr
set access-list 1 permit default-route 1
set access-list 2 deny default-route 1
set access-list 2 permit 0.0.0.0/0 2
set route-map name "RedistToBGP" permit 1
set match ip 1
set as-path 1
exit
set route-map name "RedistToBGP" permit 2
set match ip 2
exit

set proto bgp 65111
set as-path-access-list 1 permit "65111 65111"
set neighbor 1.1.1.1 remote-as 65112
set neighbor 1.1.1.1 enable
set neighbor 1.1.1.1 route-map "RedistToBGP" out
exit
set advertise-def-route
set redistribute route-map "RedistToBGP" proto static

First, create 2 access-lists

– One for the default route (access-list 1)

– One for the non-default routes (access-list 2)

Next, create a route-map (“RedistToBGP”) with 2 access-lists bound to it. The first one must match the one for the default route (and the as-path parameter must be set),  the second one must match the non-default route.   This sequence is fundamentally important.

The as-path-access-list (configured under bgp) must define the AS prepend values. In my example, the default route will be AS prepended twice.

Next, in the neighbor configuration, an outgoing route-map must be set, referring to the route-map that contains the 2 access-lists.  If you don’t set the outgoing route-map, the config will not work.

Finally, you must configure “set advertise def-route” in bgp (otherwise the default route will not be advertised) and do a redistribute of route-map “RedistToBGP” of the static routes.

The redistribute command will take care of the other (non default) static routes, the outgoing route-map on the bgp peer definition will take care of the default route.

After setting this configuration, all static routes will be redistributed into BGP.  Only the default route will be AS prepended.

 

Tackling the “connected preference=0” problem

As explained earlier in this post, a connected default route has a preference of 0.  You can change the preference value in the vrouter, but that is not a good idea because it will have an impact on all connected subnets, and it may make your routing configuration much more complex.  (suppose you change the connected preference to a value that is higher than one of the other routes in your routing table, you may break access to the local subnets)

But what if you have 2 default gateways, one of them being a connected and another one let’s say a static one; and you want to prefer the static one over the connected one ? Well, it’s quite simple.

Put the interface that has the connected default route in a separate vrouter, and export the default gateway from that new vrouter to your trust vrouter.  You can change the preference for imported routes (or exported routes if you choose to export the default route from the new vr to the trust vr) in the trust vr, which means that you can force the connected default route to become the second preferred default route.

In fact, if you look back at the “import default route into another vrouter” example, you will notice that the default route in the internet-vr is in fact a connected default route, and the actual default route used in trust-vr is imported and has a preference of 30 because I’ve configured the vrouter trust-vr as such.

 

 

useful links :

http://www.juniper.net/techpubs/software/screenos/screenos6.1.0/ce_v7.pdf

© 2009 – 2021, Peter Van Eeckhoutte (corelanc0d3r). All rights reserved.

4 Responses to Juniper ScreenOS : default route manipulations and redistributions

Corelan Training

We have been teaching our win32 exploit dev classes at various security cons and private companies & organizations since 2011

Check out our schedules page here and sign up for one of our classes now!

Donate

Want to support the Corelan Team community ? Click here to go to our donations page.

Want to donate BTC to Corelan Team?



Your donation will help funding server hosting.

Corelan Team Merchandise

You can support Corelan Team by donating or purchasing items from the official Corelan Team merchandising store.

Protected by Copyscape Web Plagiarism Tool

Corelan on Slack

You can chat with us and our friends on our Slack workspace:

  • Go to our facebook page
  • Browse through the posts and find the invite to Slack
  • Use the invite to access our Slack workspace
  • Categories