Blogs

Scripting How-To: Use the ttl-security script to turn on TTL-based security (GTSM)

By Erdem posted 08-11-2015 02:49

  

Use the ttl-security Script to Turn on TTL-based Security

 For SLAX version 1.0 and higher, you can use the ttl-security script as an easy mechanism to turn on TTL-based security (GTSM).

 

For example, create an lo0 filter based on your BGP configuration. List any members of BGP groups with "apply-macro ttl-security" turned on in the "ttl-security" filter, and are only allowed if the TTL on incoming packets is 254 (meaning they are exactly one hop away).

 

Script Implementation

 
There are three parts to this script:

 

  1. First, set the TTL to 255.
  2. Create a filter that discards traffic where TTL != 254.
  3. Place that filter in lo0.

You don't want to interfere with an existing filter on lo0, so look at the current state:

 

  • If there's no filter, make one and put a "then accept" on it.
  • If there's a single filter, turn it into a filter list with your newly created filter at the front of the list.
  • If there's already a filter list, add your new filter to the front of the list.

Source Code and GitHub Links

 

The source code below is also available from the following GitHub locations:

 


Example Configuration


01	system {
02	    scripts {
03	        commit {
04	            allow-transients;
05	            file ttl-security.slax;
06	        }
07	    }
08	}
09	protocols {
10	    bgp {
11	        group test {
12	            apply-macro ttl-security;
13	            neighbor 10.1.2.3;
14	            neighbor 10.3.4.5;
15	            neighbor 10.5.6.7;
16	        }
17	    }
18	}

 

Example Output


01	system {
02	    scripts {
03	        commit {
04	            allow-transients;
05	            file ttl-security.slax;
06	        }
07	    }
08	}
09	interfaces {
10	    lo0 {
11	        unit 0 {
12	            family inet {
13	                filter {
14	                    input ttl-security;
15	                }
16	            }
17	        }
18	    }
19	}
20	protocols {
21	    bgp {
22	        group test {
23	            apply-macro ttl-security;
24	            ttl 255;
25	            neighbor 10.1.2.3;    
26	           neighbor 10.3.4.5;
27	            neighbor 10.5.6.7;
28	            }
29	      }      
30	   }     
31	 firewall {  
32	filter ttl-security {
33	     term gtsm {
34	           from {
35	        source-address {
36	                   10.1.2.3/32;
37	                   10.3.4.5/32;
38	                   10.5.6.7/32;
39	                 }   
40	                  protocol tcp;  
41	                 ttl-except 254;
42	                 port 179;
43	             }   
44	             then {   
45	               discard;
46	            }
47	         }       
48	        term else {    
49	        then {
50	              accept;
51	            }
52	         }       
53	      }      
54	   }      

SLAX Script Contents


001	version 1.0;
002	 
003	ns junos = "http://xml.juniper.net/junos/*/junos";
004	ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
005	ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
006	 
007	import "../import/junos.xsl";
008	 
009	/*
010	 * Implement GTSM for JUNOS
011	 *
012	 * We need to make an lo0 filter based on our BGP config.  Any
013	 * members of BGP groups with "apply-macro ttl-security" turned
014	 * on are listed in the "ttl-security" filter and are only allowed
015	 * if the TTL on incoming packets is 254, meaning they are exactly
016	 * one hop away.
017	 *
018	 * Three parts to this script.  First we set the TTL to 255.  Then
019	 * we make a filter that discards traffic where TTL != 254.  Then
020	 * we put that filter in lo0.
021	 *
022	 * We don't want to interfere with an existing filter on lo0, so
023	 * we have to look at the current state.  If there's no filter,
024	 * we make one and put a "then accept" on it.  If there's a single
025	 * filter, we turn it into a filter list with our's at the front of
026	 * the list.  If there's already a filter list, we add our's to the
027	 * front of the list.
028	 */
029	match configuration {
030	    var $all = protocols/bgp/group[apply-macro/name == 'ttl-security'];
031	    var $tag = "transient-change";
032	    var $lo0 = interfaces/interface[name == 'lo0']
033	            /unit[name == '0']/family/inet/filter;
034	    if ($all) {
035	    var $content = <multihop> {
036	        <ttl> 255;
037	    }
038	 
039	    for-each ($all) {
040	        call jcs:emit-change($tag, $content);
041	    }
042	 
043	    var $last-term = {
044	        if (not($lo0/input) && not($lo0/input-list)) {
045	        <term> {
046	            <name> "else";
047	            <then> {
048	            <accept>;
049	            }
050	        }
051	        }
052	    }
053	 
054	    var $filter = {
055	        if ($lo0/input) {
056	        <input-list> "ttl-security";
057	        <input-list> $lo0/input;
058	        } else if ($lo0/input-list) {
059	        var $name = $lo0/input-list[1];
060	        <input-list insert="before" name=$name> "ttl-security";
061	        } else {
062	        <input> "ttl-security";
063	        }
064	    }
065	 
066	    <transient-change> {
067	        <firewall> {
068	        <filter> {
069	            <name> "ttl-security";
070	            <term> {
071	            <name> "gtsm";
072	            <from> {
073	                for-each ($all/neighbor/name) {
074	                <source-address> .;
075	                }
076	                <protocol> "tcp";
077	                <port> 179;
078	                <ttl-except> 254;
079	            }
080	            <then> {
081	                <discard>;
082	            }
083	            }
084	            copy-of $last-term;
085	        }
086	        }
087	        <interfaces> {
088	        <interface> {
089	            <name> "lo0";
090	            <unit> {
091	            <name> "0";
092	            <family> {
093	                <inet> {
094	                <filter> {
095	                    copy-of $filter;
096	                }
097	                }
098	            }
099	            }
100	        }
101	        }
102	    }
103	    }
104	}

 

XML Script Contents


01	<?xml version="1.0"?>
02	<script version="0.1">
03	  <title>ttl-security.slax</title>
04	  <author>phil</author>
05	  <synopsis>Easy mechanism to turn on TTL-based security (GTSM)</synopsis>
06	  <keyword>GTSM</keyword>
07	  <keyword>BGP</keyword>
08	  <keyword>TTL</keyword>
09	 
10	  <description>
11	    We need to make an lo0 filter based on our BGP config.  Any
12	    members of BGP groups with "apply-macro ttl-security" turned
13	    on are listed in the "ttl-security" filter and are only allowed
14	    if the TTL on incoming packets is 254, meaning they are exactly
15	    one hop away.  This script is based on:
16	    http://juniper.cluepon.net/index.php/ER_BGP_TTL_Security_support_enhancements
17	  </description>
18	  <implementation>
19	    Three parts to this script.  First we set the TTL to 255.  Then
20	    we make a filter that discards traffic where TTL != 254.  Then
21	    we put that filter in lo0.
22	     
23	    We don't want to interfere with an existing filter on lo0, so
24	    we have to look at the current state.  If there's no filter,
25	    we make one and put a "then accept" on it.  If there's a single
26	    filter, we turn it into a filter list with our's at the front of
27	    the list.  If there's already a filter list, we add our's to the
28	    front of the list.
29	  </implementation>
30	 
31	  <example>
32	    <config>ttl-security.conf</config>
33	    <title>An example with no lo0</title>
34	    <output>ttl-security.output</output>
35	  </example>
36	  <xhtml:script xmlns:xhtml="http://www.w3.org/1999/xhtml"
37	                src="../../../../../web/leaf.js" type="text/javascript"/>
38	</script>

 


#BGP
#commitscript
#ttl
#ScriptingHow-To
#How-To
#Slax