Managing user and group properties from command line

User and Group Properties

Aside from globally configured properties that apply to the entire server and all its users and groups, there are properties that can be set specifically on specific users and groups. In the example commands given in the documentation, <USER_OR_GROUP> indicates where you can specify either one of these:

  1. A user name
  2. A group name
  3. __DEFAULT__

The name __DEFAULT__ (two underscores on both sides of the capitalized word DEFAULT) is a special reserved keyword that serves as a place where base properties can be defined that other users and groups can inherit. This opens up certain possibilities for user accounts - existing and yet to be created - to be automatically assumed to have certain properties set, like the ability to use auto-login type connection profiles and other properties, without this being specified specifically on a user. If a property is defined on multiple levels then the order of preference from highest priority to lowest priority is exactly as shown above in the numbered list. That is, user first, then group, then the __DEFAULT__ reserved name. Here are some common tasks:

Show the current properties for all users:

./sacli UserPropGet

Show the current properties for a specific user or group:

./sacli --pfilt <USER_OR_GROUP> UserPropGet

Enable for a user or group the auto-login privilege:

./sacli --user <USER_OR_GROUP> --key "prop_autologin" --value "true" UserPropPut

Disable the auto-login privilege for a user or group:

./sacli --user <USER_OR_GROUP> --key "prop_autologin" --value "false" UserPropPut

Remove the auto-login property from a user or group:

./sacli --user <USER_OR_GROUP> --key "prop_autologin" UserPropDel

Remove all properties (this deletes the user or group):

./sacli --user <USER_OR_GROUP> UserPropDelAll

Add a new user from scratch:

./sacli --user <USER_NAME> --key "type" --value "user_connect" UserPropPut

Create a new group from scratch:

./sacli --user <GROUP_NAME> --key "type" --value "group" UserPropPut
./sacli --user <GROUP_NAME> --key "group_declare" --value "true" UserPropPut

Add a user to a group:

./sacli --user <USER_NAME> --key "conn_group" --value "<GROUP_NAME> UserPropPut

Remove a user from a group:

./sacli --user <USER_NAME> --key "conn_group" UserPropDel

Set password for a user in local authentication mode:

./sacli --user <USER_NAME> --new_pass <PASSWORD> SetLocalPassword

There are a couple of important notes and caveats about the above. The above are just some examples, it is not a complete listing of everything that is possible with sacli.

In general whenever there is a single property set on a user, the user will automatically exist in the system. For example if you merely set the auto-login property (prop_autologin) either false or true on a user that didn't exist, then the user will automatically exist from that point on. The same goes for any user specific property. Of course the user must also exist in the authentication system behind it in order to be able to login, and it depends on your chosen authentication system on how to setup a password and possibly an account for that user in the chosen authentication back-end.

Properties work with inheritance. For example, if you enable the auto-login property on a group, then users in that group will have the privilege to download an auto-login type configuration file. If you specifically deny the auto-login property on a user in that group, then users in that group will be able to get an auto-login type configuration file, except that user. If neither the user nor the group have anything specified in the auto-login property, then it will be inherited from __DEFAULT__, which by default has the value "false".

Groups need a subnet to work with. It can either be a global subnet that is configured in the VPN Settings page or in the server's global configuration database, or it can be a subnet that is defined specifically for the group. More information about that can be found elsewhere in the documentation. Without a valid subnet to draw IP addresses from, users assigned to a group tend to end up with one of the standard addresses from the globally configured dynamic IP address pool.

Many commands you can give with sacli will write changes to the configuration databases that stores all the settings, but they may not take effect immediately. In order to make the changes take effect the configuration of the running servers must be refreshed. To do this use the sacli start command. This is a command designed to only refresh or restart components that need it. Additionally, if you make changes that may require a connected user to be disconnected and reconnected, the Access Server may issue a 'kick' command to such a connected client to force it to disconnect and reconnect and obtain the correct settings from the server.

Refresh the configuration of the Access Server:

