Enforce a Login-based CLI Access From an Authorized Subnet
For SLAX version 1.0 and higher, you can use the check-file-acl script to enforce a login-based CLI access from an authorized subnet only.
This event script restricts the CLI access to logins from an authorized subnet only. You can easily extend this to multiple subnets, or use 0.0.0.0/32 to deny any access. It uses the jcs:parse-ip extension function.
Source Code and GitHub Links
The source code below is also available from the following GitHub locations:
Example Configuration
01 system { 02 scripts { 03 op { 04 file check-cli-acl.slax; 05 } 06 } 07 } 08 09 event-options { 10 policy no-cli-for-automation-user { 11 events ui_login_event; 12 attributes-match { 13 ui_login_event.username matches "automation1|automation2"; 14 } 15 then { 16 /* 17 * Invoke an event script to forcibly log out 18 * the user who are not supposed to have CLI access. 19 * If the "automation" user is logged in via NETCONF, 20 * this script will have no effect. 21 */ 22 event-script check-cli-acl.slax { 23 arguments { 24 username "{$$.username}"; 25 auth-subnet "0.0.0.0/32"; 26 } 27 } 28 } 29 } 30 policy cli-for-admin-user { 31 events ui_login_event; 32 attributes-match { 33 ui_login_event.username matches "admin1|admin2"; 34 } 35 then { 36 /* 37 * Invoke an event script to check if the admin 38 * user login via CLI is connected from an authorized 39 * subnet, otherwise, forcibly log out the user. 40 */ 41 event-script check-cli-acl.slax { 42 arguments { 43 username "{$$.username}"; 44 auth-subnet "172.17.27.0/24"; 45 } 46 } 47 } 48 } 49 }
SLAX Script Contents
001 /* 002 * YOU MUST ACCEPT THE TERMS OF THIS DISCLAIMER TO USE THIS SOFTWARE. 003 * 004 * JUNIPER IS WILLING TO MAKE THE INCLUDED SCRIPTING SOFTWARE AVAILABLE TO YOU 005 * ONLY UPON THE CONDITION THAT YOU ACCEPT ALL OF THE TERMS CONTAINED IN THIS 006 * DISCLAIMER. PLEASE READ THE TERMS AND CONDITIONS OF THIS DISCLAIMER CAREFULLY. 007 * 008 * THE SOFTWARE CONTAINED IN THIS FILE IS PROVIDED "AS IS". JUNIPER MAKES NO 009 * WARRANTIES OF ANY KIND WHATSOEVER WITH RESPECT TO SOFTWARE. ALL EXPRESS OR 010 * IMPLIED CONDITIONS, REPRESENTATIVES AND WARRANTIES, INCLUDING ANY WARRANTY 011 * OF NON-INFRINGEMENT OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR A 012 * PARTICULAR PURPOSE, ARE HEREBY DISCLAIMED AND EXCLUDED TO THE EXTENT 013 * ALLOWED BY APPLICABLE LAW. 014 * 015 * IN NO EVENT WILL JUNIPER BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR 016 * FOR DIRECT, SPECIAL, INDIRECT, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES 017 * HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY ARISING OUT OF THE 018 * USE OF OR INABILITY TO USE THE SOFTWARE, EVEN IF JUNIPER HAS BEEN ADVISED OF 019 * THE POSSIBILITY OF SUCH DAMAGES. 020 * 021 * 022 * Author : Roy Lee 023 * Version : 1.0 024 * Last Modified : 2008-12-01 025 * 026 * Description : check-cli-acl.slax 027 * This event script is written to restrict the cli access with a given login 028 * from an authorized subnet only. This can be easily extended to multiple 029 * authorized subnets, or use 0.0.0.0/32 to deny any access. 030 * 031 * 032 * Below is a sample event policy configuration which will be triggered 033 * when the administrative user "adminX" has login to the device via CLI. 034 * The name of the user and the authorized subnet are the two arguments passed 035 * to the event-script. 036 * 037 * --- 038 * event-options { 039 * policy cli-for-admin-user { 040 * events UI_LOGIN_EVENT; 041 * attributes-match { 042 * UI_LOGIN_EVENT.username matches "admin1|admin2"; 043 * } 044 * then { 045 * event-script check-cli-acl.slax { 046 * arguments { 047 * username "{$$.username}"; 048 * auth-subnet "172.17.27.0/24"; 049 * } 050 * } 051 * } 052 * } 053 * } 054 * --- 055 * 056 * When a CLI login with the matching username is found, the script 057 * will compare its source IP with the authorized subnet. It will forcibly 058 * log out the CLI user who is not connected from the authorized subnet. 059 * 060 * If the requirement is to completely disallow CLI login for a given username 061 * from any subnet, specify the value "0.0.0.0/32" as the auth-subnet argument. 062 * 063 */ 064 065 version 1.0; 066 067 ns junos = "http://xml.juniper.net/junos/*/junos"; 068 ns xnm = "http://xml.juniper.net/xnm/1.1/xnm"; 069 ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0"; 070 071 072 param $username; 073 param $auth-subnet; 074 075 match / { 076 <op-script-results> { 077 078 /* 079 * "show system users no resolve" command displays 080 * only the user which has TTY assigned to it, 081 * which means the users who are logged in 082 * through the CLI. 083 */ 084 085 var $cmd1 = <command> "show system users no-resolve"; 086 var $out1 = jcs:invoke($cmd1); 087 088 for-each ($out1/uptime-information/user-table/user-entry[user=$username]) { 089 var $ipaddr = from; 090 091 /* 092 * Process the authorized subnet params using jcs:parse-ip(), 093 * then extract the subnet and prefix, i.e. 094 * auth-ip[3] is the prefix, 095 * auth-ip[4] is the subnet 096 */ 097 var $auth-ip = jcs:parse-ip($auth-subnet); 098 099 /* 100 * Append the prefix to ipaddr and 101 * then parse it 102 */ 103 var $temp = $ipaddr _ "/" _ $auth-ip[3]; 104 var $user-ip = jcs:parse-ip($temp); 105 106 /* 107 * Now match the subnet 108 */ 109 if ($user-ip[4] != $auth-ip[4]) { 110 var $logout = { 111 <command> 'request system logout user ' _ $username _ " terminal " _ tty; 112 } 113 114 var $result = jcs:invoke($logout); 115 expr jcs:output("Logging out cli user ", $username); 116 expr jcs:output(" connected from an unauthorized subnet."); 117 } 118 } 119 } 120 }
XML Script Contents
01 <?xml version="1.0"?> 02 <script> 03 <title>check-cli-acl.slax</title> 04 <author>royklee</author> 05 <synopsis> 06 Enforces a login-based CLI access from an authorized subnet only 07 </synopsis> 08 <coe>event</coe> 09 <type>login</type> 10 11 <description> 12 This event script is to restrict the CLI access with a given login 13 from an authorized subnet only. This can be easily extended to 14 multiple subnets, or use 0.0.0.0/32 to deny any access. It uses 15 jcs:parse-ip extension function. 16 17 </description> 18 19 <example> 20 <title>Configuration</title> 21 <description>Configuration required for this event script</description> 22 <config>example-1.conf</config> 23 </example> 24 25 <xhtml:script xmlns:xhtml="http://www.w3.org/1999/xhtml" 26 src="../../../../../web/leaf.js" 27 type="text/javascript"/> 28 </script>