Scriptable configuration with BssCfg
Bitvise SSH Server comes with a textual configuration utility called 'BssCfg' which is useful for administering SSH servers in large-scale installations, where text-based configuration is desired or where very many accounts need to be configured at the same time in a semi-automated fashion. BssCfg also allows remote server administration from client machines where it is not possible to use Bitvise SSH Client and its Remote Control Panel feature.
Note: Everything that can be configured through BssCfg can also be configured through the graphical Bitvise SSH Server Control Panel, and vice versa. Users who don't need scriptable configuration do not need to learn BssCfg. Such users should simply use the graphical settings, accessed through the Bitvise SSH Server Control Panel.
The BssCfg utility resides in the SSH server installation directory and will normally be run from the Windows command prompt (either locally or remotely in an SSH session). If run without parameters, it will show the options with which it can be used. This section will focus on interactive use, specifically when BssCfg is started with 'BssCfg settings importText -i'. This mode allows the user to inspect and manipulate Bitvise SSH Server settings dynamically. The interactive session is ended by either committing any changes that have been made (using 'commit'), or by discarding them using 'abort' or 'quit'. Commands such as these are executed in BssCfg like in a Windows command prompt.
In interactive mode, BssCfg supports two types of commands for interaction and management of settings:
- Queries: queries are used to inspect the current value of a setting or a hierarchy of settings, and they are always prefixed with 'q '. The 'q'
prefix makes it clear to BssCfg that you desire to inspect a certain
value or set of values, not to change them. Example query:
This query displays settings configured in the Access Control > Windows Groups section of Bitvise SSH Server Advanced settings.
- Instructions: instructions look similar to queries, however the absence of a 'q ' prefix tells BssCfg that you desire to change the value of a particular setting, and there is a suffix specifying the desired value of the
setting. Example instruction:
access.winGroups.(group eqi "Domain Users").permitSftp false
This instruction turns off SFTP access for the Windows group named 'Domain Users'.
Note that in non-interactive mode ('BssCfg settings importText' without the '-i' parameter), BssCfg will accept only instructions. Queries are interpreted only in an interactive context.
Getting started. Now would be a good time to look at example usage of the BssCfg utility. This example illustrates how BssCfg can be used to configure a command to be run automatically whenever a user logs into Bitvise SSH Server. The example also illustrates how special types of queries - ending in '?' or '*' - can be used to learn more about the settings hierarchy, or to get the current settings values of a subset (or the whole) of this hierarchy.
Commands entered by the user in this example are prefixed with '> '. All other text appearing in the example is output by the BssCfg utility.
Try executing the following commands yourself to start exploring:
Backslashes in strings
Setting string values through BssCfg requires additional attention. Strings use standard C-like escaping to allow representation of non-printable characters and control codes. Like in C, the escape character is the backslash ('\'), and if the backslash itself is desired (i.e. in a Windows path), it needs to be escaped by entering a double-backslash. Example of an escaped string instruction:
access.winGroups.(group eqi "Domain Users").sfsMap.mountPoints.(sfsMountPath eqi "/").realRootPath "C:\\Temp\\SFTP"
This will set the "Real root path" setting for the default mount point of the "Domain Users" group to C:\Temp\SFTP.
Adding new accounts and groups
Accounts and groups are stored internally in sorted lists. Some of the fields in each list entry are the entry's sort key; when you do a query ending in '.?', these fields are displayed with a '>' prefix. Other fields in each list entry may have a unique constraint placed on them; such fields will be marked with a '!' prefix in the results of a query ending in '.?'. For example, Windows accounts are sorted according to the value of their 'winDomain' and 'winAccount' fields. On the other hand, Windows groups are sorted according to their 'priority' field, and the values of the 'groupType', 'winDomain' and 'group' fields must be unique.
New account and group entries are added in two steps:
- First, the entry is initialized with the new settings it will contain. In this step, it is referred to with the keyword 'New', for example:
- Then, when the initial data for the new list entry is configured, it is committed into the list:
This process also applies to all other items which are stored in sorted lists.
Accessing sorted list entries
Sorted list entries such as accounts and groups can be accessed using test expressions:
q access.winAccounts.(winAccount eq "SheilaB").*
This will query the settings for the Domain\SheilaB account. The 'eq' keyword is a string equality operator. The 'eq' operator is case sensitive. However in most cases it is better to use case insensitive string comparison, as follows:
q access.winAccounts.(winAccount eqi "sheilab").*
Here the 'eq' has been replaced with 'eqi', which will match regardless of the case.
There are also operators for numeric comparison:
access.winAccounts.(winAccount eqi "sheilab").srvSideFwding.s2c.(listenPort == 5554).listenPort 5555
This changes the listening port to 5555 for the first S2C forwarding entry defined for SheilaB's account where the listening port was previously 5554.
A list of operators valid in test expressions can be obtained by issuing the simplest query: 'q'.
Removing sorted list entries
Accounts and groups can be removed from their sorted lists as follows:
access.winAccounts.Erase(winAccount eqi "sheilab")
This will remove the account settings entry for Domain\SheilaB's account. However, if your test expression matches multiple entries, all of them will be removed. If this is a problem, query the sorted list for the ID of the entry in advance:
From this output (which is similar to but more concise than .*), we may learn that Domain\SheilaB's account entry is number 31. Therefore, we might remove this specific entry as follows:
Help for other list operations can be obtained by querying a sorted list with '?':
Blocking IP addresses
In order to block a large number of IP addresses, you can use "BssCfg settings importText" to import a text file with instructions such as these:
access.clientAddresses.Clear access.clientAddresses.New.addressRule.addressType IPv4 access.clientAddresses.New.addressRule.ipv4 10.2.3.4 access.clientAddresses.New.addressRule.sigBitsIpv4 32 access.clientAddresses.New.instr.allowConnect false access.clientAddresses.NewCommit access.clientAddresses.New.addressRule.addressType AnyIP access.clientAddresses.New.instr.allowConnect true access.clientAddresses.NewCommit
These instructions will:
- Clear the list of rules in Advanced settings > Access control > Client address rules.
- Add a rule to block connections from the IPv4 address 10.2.3.4, identified with all 32 bits.
- Add a final rule to allow connections from other IP address.
If you run into any problems or need help with the BssCfg utility, feel free to contact us. Your questions will help us augment this guide so that answers to your questions, as well as solutions to any problems, will be readily available.