./sacli start

Assign a user a static IP address

Before you are able to use this function you should have a static IP address network configured. By default the Access Server is not configured with a static IP address network. As is usual all subnets you use must be unique, so when you go to configure this subnet, make sure to make it different from anything else you have in use. If the user you want to assign a static IP address is part of a group, you must assign a static IP address to the user that falls within the subnet of the assigned group. If the group doesn't have a subnet yet, you must assign it first in order to be able to use static IP addressing on a user in a group. If the user is not part of a group the default static IP address network as configured in the Admin UI under "VPN Settings" must be used instead.

If you were using groups before but didn't specifically have subnets assigned to groups, then users assigned to a group will dynamically be allocated an address from the "Group Default IP Address Network (optional)" as configured in the Admin UI under "VPN Settings". Using static IP addressing on a user in a group means you must assign a subnet to that group. Such a subnet is only for static assignment and forces all users in the group to use IP addresses from the group subnet. The second subnet field under "Group Permissions" is designed to specify a dynamic allocation range for users in a group that do not get a static IP address assigned.

OpenVPN Access Server uses the start IP address and the end IP address of the subnet you want to use for static IP address assignment for itself. If you have the subnet 192.168.70.0/24 configured for static IP addressing then 192.168.70.1 and 192.168.70.254 are reserved by the Access Server itself and those IP addresses must not be used for static IP assignment to users. Addresses in the example subnet that are valid are 192.168.70.2 all the way through to 192.168.70.253. One final note about IP addressing space is that due to the way IP addressing and access control works internally in Access Server there will be a certain 'waste' of IP addressing space. In other words the Access Server can run out of assignable addresses even though the entire subnet has not yet been used up by connected VPN clients. The Access Server is more efficient with static IP addressing space if you use groups with different subnets instead of a global static IP address network. However given the fact that there are millions of addresses in private IP address space this should not pose any problems. There are more caveats with IP addressing space but for static IP address assignment these are the most important items to consider.

Assign a default static IP addressing network for users not part of a group:

./sacli --key "vpn.server.static.0.network" --value <SUBNET> ConfigPut
./sacli --key "vpn.server.static.o.netmask_bits --value <CIDR> ConfigPut

Assign a primary subnet for static IP addressing space to a group:

./sacli --user <GROUP_NAME> --key "group_subnets.0" --value <SUBNET/CIDR> UserPropPut

Assign a user a static IP address:

./sacli --user <USER_NAME> --key "conn_ip" --value <IP_ADDRESS> UserPropPut

In the above examples if we assume we want to configure 192.168.70.0/24 as the subnet to use, then SUBNET is 192.168.70.0 and CIDR is 24. In the case of SUBNET/CIDR it is written as simply 192.168.70.0/24.

Disconnect (kick) a user

If for whatever reason you need to force a user to drop its connection to the Access Server, you can do so using the sacli DisconnectUser function. It is possible to kick a user off the server with an invitation to reconnect again with the existing session token it may have. It's also possible to send a string of text to the VPN client which should be shown on screen or in the log that gives a reason why the user was kicked off the server. If a user has multiple active OpenVPN tunnels it is unfortunately not possible to specify a single VPN tunnel for that user to kick; it's all or nothing.

Disconnect all VPN connections for a given user name:

./sacli --user <USER_NAME> DisconnectUser

Disconnect all VPN connections for a given user name, with a reason:

./sacli --user <USER_NAME> --client_reason <TEXT> DisconnectUser

Disconnect all VPN connections for a given user name, with an invitation to auto-reconnect:

./sacli --user <USER_NAME> --restart --psid DisconnectUser

When you provide parameters to the sacli command like for example a text for the --client-reason you should enclose it with double quotes. For example "You have been disconnected by Johan". Spaces tend to upset command line programs but when a string of text is enclosed with double quotes it will work correctly.

