Advanced keystroke action
Advanced Keystroke Action was introduced to allow control and audit of command line based network appliances, and was implemented as an enhancement to the pbssh feature. Full session logging provides a complete command audit trail through the existing session logging technology.
Advanced Keystroke Action emulates an interactive command line, and only then authorizes the command once the user has pressed Enter to execute the command. This means the policy can try to match the command it receives in context to the task the user is performing, and it can choose to rewrite the command, accept it, or reject it. It also allows the policy to change the user environment as they carry out their tasks, for example, changing prompts or tab completion.
Get started with advanced keystroke action
Configure EPM-UL policy
Advanced Keystroke Action is implemented on top of existing pbssh technology and appropriate configuration is required in the policy script file. For example:
if(pbclientname=="pbssh") {
myadmins={"admin1"};
myswitches={"cisco1"};
if(pbclientmode=="pbssh") {
if(search(myadmins,user) >= 0 && search(myswitches,host) >= 0) {
accept;
} else {
reject;
}
} else if(pbclientmode=="run") {
args=split(argv[argc-1]," ");
argslen = length(args);
if(argslen > 0 && search(myswitches,args[argslen-1]) >= 0) {
keystrokeactionprofile="cisco profile1";
accept;
} else {
reject;
}
}
}
Configure Password Safe
Configure Password Safe on the Advanced Keystroke Action primary server or Policy Servers.
Note
To provide automatic authentication, Password Safe can be configured to retrieve logon credentials. For information on this configuration, including the specification of pkrunfile, pk_cert, and pk_servers in the pb.settings configuration file, see pbssh.
Configure the advanced keystroke action primary server or policy servers
If the Advanced Keystroke Action is being configured for the first time, the policy database will need to be created on the primary AKA server or primary Policy Server.
- Specify the Advanced Keystroke Action Policy Database by adding the keyword advkeystrokeactionpolicydb to the pb.settings on all server hosts.
- If you are using Registry Name Service you will need to define your Primary Server in the RNS using:
pbadmin --svc -u '{"svcgname":"dflt_akapolicy_service", "svc":"advkeystrokeactionpolicy", "cn": "<policy server fqdn>", "role":"primary"}'
- Create the policy database (which includes a demo policy that can be used as a basis for further configuration and learning)
pbadmin –-aka -n
The pbadmin command can then be used to export and re-import Advanced Keystroke Action policies. The Endpoint Privilege Management for Unix and Linux script policy keyword must match a valid Advanced Keystroke Action policy name for the session to run.
Maintain and configure advanced keystroke action policy
pbadmin has been enhanced to provide methods to maintain the Advanced Keystroke Action Policy on the Primary Policy server. This includes a new section (--aka) with new options.
Usage
pbdbutil --aka [<options>] [ <file> <file> ...]
Options for AKA client:
Option | Description |
---|---|
-R | Force refresh of the client aka profile cache file(s) |
args | Optional. The arguments to the function. |
Options for Advanced Keystroke Action profile server database management:
Option | Description |
---|---|
-n | Create new AKA database |
-l | List all AKA configurations in database |
-s <[-|+]attribute> | Sort the list of records by attribute name (asc/desc) |
-i | Import AKA configuration file |
-e | Export specified AKA configuration |
-g | Get AKA configuration by name |
-d | Delete AKA configuration |
-u { "name" : "", "cfg": { json param... }} | Update AKA configuration |
Advanced keystroke action policy
Policies for Advanced Keystroke Action are different from normal Endpoint Privilege Management for Unix and Linux policies because they have a different function to fulfill. The policy is defined as a JSON object split into a number of separate sections including variables, prerun, complete actions, macros, readonly, and policy. The primary section of the policy is an ordered list of match and action nodes. These match the command line, or other variable, and perform specified actions if the match is successful.
Preamble
The preamble defines the name of the configuration and whether debug can be enabled.
Example
Through the command line:
set akadebug 10``{
"name": "demo",
"cfg": {
"debug_enabled": true,
….
}
Variables
The variables section allows the configuration of variables that can be used within the policy. Variables, by default, are read/write within the policy but may be defined as readonly in the readonly section.
All JSON data types are supported, including booleans (true/false), strings, integers, floating point numbers (reals), and arrays of datatypes using the JSON format. These can then be referred to by name using a notation similar to bash. For example, ${varname}" or "${arrayelement[2]}.
Some variables are special in that they can only hold specific values. For example, editor can only be emacs or vi, and keymap can only hold specific definitions of keys (similar to the NetBSD libedit or GNU readline names.
The variable input is the current command line, and if it is rewritten it will change the command line. If it is set to null, it removes the current input and returns the user to the command line.
Example
"variables": {
"editor": "emacs", "prompt": "$ ", "ro_var": "this variable is readonly", "remote_prompt":
"##prompt##:",
"keymap": [{ "key": "^I", "value": "ed-complete" }
]
},
Key definitions by default are listed below.
In vi input mode, input characters are bound to the following editor commands by default:
Ctrl-D, EOF | vi-list-or-eof |
Ctrl-H, BS | vi-delete-prev-char |
Ctrl-J, LF | ed-newline |
Ctrl-M, CR | ed-newline |
Ctrl-Q | ed-tty-start-output |
Ctrl-S | ed-tty-stop-output |
Ctrl-U | vi-kill-line-prev |
Ctrl-V | ed-quoted-insert |
Ctrl-W | ed-delete-prev-word |
Ctrl-[, ESC | vi-command-mode |
Ctrl-, QUIT | ed-tty-sigquit |
Ctrl-?, DEL | vi-delete-prev-char |
All other input characters except the NUL character (Ctrl-@) are bound to ed-insert.
In vi command mode, input characters are bound to the following editor commands by default:
Ctrl-A | ed-move-to-beg |
Ctrl-C, INT | ed-tty-sigint |
Ctrl-E | ed-move-to-end |
Ctrl-H, BS | ed-delete-prev-char |
Ctrl-J, LF | ed-newline |
Ctrl-K | ed-kill-line |
Ctrl-L, FF | ed-clear-screen |
Ctrl-M, CR | ed-newline |
Ctrl-N | ed-next-history |
Ctrl-O | ed-tty-flush-output |
Ctrl-P | ed-prev-history |
Ctrl-Q | ed-tty-start-output |
Ctrl-R | ed-redisplay |
Ctrl-S | ed-tty-stop-output |
Ctrl-U | vi-kill-line-prev |
Ctrl-W | ed-delete-prev-word |
Ctrl-[, ESC | em-meta-next |
Ctrl-, QUIT | ed-tty-sigquit |
Space | ed-next-char |
# | vi-comment-out |
$ | ed-move-to-end |
% | vi-match |
- | ed-next-history |
, | vi-repeat-prev-char |
- | ed-prev-history |
. | vi-redo |
/ | vi-search-prev |
0 | vi-zero |
1 to 9 | ed-argument-digit |
: | ed-command |
; | vi-repeat-next-char |
? | vi-search-next |
@ | vi-alias |
A | vi-add-at-eol |
B | vi-prev-big-word |
C | vi-change-to-eol |
D | ed-kill-line |
E | vi-end-big-word |
F | vi-prev-char |
G | vi-to-history-line |
I | vi-insert-at-bol |
J | ed-search-next-history |
K | ed-search-prev-history |
N | vi-repeat-search-prev |
O | ed-sequence-lead-in |
P | vi-paste-prev |
R | vi-replace-mode |
S | vi-substitute-line |
T | vi-to-prev-char |
U | vi-undo-line |
W | vi-next-big-word |
X | ed-delete-prev-char |
Y | vi-yank-end |
[ | ed-sequence-lead-in |
^ | ed-move-to-beg |
_ | vi-history-word |
a | vi-add |
b | vi-prev-word |
c | vi-change-meta |
d | vi-delete-meta |
e | vi-end-word |
f | vi-next-char |
h | ed-prev-char |
i | vi-insert |
j | ed-next-history |
k | ed-prev-history |
l | ed-next-char |
n | vi-repeat-search-next |
p | vi-paste-next |
r | vi-replace-char |
s | vi-substitute-char |
t | vi-to-next-char |
u | vi-undo |
v | vi-histedit |
w | vi-next-word |
x | ed-delete-next-char |
y | vi-yank |
| | vi-to-column |
~ | vi-change-case |
Ctrl-?, DEL | ed-delete-prev-char |
Meta-O | ed-sequence-lead-in |
Meta-[ | ed-sequence-lead-in |
In emacs mode, input characters are bound to the following editor commands by default:
0 to 9 | ed-digit |
Ctrl-@, NUL | em-set-mark |
Ctrl-A | ed-move-to-beg |
Ctrl-B | ed-prev-char |
Ctrl-C, INT | ed-tty-sigint |
Ctrl-D, EOF | em-delete-or-list |
Ctrl-E | ed-move-to-end |
Ctrl-F | ed-next-char |
Ctrl-H, BS | em-delete-prev-char |
Ctrl-J, LF | ed-newline |
Ctrl-K | ed-kill-line |
Ctrl-L, FF | ed-clear-screen |
Ctrl-M, CR | ed-newline |
Ctrl-N | ed-next-history |
Ctrl-O | ed-tty-flush-output |
Ctrl-P | ed-prev-history |
Ctrl-Q | ed-tty-start-output |
Ctrl-R | ed-redisplay |
Ctrl-S | ed-tty-stop-output |
Ctrl-T | ed-transpose-chars |
Ctrl-U | ed-kill-line |
Ctrl-V | ed-quoted-insert |
Ctrl-W | em-kill-region |
Ctrl-X | ed-sequence-lead-in |
Ctrl-Y | em-yank |
Ctrl-Z, TSTP | ed-tty-sigtstp |
Ctrl-[, ESC | em-meta-next |
Ctrl-, QUIT | ed-tty-sigquit |
Ctrl-] | ed-tty-dsusp |
Ctrl-?, DEL | em-delete-prev-char |
Ctrl-Meta-H | ed-delete-prev-word |
Ctrl-Meta-L | ed-clear-screen |
Ctrl-Meta-_ | em-copy-prev-word |
Meta-0 to 9 | ed-argument-digit |
Meta-B | ed-prev-word |
Meta-C | em-capitol-case |
Meta-D | em-delete-next-word |
Meta-F | em-next-word |
Meta-L | em-lower-case |
Meta-N | ed-search-next-history |
Meta-O | ed-sequence-lead-in |
Meta-P | ed-search-prev-history |
Meta-U | em-upper-case |
Meta-W | em-copy-region |
Meta-X | ed-command |
Meta-[ | ed-sequence-lead-in |
Meta-b | ed-prev-word |
Meta-c | em-capitol-case |
Meta-d | em-delete-next-word |
Meta-f | em-next-word |
Meta-l | em-lower-case |
Meta-n | ed-search-next-history |
Meta-p | ed-search-prev-history |
Meta-u | em-upper-case |
Meta-w | em-copy-region |
Meta-x | ed-command |
Ctrl-Meta-? | ed-delete-prev-word |
The prompt variable is the prompt that the user will see to type at. The remote_prompt is important in that AKA attempts to wait for the remote prompt before letting the user type at the command line. This should make interaction clearer and more intuitive without mixing input and output characters in the input/output terminal data stream.
Other special variables are:
- runuser: The remote run user
- runhost: The fully qualified domain name of the the remote run host
- runhostname: The simple hostname of the remote run host
- runcmd: The command line passed to pbssh
- argv: The command line array passwd to pbssh
- prompt_wait: The maximum time to wait for remote command to run (in milliseconds)
- history: The number of command line history entries to save for the next session
- input: The submitted command line
- prerun_prompt_wait: The maximum time to wait for remote command to run when executing the pre-run as the user session starts (in milliseconds)
- prerun_slowdown: The delay time added to each prerun command to slow down the prerun (in milliseconds)
- remote_prompt: The remote prompt, used by Advanced Keystroke Action profiles to synchronize the terminal session input and output sequences
- akadebug: Built-in debugging to allow the policy writer to diagnose issues in policy
- pkcert: The value of the pk_cert passed into the Advanced Keystroke Action service
- pkserver: The value of the pk_server passed into the Advanced Keystroke Action service
- pkdomain: The value of the pk_domanit passed into the Advanced Keystroke Action service
Note
For more information, see the NetBSD editline(7) man page.
Prerun
The prerun section is an array of string commands that are submitted to the remote system before any user commands can be submitted. It is recommended, if possible, to define prompts, etc, so they can be waited for using remote_prompt variable. The strings are submitted one after another with a short delay, but with not intelligent processing. If processing is required is recommended that normal policy is used.
Example
"prerun": [ "PS1=##prompt##:", "unset PROMPT_COMMAND" ],
Filter
The filter section is an array of strings that are filtered from the session output and are therefore not displayed on the client terminal session.
Example
"filter": [ "Filtered string one", "Filtered string two" ],
Login_sequence
The login sequence object details what happens with a successful or unsuccessful login. It details whether the user is allowed any input during the login phase, the successful/unsuccessful messages and strings that are matched to determine whether it was successful:
Example
"login_sequence" : {
"input_allowed" : true,
"successful" : "*** Login sequence successful ***",
"denied" : "*** Failed login sequence – access denied ***",
"prematch" : [
{"Last login: " : true },
{"Access denied" : false }
]
},
Completion
Completion is a list of strings that can be used to complete command lines (usually when the ed-complete key is submitted). If more than one string can complete the command, the list will be provided. If only one matches, the current command line is rewritten to the completion string. There are two types of completion value. A line completion, where the who line will be compared up to the cursor, and word completion that simply checks the previous word.
Example
"complete": [ {""value": "compabcd", "type" : "line" },{"value" : "compadef", "type" : "line"},{"value": "compxyz","type" : "word" } ],
Macros
Macros are an ordered list of regular expression patterns and rewrite strings. It is used to simply rewrite the current command line if patterns match when return is pressed. This should simplify the majority of policy that are simple rewrites.
Example
"macros": [
{ "pattern": "macroa(b)(c)d", "value": "echo macro rewrites to ${1} ${2}" }
],
When the user types macroabcd, it rewrites the command line to echo macro rewrites to b c, and it executes the command on the remote system.
Readonly
The readonly section is a simple list of variables that are readonly and cannot be rewritten. This is useful for constant strings or messages.
Example
"readonly": {
"ro_var": true
},
Policy
The policy section is an ordered list of matching conditions and actions that are taken if the match is positive. Matching is processed against variables or user input, and can be any normal operation, including regular expressions. Actions can be:
- Accept: Immediately accept the current command line and submit the command line to the remote host to execute.
- Reject: Immediately reject the current command line, optionally displaying a message.
- Restart: Restart processing the policy list from the beginning.
- Readonly: Mark the specified variable readonly for the rest of the session.
- Disable: Execute the current command line, but disable command line processing until either the specified string is matched in the output, or the remote prompt is once again displayed. This allows interactive sessions to be authorized.
- Unset: Unset the specified variable.
- Printf: Display the specified message to the users terminal session, processing specified arguments to make up the message.
- Sendf: Send the specified message to the remote application as if typed, processing specified arguments to make up the input.
- Set: Set the specified variable to a constant or calculated value. Constant values can include any data type, or can reference another variable. Calculated values can be integer or floating point math, shift or logic values, substrings, substituted strings, upper/lower case strings, split or sprint strings. Arguments can be constants or specified variable values, or the arguments matched from the regular expression match.
- Operators on integers include add(+), subtract (-), divide (/), multiply (*), logical AND (&&), bitwise AND (&), logical OR (||), bitwise OR (|), NOT (!), shift left (<<), shift right (>>), modulo divide (%).
- Operators on floating point include add(+), subtract (-), divide (/), multiply (*).
- Operators on strings include concatenation (+), substitute (sub), substring (substr), uppercase (upper), lowercase (lower), split/tokensize string (split) and sprintf to format a string with arguments.
- Operators on arrays include append/extend (+), remove (-) and index set (=).
The match node consists of a singular expression match, or an array of called and or or which are evaluated to a logical AND or OR of the constituent singular expression matches.
Example
"match": { "op": "=", "${var}": "var1", "value": 123 }
Example
"match": { "and" = [
{"op": "=", "var": "${var1}", "value": 123 },
{ "op": "=", "var": "${var2}", "value": 678}
]}
Example
"match": { "or" = [
{"op": "=", "var": "${var1}", "value": 123 },
{ "op": "=", "var": "${var2}", "value": 678}
]}
A simple example of policy
This shows a simple policy where the command line is matched against the user typing PS1=….. If it matches, the command is rejected with a suitable message to the user.
"policy": [
{
"match": {
"op": "=~",
"var": "${input}",
"value": "PS1=.*"
},
"actions": [
{
"action": "reject",
"value": "sorry, you cannot reset the prompt"
}
]
}, ….
Note
For more examples, see the demo policy in the default Advanced Keystroke Action database.
Logging and events
Similarly to EPM-UL session logging, Advanced Keystroke Action sessions can be logged and events collated. The keyword advkeystrokeactionevents yes should be added to pb.settings. By default, the events will be collated in the event database or they can be logged in CSV or JSON to syslog, a normal text file, or sent to a program using the keyword eventdestinations.
Example
An Advanced Keystroke Action log:
{"hostname":"pbuild","evtname":"aka_start_session","service":"pbrunsshaka9.4.4-03_debug","who":"root","severity":16,"utc":"2017-06-23 11:19:00","progname":"pbrunsshaka9.4.4-03_debug","version":"9.4.4-03_debug","arch":"linux.x86-64","data":{"runhost":"cisco1","hostname":"pbuild","pid":23319,"runuser":"admin","sid":23319,"uid":0}}
{"hostname":"pbuild","evtname":"aka_accept_cmd","service":"pbrunsshaka9.4.4-03_debug","who":"root","severity":16,"utc":"2017-06-23 11:19:09","progname":"pbrunsshaka9.4.4-03_debug","version":"9.4.4-03_debug","arch":"linux.x86-64","data":{"hostname":"pbuild","pid":23319,"cmd":"show ip interface brief","sid":23319,"uid":0}}
{"hostname":"pbuild","evtname":"aka_reject_cmd","service":"pbrunsshaka9.4.4-03_debug","who":"root","severity":16,"utc":"2017-06-23 11:19:11","progname":"pbrunsshaka9.4.4-03_debug","version":"9.4.4-03_debug","arch":"linux.x86-64","data":{"hostname":"pbuild","pid":23319,"cmd":"wexit","policy":{"action":"reject"},"sid":23319,"uid":0}}
{"hostname":"pbuild","evtname":"aka_terminate","service":"pbrunsshaka9.4.4-03_debug","who":"root","severity":16,"utc":"2017-06-23 11:19:11","progname":"pbrunsshaka9.4.4-03_debug","version":"9.4.4-03_debug","arch":"linux.x86-64","data":{"hostname":"pbuild","pid":23319,"cmd":"exit","policy":{"action":"terminate"},"sid":23319,"uid":0}}
{"hostname":"pbuild","evtname":"aka_end_session","service":"pbrunsshaka9.4.4-03_debug","who":"root","severity":16,"utc":"2017-06-23 11:19:11","progname":"pbrunsshaka9.4.4-03_debug","version":"9.4.4-03_debug","arch":"linux.x86-64","data":{"status":{"status":0},"hostname":"pbuild","pid":23319,"sid":23319,"uid":0}}
For more information, see Auditing and logging.
Updated 5 days ago