Security

Security Rules

To prevent malicious clients from attacking Union Server using built-in commands such as "remove room" and "remove account", Union Server provides fine-grained controls over client privileges. An administrator can, for example, specify that a room can be removed by the client that created it only, or that no client is allowed to remove any room.

Setting Remote Client Rules

For the purposes of Union Server security discussions, a "remote client" is any client that connects to the server through a non-admin gateway. To limit a remote client's ability to perform actions on the server, set "remote client security rules" in the server's union.xml file.

A security rule consists of a security action and a number of security roles. The "action" describes what the remote client wants to do (e.g., remove a room). The "role" describes the client's level of privilege (e.g., moderator). Roles defined in a rule are additive. That is, a client can be both a moderator and a room owner, and have the combined privileges of both roles.

If a rule contains no roles, then no remote clients are permitted to perform the action. If an action is omitted from union.xml, then no remote clients are permitted to perform that action. Both server code (i.e. server modules and room modules) and clients connected to the admin gateway are allowed to perform all actions regardless of the security rules.

Security Actions

Union Server defines the following security actions.

CREATE_ROOM - Create a room.
JOIN_ROOM - Join a room.
MODIFY_ROOM_SETTING - Set, update, or remove a room setting (eg. _DIE_ON_EMPTY).
MODIFY_ROOM_ATTRIBUTE - Set, update, or remove a room attribute.
REMOVE_ROOM - Remove a room.
ROOMLIST_ACCESS - Access the list of rooms on the server.
ROOMINFO_ACCESS - Access information about a room (eg. get a snapshot or observe a room).
MODIFY_CLIENT_ATTRIBUTE - Set, update, or remove a client attribute.
SEND_MESSAGE_TO_CLIENT - Send a message to a client.
SEND_MESSAGE_TO_ROOM - Send a message to a room.
SEND_MESSAGE_TO_SERVER - Send a message to the server.
CREATE_ACCOUNT - Create an account.
REMOVE_ACCOUNT - Remove an account.
SEND_ROOM_MODULE_MESSAGE - Send a room module message.
SEND_SERVER_MODULE_MESSAGE - Send a server module message.
CLIENTLIST_ACCESS - Access the list of clients on the server.
CLIENTINFO_ACCESS - Access information about a client (eg. get a snapshot or observe a client).
LOGIN - Login a client.
LOGOFF - Logoff a client.
ADD_ROLE - Add a role to a client (eg. make a client a moderator).
REMOVE_ROLE - Remove a role from a client (eg. remove moderator role from a client).
BAN - Ban an address from the server.
UNBAN - Remove a ban from an address (i.e. allow clients to connect from that address).
GET_BANNED_LIST_SNAPSHOT - Get a list of all banned addresses.
WATCH_FOR_BANNED_ADDRESSES - Get updates when the list of banned addresses changes.
KICK_CLIENT - Kick a client from the server.
ACCOUNTLIST_ACCESS - Access the list of accounts on the server.
ACCOUNTINFO_ACCESS - Access information about an account.
MODULE_ACCESS - Access the list of modules and the server and clear the module cache.
UPC_ACCESS - Access to UPC message stats and UPC messages being processed on the server.
NODELIST_ACCESS - Access to the list of nodes on the server.

Security Roles

Union Server defines the following security roles:

ALL - All clients are allowed to perform the action.
SELF - The client can perform the action on itself.
USER - A logged in client can perform the action.
MODERATOR - A moderator can perform the action.
ROOM_OWNER - The room owner can perform the action on the room.(1)
ROOM_OCCUPANT - A room occupant can perform the action on the room.(1)
ROOM_OBSERVER - A room observer can perform the action on the room.(1)

(1) - These roles have a room context and the role of a client will depend on the room (i.e. a client could be a ROOM_OWNER of chat.sports but have no room role in chat.hobbies because they are neither the owner, nor an occupant, nor an observer of the room).

Defining rules with union.xml

Rules are defined as follows:

<rule>
    <action>SECURITY_ACTION</action>
    <roles>ROLE1, ROLE2, ....</role>
</rule>