Some clients and configurations will attempt to automatically reconnect no matter what method is used to kick a user off the VPN server. If you want the user to stay disconnected in such a situation you can additionally set the prop_deny property on the user to true. This effectively bans the user from the server.

Block (ban) a user

With the prop_deny property you can deny access to users. You can lift this restriction at any time. This is a property that can be set on a user name, a group name, or the pseudo name __DEFAULT__ and can be inherited. The user will still remain present in the Access Server with all its settings and certificates retained, but the user will simply be unable to login on the web services or make a VPN connection to the Access Server. If the user is currently connected to the Access Server then banning the user will not disconnect this user, but will only preventing the user from making a new connection or logging in to the web interface. You can use the sacli DisconnectUser function to kick any existing connections.

Deny future logins for a user or group:

./sacli --user <USER_OR_GROUP> --key "prop_deny" --value "true" UserPropPut

Specifically allow future logins for a user or group:

./sacli --user <USER_OR_GROUP> --key "prop_deny" --value "false" UserPropPut

Removing the property will restore the user to defaults and have it adhere to any inheritance:

./sacli --user <USER_OR_GROUP --key "prop_deny" UserPropDel

Grant or revoke Admin Privileges

Admin privileges let the user log on to the Admin UI of the Access Server. It is important to note that we advise that you use user accounts that have admin privileges only for administration of the OpenVPN Access Server. While user accounts that have admin privileges can be used for VPN connections, they can have special access to subnets configured that may upset inheritance of properties from groups like access control rules. So if you experience a problem where an admin user in a normal group does not receive certain routes or access to specific subnets, then that may be the reason why. Usually putting normal user in normal groups, and putting admin users in admin groups, is okay, but mixing admin users in normal groups and putting normal users in admin groups may cause some issues with access control. The Access Server will then always choose the safe path and leave out access to certain subnets rather than giving normal users access to subnets only admin users should be given access to, for example.

To give a user or group the admin privilege:

./sacli --user <USER_OR_GROUP> --key "prop_superuser" --value "true" UserPropPut

To specifically revoke from a user or group the admin privilege:

./sacli --user <USER_OR_GROUP> --key "prop_superuser" --value "false" UserPropPut

Removing the property will restore the user or group to defaults and have it adhere to any inheritance:

./sacli --user <USER_OR_GROUP> --key "prop_superuser" UserPropDel

Auto-login profiles

Connection profiles of the auto-login type allow automatic connection without requiring user input. This means this connection profile contains everything it needs to make a connection and does not require credentials to establish a VPN tunnel. The connection profile contains embedded in it a client certificate and a private key that are unique and belong to this specific user account and is known at the Access Server as being allowed to make a connection in this way. The prop_autologin property can be set on the __DEFAULT__ pseudo name, a group name, or a user name, and can be inherited. The default situation is that the OpenVPN Access Server does not have the prop_autologin property defined anywhere, and it is then by default assumed to be denied.

To give a user or group the auto-login privilege:

./sacli --user <USER_OR_GROUP> --key "prop_autologin" --value "true" UserPropPut

To specifically revoke from a user or group the auto-login privilege:

./sacli --user <USER_OR_GROUP> --key "prop_autologin" --value "false" UserPropPut

Allow all users in a group to use auto-login connection profiles:

./sacli --user <GROUP_NAME> --key "prop_autologin" --value "true" UserPropPut

Allow all users to use auto-login connection profiles by default:

./sacli --user "__DEFAULT__" --key "prop_autologin" --value "true" UserPropPut

Deny all user to use auto-login connection profiles by default:

./sacli --user "__DEFAULT__" --key "prop_autologin" UserPropDel

Removing the property will restore the user or group to defaults and have it adhere to any inheritance:

./sacli --user <USER_OR_GROUP> --key "prop_autologin" UserPropDel

Compression settings

