Documentation

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.

  1. Specify the Advanced Keystroke Action Policy Database by adding the keyword advkeystrokeactionpolicydb to the pb.settings on all server hosts.
  2. 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"}'
    
  3. 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:

OptionDescription
-RForce refresh of the client aka profile cache file(s)
argsOptional. The arguments to the function.

Options for Advanced Keystroke Action profile server database management:

OptionDescription
-nCreate new AKA database
-lList 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, EOFvi-list-or-eof
Ctrl-H, BSvi-delete-prev-char
Ctrl-J, LFed-newline
Ctrl-M, CRed-newline
Ctrl-Qed-tty-start-output
Ctrl-Sed-tty-stop-output
Ctrl-Uvi-kill-line-prev
Ctrl-Ved-quoted-insert
Ctrl-Wed-delete-prev-word
Ctrl-[, ESCvi-command-mode
Ctrl-, QUITed-tty-sigquit
Ctrl-?, DELvi-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-Aed-move-to-beg
Ctrl-C, INTed-tty-sigint
Ctrl-Eed-move-to-end
Ctrl-H, BSed-delete-prev-char
Ctrl-J, LFed-newline
Ctrl-Ked-kill-line
Ctrl-L, FFed-clear-screen
Ctrl-M, CRed-newline
Ctrl-Ned-next-history
Ctrl-Oed-tty-flush-output
Ctrl-Ped-prev-history
Ctrl-Qed-tty-start-output
Ctrl-Red-redisplay
Ctrl-Sed-tty-stop-output
Ctrl-Uvi-kill-line-prev
Ctrl-Wed-delete-prev-word
Ctrl-[, ESCem-meta-next
Ctrl-, QUITed-tty-sigquit
Spaceed-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
0vi-zero
1 to 9ed-argument-digit
:ed-command
;vi-repeat-next-char
?vi-search-next
@vi-alias
Avi-add-at-eol
Bvi-prev-big-word
Cvi-change-to-eol
Ded-kill-line
Evi-end-big-word
Fvi-prev-char
Gvi-to-history-line
Ivi-insert-at-bol
Jed-search-next-history
Ked-search-prev-history
Nvi-repeat-search-prev
Oed-sequence-lead-in
Pvi-paste-prev
Rvi-replace-mode
Svi-substitute-line
Tvi-to-prev-char
Uvi-undo-line
Wvi-next-big-word
Xed-delete-prev-char
Yvi-yank-end
[ed-sequence-lead-in
^ed-move-to-beg
_vi-history-word
avi-add
bvi-prev-word
cvi-change-meta
dvi-delete-meta
evi-end-word
fvi-next-char
hed-prev-char
ivi-insert
jed-next-history
ked-prev-history
led-next-char
nvi-repeat-search-next
pvi-paste-next
rvi-replace-char
svi-substitute-char
tvi-to-next-char
uvi-undo
vvi-histedit
wvi-next-word
xed-delete-next-char
yvi-yank
|vi-to-column
~vi-change-case
Ctrl-?, DELed-delete-prev-char
Meta-Oed-sequence-lead-in
Meta-[ed-sequence-lead-in

In emacs mode, input characters are bound to the following editor commands by default:

0 to 9ed-digit
Ctrl-@, NULem-set-mark
Ctrl-Aed-move-to-beg
Ctrl-Bed-prev-char
Ctrl-C, INTed-tty-sigint
Ctrl-D, EOFem-delete-or-list
Ctrl-Eed-move-to-end
Ctrl-Fed-next-char
Ctrl-H, BSem-delete-prev-char
Ctrl-J, LFed-newline
Ctrl-Ked-kill-line
Ctrl-L, FFed-clear-screen
Ctrl-M, CRed-newline
Ctrl-Ned-next-history
Ctrl-Oed-tty-flush-output
Ctrl-Ped-prev-history
Ctrl-Qed-tty-start-output
Ctrl-Red-redisplay
Ctrl-Sed-tty-stop-output
Ctrl-Ted-transpose-chars
Ctrl-Ued-kill-line
Ctrl-Ved-quoted-insert
Ctrl-Wem-kill-region
Ctrl-Xed-sequence-lead-in
Ctrl-Yem-yank
Ctrl-Z, TSTPed-tty-sigtstp
Ctrl-[, ESCem-meta-next
Ctrl-, QUITed-tty-sigquit
Ctrl-]ed-tty-dsusp
Ctrl-?, DELem-delete-prev-char
Ctrl-Meta-Hed-delete-prev-word
Ctrl-Meta-Led-clear-screen
Ctrl-Meta-_em-copy-prev-word
Meta-0 to 9ed-argument-digit
Meta-Bed-prev-word
Meta-Cem-capitol-case
Meta-Dem-delete-next-word
Meta-Fem-next-word
Meta-Lem-lower-case
Meta-Ned-search-next-history
Meta-Oed-sequence-lead-in
Meta-Ped-search-prev-history
Meta-Uem-upper-case
Meta-Wem-copy-region
Meta-Xed-command
Meta-[ed-sequence-lead-in
Meta-bed-prev-word
Meta-cem-capitol-case
Meta-dem-delete-next-word
Meta-fem-next-word
Meta-lem-lower-case
Meta-ned-search-next-history
Meta-ped-search-prev-history
Meta-uem-upper-case
Meta-wem-copy-region
Meta-xed-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.


©2003-2025 BeyondTrust Corporation. All Rights Reserved. Other trademarks identified on this page are owned by their respective owners. BeyondTrust is not a chartered bank or trust company, or depository institution. It is not authorized to accept deposits or trust accounts and is not licensed or regulated by any state or federal banking authority.