The <roles> element is a comma-delimited list of roles that can perform the specified action. Leaving the <roles> element blank prevents all remote clients from performing the action.

Defining Rules Programmatically

Rules can be set programmatically through the net.user1.union.api.Security interface, referenced from net.user1.union.api.Server, using the method setPermission(SecurityAction, SecurityRole). Since all server code is considered trusted, modules can use the various check* methods to determine if an action would be permitted under the current security rules.

Security Rule Examples

Example

    <security>
        <remote-client-rules>
            <rule>
                <action>CREATE_ROOM</action>
                <roles>USER</roles>
            </rule>
            <rule>
                <action>JOIN_ROOM</action>
                <roles>ALL</roles>
            </rule>
            <rule>
                <action>REMOVE_ROOM</action>
                <roles>ROOM_OWNER, MODERATOR</roles>
            </rule>
                <rule>
                <action>SEND_MESSAGE_TO_ROOM</action>
                <roles>MODERATOR, ROOM_OCCUPANT, ROOM_OWNER</roles>
            </rule>
            <rule>
                <action>REMOVE_ACCOUNT</action>
                <roles></roles>
            </rule>
        </remote-client-rules>
    </security>
  • Only users (clients that are logged in) are allowed to create rooms.
  • All clients are allowed to join rooms.
  • Only the owner of the room or a moderator are allowed to remove the room. A room will still be removed if it is empty and set to die on empty.
  • Only a moderator, an occupant of the room, or the room owner can send a message to the room.
  • No clients are allowed to remove an account.

Example

Only room occupants and room observers are allowed to modify room attributes for the room.

server.getSecurity().setPermission(SecurityAction.MODIFY_ROOM_ATTRIBUTE, SecurityRole.ROOM_OCCUPANT, SecurityRole.ROOM_OBSERVER);

Example

Check if a client can create accounts.

        try {
            server.getSecurity().checkCreateAccount(client);
            // client can create accounts
        } catch (UnionSecurityException e) {
            // client cannot create accounts
        }

Banning an Address

Each client connected to the server is identified by an address. For the common case of a socket connection the address is the IP of the remote client. This address can be banned from connecting to the server.

To ban a client use the net.user1.union.api.Security class.

Example

        server.getSecurity().banClient("1.2.3.4", BanInterval.FOREVER, "DOS attack");

Ban the address "1.2.3.4" forever from connecting to the server.

Example

        server.getSecurity().banClient(client.getAddress(), 240, "Connecting too often.";);

Ban the given client for 240 seconds.

Example

        server.getSecurity().unbanClient("1.2.3.4");

Unban the address "1.2.3.4".

Example

        boolean isBanned = server.getSecurity().isBanned("1.2.3.4");

Check if the address "1.2.3.4" is banned from the server.

Connection Refusal Notification

If a connection to the server is refused (eg. banned) the server can be configured to send a u164 (CONNECTION_REFUSED) indicating to the client the reason for refusal. Only a u164 will be sent after which the connection will be disconnected. The connection must first send a u65 (CLIENT_HELLO) so that the communication protocol can be identified. Connections that do not send a u65 will be disconnected after 15 seconds.

Note: connection refusal notification is not currently supported for websocket connections.

Configuring Connection Refusal in union.xml

Configuration for connection refusal is as follows within the <security> element:

1
2
3
4
<connect_refusal_recipients>
    <recipient>group1</recipient>
    <recipient>group2</recipient>
</connect_refusal_recipients>

If a refused connection matches at least one group in the recipient list the u164 will be sent. If the connection_refusal_recipients element is missing or no recipients are specified then no connections will receive a u164.

Valid group values are:

temporarily_banned (if the refusal reason is BANNED and the ban is temporary)
permanently_banned (if the refusal reason is BANNED and the ban is permanent)

Connection Refusal Example

With the following configuration in union.xml:

1
2
3
<connect_refusal_recipients>
    <recipient>temporarily_banned</recipient>
</connect_refusal_recipients>

If a connection is made to the server that is banned but the ban is not permanent the connection will receive a u164 with a reason of BANNED and a description providing details about the duration and reason for the ban. If a connection is made to the server that is permanently banned then no u164 will be sent.