In the Admin UI under "Advanced VPN" it's possible to enable or disable compression support. Compression support can enhance the connection speed depending on circumstances and data transferred. In most cases it has a positive impact on the transfer speed. However even when it is enabled or disabled in "Advanced VPN" globally, it can be overridden specifically for users or group using the prop_lzo property shown in the examples below. This does not by the way limit the Access Server to using only the LZO compression method, but the property name is just a hold-over from when LZO was the only compression method available in OpenVPN at the time. If you delete the property from the user or group, it will adhere to the global default set under "Advanced VPN".

Enable compression for a given user or group:

./sacli --user <USER_OR_GROUP> --key "prop_lzo" --value "true" UserPropPut

Disable compression for a given user or group:

./sacli --user <USER_OR_GROUP> --key "prop_lzo" --value "false" UserPropPut

Redirect-gateway and DNS settings

Redirect-gateway is the directive name in the OpenVPN protocol that instructs a VPN client to send all its traffic through the VPN tunnel to the VPN server. In the Admin UI under "VPN Settings" it's possible to enable the option to have connected VPN clients send the Internet traffic through the OpenVPN Access Server globally, as well as configure pushing DNS servers to the VPN clients. Usually both are done to ensure DNS queries can be resolved, as some providers block queries to their DNS servers from non-local sources. It can be overridden specifically for users or groups using the prop_reroute_gw_override property shown in the examples below. If you delete the property from the user or group, it will adhere to the global defaults set under "VPN Settings".

It is not possible to push a specific DNS server to a specific user or group. The DNS servers that are pushed are set globally, and only the act of pushing it to a user or group can be switched on or off. Additionally, if you want to redirect client Internet traffic through the Access Server without implementing DNS for a specific user or group you can use the trick of disabling the option to redirect client Internet traffic through the server in the VPN Settings page and then go to the settings for that user or group and give access via NAT method to the subnets 0.0.0.0/1 and 128.0.0.0/1.

Disable redirection of Internet traffic, and don't push DNS servers:

./sacli --user <USER_OR_GROUP> --key "prop_reroute_gw_override" --value "disable" UserPropPut

Disable redirection of Internet traffic, but still push DNS servers:

./sacli --user <USER_OR_GROUP> --key "prop_reroute_gw_override" --value "dns_only" UserPropPut

Use the settings as defined under VPN settings specifically:

./sacli --user <USER_OR_GROUP> --key "prop_reroute_gw_override" --value "global" UserPropPut

Removing the property will restore the user or group to defaults and have it adhere to any inheritance:

./sacli --user <USER_OR_GROUP> --key "prop_reroute_gw_override" UserPropDel

Redirect Internet traffic for a user, but don't push DNS servers:

./sacli --user <USER_NAME> --key "type" --value "user_compile" UserPropPut
./sacli --user <USER_NAME> --key "access_to.0" --value "+NAT:0.0.0.0/1" UserPropPut
./sacli --user <USER_NAME> --key "access_to.1" --value "+NAT:128.0.0.0/1" UserPropPut

Redirect Internet traffic for a group, but don't push DNS servers:

./sacli --user <GROUP_NAME> --key "access_to.0" --value "+SUBNET:0.0.0.0/1" UserPropPut
./sacli --user <GROUP_NAME> --key "access_to.1" --value "+SUBNET:128.0.0.0/1" UserPropPut

Please note that in the last two examples where we're implementing 0.0.0.0/1 and 128.0.0.0/1 routes we're assuming that there are not already other access control rules present on the user or group. If there are, use the next available configuration keys (.2, .3, .4 etc) to add these rules. It's also important to note that in the command line it is possible to mix NAT and route rules, but in the Admin UI this is currently not possible. That means if you set up mix NAT and route rules on the same user or the same group, and you next go to the Admin UI and change settings there, they will be reset to the settings defined in the Admin UI (ie: all NAT or all route).

You may also notice the property user_compile on the user. The default for a standard user is user_connect when the user has no access control rules of itself. In such a case the user can just join the VPN client subnet and the server won't have to setup any special rules for this user. But when you assign specific access control rules to a user, the server must be told to set up special rules the moment this user connects. For that purpose the property user_compile is used.

Specify a client-side script

In the Admin UI you're limited to specifying a client-side script on a group, and then assigning users to those groups. There is no more granularity than that in the Admin UI when it comes to client-side scripting. However on the command line you can set a script on a usergroup, or the __DEFAULT__ special keyword from which the default properties for users and groups are inherited.

Load an on-connect client-side script for Windows platform:

./sacli --user <USER_OR_GROUP> --key "prop_cli.script.win.user.connect" --value-file "./windows-on-connect.txt" UserPropPut

Load an on-connect client-side script for Macintosh platform:

./sacli --user <USER_OR_GROUP> --key "prop_cli.script.mac.user.connect" --value-file "./macintosh-on-connect.txt" UserPropPut

Load an on-connect client-side script for Linux platform:

./sacli --user <USER_OR_GROUP> --key "prop_cli.script.linux.user.connect" --value-file "./linux-on-connect.txt" UserPropPut

Load an on-connect client-side script for all three platforms:

./sacli --user <USER_OR_GROUP> --key "prop_cli.script.all.user.connect" --value-file "./all-on-connect.txt" UserPropPut

Remove an on-connect client-side script of the four types shown above - note that this does not stop inheriting scripts from a higher level:

./sacli --user <USER_OR_GROUP> --key "prop_cli.script.win.user.connect" UserPropDel
./sacli --user <USER_OR_GROUP> --key "prop_cli.script.mac.user.connect" UserPropDel
./sacli --user <USER_OR_GROUP> --key "prop_cli.script.linux.user.connect" UserPropDel
./sacli --user <USER_OR_GROUP> --key "prop_cli.script.all.user.connect" UserPropDel

Load an on-disconnect client-side script for Windows platform:

./sacli --user <USER_OR_GROUP> --key "prop_cli.script.win.user.disconnect" --value-file "./windows-on-disconnect.txt" UserPropPut

Load an on-disconnect client-side script for Macintosh platform:

./sacli --user <USER_OR_GROUP> --key "prop_cli.script.mac.user.disconnect" --value-file "./macintosh-on-disconnect.txt" UserPropPut

Load an on-disconnect client-side script for Linux platform:

./sacli --user <USER_OR_GROUP> --key "prop_cli.script.linux.user.disconnect" --value-file "./linux-on-disconnect.txt" UserPropPut

Load an on-disconnect client-side script for all three platforms:

./sacli --user <USER_OR_GROUP> --key "prop_cli.script.all.user.disconnect" --value-file "./all-on-disconnect.txt" UserPropPut

Remove an on-disconnect client-side script of the four types shown above - note that this does not stop inheriting scripts from a higher level:

./sacli --user <USER_OR_GROUP> --key "prop_cli.script.win.user.disconnect" UserPropDel
./sacli --user <USER_OR_GROUP> --key "prop_cli.script.mac.user.disconnect" UserPropDel
./sacli --user <USER_OR_GROUP> --key "prop_cli.script.linux.user.disconnect" UserPropDel
./sacli --user <USER_OR_GROUP> --key "prop_cli.script.all.user.disconnect" UserPropDel

Setting a client-side environment variable

This can be set in the Admin UI only on a group via the Group Permissions page. But in the command line you can set it per group or per user individually. This is meant to push variables to the client program which will be made available to the client-side script as specified in the section above.

Example of setting variable "username" to "elfredy" on the client:

./sacli --user <USER_OR_GROUP> --key "prop_cli.script_env.win.username" --value "elfredy" UserPropPut

As with client-side scripting, you can adjust the "win" to "mac", "linux", or "all", to specify if this should apply to Windows, Macintosh, Linux, or all three of them. In the above example, the key name itself contains the name of the variable. So if you want to specify a variable name "myvariable" then change "username" to "myvariable" in the above example.

To remove the variable setting shown above:

./sacli --user <USER_OR_GROUP> --key "prop_cli.script_env.win.username" UserPropDel