(9.2+) Securing your Callback installation

Use the following guides to enhance the security of your On-PremiseCallback installation in version 9.2 and higher.

Callback ports

The following ports are used by Callback components:

Application namePortDescriptionDirection
Agent Priority for AEP2850Used by the Agent Priority APIInbound
Authorization API2800Used by the Authorization APIInbound
Configuration Management 8001Used by the Configuration Management APIInbound
Erlang (epmd.exe)4369The Erlang Port Mapper Daemon (epmd.exe) listens on this portInbound
Erlang (erl.exe, werl.exe)Contiguous range of at least 1000 portsUsed for dynamically assigning listening sockets for each Erlang virtual machine (erl.exe, werl.exe) on which they will listen for incoming communications from other nodesInbound & outbound
IIS

80 (http used)

443 (https used)

Web server used by On-PremiseCallback softwareInbound
IVRUsually dynamically setControls the IVR ports for the Interactive Voice Response portion of On-PremiseCallback softwareOutbound
License Management 8002Used by the License ManagerInbound
Management API8000Used by the System Management API.Inbound
Management Gateway8012Passes licensing information between the user web page and the licensing database.Inbound
Message Bus2136Communication layer between QueueManager and various On-PremiseCallback Software web services, allowing information to be sent to and retrieved from QueueManagerInbound
Notification Server25Used for System Management email notificationsInbound
Operation Mode (OpMode) Server9100Service responsible for sending Operation Mode changes based on schedule to Queue ManagerInbound
Queue Manager9999Core component of On-PremiseCallback ApplicationInbound
Queue Statistics API2900Used by the Stats API for Queue StatisticsInbound
RabbitMQ

BEST PRACTICE

Version 9.1.0 utilizes RabbitMQ and an older version of jQuery (lower than jQuery 3.5.x). To resolve issues with RabbitMQ, disable the RabbitMQ management plugin.

To disable the RabbitMQ management plugin, run the following command on all Callback servers:

{Virtual Hold Directory}\RabbitMQ Server\rabbitmq_server-3.8.1\sbin\rabbitmq-plugins disable rabbitmq_management

15672Used by the System Management API, Notification Server, Platform ToolKit, Peripheral Monitor, and Core MonitorInbound

5672

5671

Used by AMQP 0-9-1 and 1.0 clients with and without TLS.
25672Used for inter-node and CLI tools communication.
Real-Time Adapter6999Used by On-PremiseCallbacksoftware to acquire real-time information from the systemInbound
SQL Server1433Server running the MS SQL instance containing the VHT_Config and VHT_RPT databasesInbound

Third party application ports

Application namePortDescription
Cisco Application Gateway9000Default port for Cisco App Gateway communication.
Cisco PG_A42027Default port for Cisco-to-peripheral gateway communication.
Cisco PG_B43027Default port for Cisco-to-peripheral gateway communication.
Genesys SIP Server7000Default port for Genesys SIP communication.
SMTP Server25Default SMTP port for email communication.
TSAPI Client451Default port for TSAPI communication.

HTTPS protocol support

On-Premise Callback can be configured to use the HTTPS protocol for secure network communication with its web applications. Use the following procedures to copy certificates and enable Callback components and web services to communicate using HTTPS.

Overview

This guide covers the following steps:

  • Create a certificate and install Nginx
  • Configure Internet Information Services (IIS)
  • Configure Nginx
  • Configure On-Premise Callback
  • Restart Callback components

Create a certificate

  • For information on the certificate required for installation, see the following resources from Nginx:
  • For testing environments, you can create a self-sign certificate by following the steps below:
    • On each Management server, open IIS Manager
    • Navigate to Server Certificates
    • Select Self-Signed Certificate action and follow prompts
    • Export the created certificate

Install Nginx

Use the following instructions to copy certificates andwork with NGINX.

Copying the certificate, creating the cert and key for NGINX

Follow these steps to copy the certificate.

  • Open IIS Manager andnavigate to server certificates. Right-click on the certificate, and export itto a .pfxfile.

Note the exportpath and password used.Theywill be referenced later.

  • Install the OpenSSL Windows client:
  • Open a command prompt from the bin folder where the SSL Client was installed and enter the following:
openssl pkcs12 -in Input.pfx -clcerts -nokeys -out vht_callback_ssl.crt 
 openssl pkcs12 -in Input.pfx -nocerts -nodes -out vht_callback_ssl.key 

Where Inputis the name and file path of the pfx file. Verify the files use the naming convention vht_callback_ssl.crt and vht_callback_ssl.key

See the following example for reference:

openssl pkcs12 -in "C:\user\TLS 1.2\cert.pfx" -clcerts -nokeys -out vht_callback_ssl.crt

If the path contains a space, enclose the path and filename in quotes.

  • Note the directory where the files in Step 3 were created.

Installing, configuring, and running NGINX

Mindful Professional Services provide a single zip file with all components necessary for installing NGINX and running it as a Windows service. Within this package, NGINX is already configured for a normal Callback system.

Contact Mindful Support or Professional Services for the NGINX package.

  • Copy the NGINX zip fileto the Management Instance.
  • Unzip the file to the directory where Callback is installed. This creates a folder called proxy with several subfolders. Do NOT modify any of the unzipped files.
  • Create new directory named logs directory under proxy\nginx.
  • Copy the certificates created in Copying the certificate, creating the cert and key for NGINX to the \proxy\nginx\confdirectory.
    • Verify the files use the naming convention vht_callback_ssl.key and vht_callback_ssl.crt.

Naming these files incorrectly or copying them to the wrong folder prevents NGINX from working.

  • Navigate to the install_path\VirtualHoldTechnology\proxy\bin folder and open a command prompt window.
  • Run the following command to install the VHT Reverse Proxy:
nginx_windows_service.cmd install

The command only contains the single argument install.

  • On Core servers, run the \proxy\dependencies\install_dependencies.cmd script via the command line with Administrator permissions.
  • After installing the VHTReverse Proxy, start it using the Windows Services control panel.
  • Import the certificate to Trusted Root on each Callback server

Removing NGINX

If you need to remove NGINX at a later time, navigate to the install_path\VirtualHoldTechnology\proxy\binfolder, open a command prompt, and run the following command:

nginx_windows_service.cmd uninstall

Configure Internet Information Services (IIS)

  • Edit the site binding of port 80 to 127.0.0.1
  • Remove the binding for port 443

bindings

Configure Nginx

  • Copy and unzip the proxy package to the Virtual Hold Technology directory on Management servers (\\Program Files (x86)\Virtual Hold Technology by default).
  • In the nginx.conf file, modify the cors_origin_header mappings to list each management FQDN:
map $http_origin $cors_origin_header { default ""; "~*(^https://)(<server01>\.<domain>\.com$)" "$http_origin"; "~*(^https://)(<server02>\.<domain>\.com$)" "$http_origin"; }

Note that the dots (.) in the FQDNs use escape characters (\.). This format must be followed for the configuration to work as expected.

Configure On-Premise Callback

  • Update the VHQMWSPATH registry key at HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Virtual Holdas follows:
    • If Core and Management are on same server: VHQMWSPATH = http://127.0.0.1/VHQMWS/VHQMWS.asmx
    • If Core is not on same server as Management: VHQMWSPATH = https://<PROXY_FQDN>/VHQMWS/VHQMWS.asmx
  • In the VHT_Config database, in the WSConfiguration table, update the WSPath field in both rows as follows:
http://127.0.0.1/VHACDConfigWS/VHACDConfigWS.asmx http://127.0.0.1/VHSysConfigWS/VHSysConfigWS.asmx

database example

  • Update the following configuration files for On-Premise Callback components:
  • Configuration Management (\\Virtual Hold Technology\ConfigurationManagement\site.config):
auth_api_url,"http://127.0.0.1:2800"
  • Dashboards Auth API (\\Virtual Hold Technology\Dashboard\vht_auth_api-config.yml):
:host: '127.0.0.1'
  • Dashboards Stats API (\\Virtual Hold Technology\Dashboard\vht_stats_api-config.yml):
:host: '127.0.0.1' :ws_host: '127.0.0.1'
  • Management API (\\Virtual Hold Technology\Management API\site.config):
auth_api_url,"http://127.0.0.1:2800"
  • Notification Server (\\Virtual Hold Technology\Notification Server\site.config):
{url, "http://127.0.0.1/VHTPlatformWS-v5/VHTPlatformWS.asmx"} {url, "http://127.0.0.1/EyeQueue/NoAccessPage"}
  • Configuration Wizard (\\Virtual Hold Technology\VHT_ConfigurationWizard.exe.config):
<setting name="VHT_ConfigurationWizard_VHQMWS_WebRef_VHQMWS" serializeAs="String"> <value>http://127.0.0.1/VHQMWS/VHQMWS.asmx</value> </setting>
  • Smart Rules Engine service (\\SmartRules\VHT_SmartRulesEngineService.exe.config):

Locate the <system.serviceModel> section in the VHT_SmartRulesEngineService.exe.config file. Before the update, it should look like this:

<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="VHQWatchWSSoap" maxReceivedMessageSize="2147483647"/>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/VHQWatchWS/VHQWatchWS.asmx" binding="basicHttpBinding" bindingConfiguration="VHQWatchWSSoap" contract="VHQWatchWSReference.VHQWatchWSSoap" name="VHQWatchWSSoap"/>
</client>
</system.serviceModel>

Replace the <system.serviceModel> section with the following:

<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webBindingHttps">
<security mode="Transport"/>
</binding>
<binding name="webBinding">
<security mode="Transport"></security>
</binding>
</webHttpBinding>
<basicHttpBinding>
<binding name="VHQWatchWSSoap" closeTimeout="00:05:00" openTimeout="00:05:00" receiveTimeout="00:25:00" sendTimeout="00:05:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="10485760" maxBufferPoolSize="524288" maxReceivedMessageSize="10485760" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="65536"></readerQuotas>
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""></transport>
<message clientCredentialType="UserName" algorithmSuite="Default"></message>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://[SERVER_FQDN]/VHQWatchWS/VHQWatchWS.asmx" binding="basicHttpBinding" bindingConfiguration="VHQWatchWSSoap" contract="VHQWatchWSReference.VHQWatchWSSoap" name="VHQWatchWSSoap"/>
</client>
</system.serviceModel>
  • Configuration Translation API (\\Virtual Hold Technology\VirtualHoldPub\ConfigurationTranslationAPI\Web.config):
<setting name="VHQMWS" serializeAs="String">
    <value>http://127.0.0.1/VHQMWS/VHQMWS.asmx</value>
</setting>
<setting name="AuthAPI" serializeAs="String">
    <value>https://PROXY_FQDN/auth</value>
</setting>
<setting name="LicenseAPIUrl" serializeAs="String">
    <value>https://PROXY_FQDN/mgmt</value>
</setting>
  • EyeQueue URL (\\Virtual Hold Technology\VirtualHoldPub\EyeQueue\EyeQueue.url):
URL=https://<PROXY_FQDN>/EyeQueue
  • EyeQueue (\\Virtual Hold Technology\VirtualHoldPub\EyeQueue\web.config): View the content for your specific version below.

NOTE

The value of the ConversationBridgeURL key differs for version 9.5.3+ compared to prior versions. The difference is highlighted in the following examples.

EyeQueue web.config for 9.5.3 and higher

Make the following update for version 9.5.3 and higher only.

<add key="QStatsURL" value="http://127.0.0.1/VHQWatch/AjaxQueueStats.aspx"></add>
<add key="ClassicLineStatusURL" value="http://127.0.0.1/VHQWatch/AjaxLineStatus.aspx"></add>
<add key="ModernLineStatusURL" value="http://127.0.0.1/VHQWatch/AjaxLineSnapShot.aspx"></add>
<add key="VHGlobalConfigWS.VHGlobalConfigWS" value="http://127.0.0.1/VHGlobalConfigWS/VHGlobalConfigWS.asmx"></add>
<add key="VHQWatchWS.VHQWatchWS" value="http://127.0.0.1/VHQWatchWS/VHQWatchWS.asmx"></add>
<add key="VHQMWS.VHQMWS" value="http://127.0.0.1/VHQMWS/VHQMWS.asmx"></add>
<add key="ConversationBridgeAuthURL" value="https://PROXY_FQDN/auth"></add>
<add key="ConversationBridgeURL" value="/launchpad"></add>
<add key="InternalConversationBridgeURL" value="http://127.0.0.1/"></add>
<system.serviceModel>
    ...
    <client>    
        <endpoint address="http://127.0.0.1/VHQMWS/VHQMWS.asmx" binding="basicHttpBinding" bindingConfiguration="VHQMWSSoap" contract="VHQMWS.VHQMWSSoap" name="VHQMWSSoap"></endpoint>
    </client>
</system.serviceModel>    
<setting name="EyeQ_VHGlobalConfigWS_VHGlobalConfigWS" serializeAs="String">
    <value>http://127.0.0.1/VHGlobalConfigWS/VHGlobalConfigWS.asmx&lt;/value>
</setting>
<setting name="EyeQ_VHQMWS_VHQMWS" serializeAs="String">
    <value>http://127.0.0.1/VHQMWS/VHQMWS.asmx&lt;/value>
</setting>
<setting name="EyeQ_VHQWatchWS_VHQWatchWS" serializeAs="String">
    <value>http://127.0.0.1/VHQWatchWS/VHQWatchWS.asmx&lt;/value>
</setting>

EyeQueue web.config for 9.2.0 to 9.5.2

Make the following update for version 9.2.0 to 9.5.2 only.

<add key="QStatsURL" value="http://127.0.0.1/VHQWatch/AjaxQueueStats.aspx"></add>
<add key="ClassicLineStatusURL" value="http://127.0.0.1/VHQWatch/AjaxLineStatus.aspx"></add>
<add key="ModernLineStatusURL" value="http://127.0.0.1/VHQWatch/AjaxLineSnapShot.aspx"></add>
<add key="VHGlobalConfigWS.VHGlobalConfigWS" value="http://127.0.0.1/VHGlobalConfigWS/VHGlobalConfigWS.asmx"></add>
<add key="VHQWatchWS.VHQWatchWS" value="http://127.0.0.1/VHQWatchWS/VHQWatchWS.asmx"></add>
<add key="VHQMWS.VHQMWS" value="http://127.0.0.1/VHQMWS/VHQMWS.asmx"></add>
<add key="ConversationBridgeAuthURL" value="https://PROXY_FQDN/auth"></add>
<add key="ConversationBridgeURL" value="https://PROXY_FQDN/launchpad"></add>
<add key="InternalConversationBridgeURL" value="http://127.0.0.1/"></add>
<system.serviceModel>
    ...
    <client>    
        <endpoint address="http://127.0.0.1/VHQMWS/VHQMWS.asmx" binding="basicHttpBinding" bindingConfiguration="VHQMWSSoap" contract="VHQMWS.VHQMWSSoap" name="VHQMWSSoap"></endpoint>
    </client>
</system.serviceModel>    
<setting name="EyeQ_VHGlobalConfigWS_VHGlobalConfigWS" serializeAs="String">
    <value>http://127.0.0.1/VHGlobalConfigWS/VHGlobalConfigWS.asmx&lt;/value>
</setting>
<setting name="EyeQ_VHQMWS_VHQMWS" serializeAs="String">
    <value>http://127.0.0.1/VHQMWS/VHQMWS.asmx&lt;/value>
</setting>
<setting name="EyeQ_VHQWatchWS_VHQWatchWS" serializeAs="String">
    <value>http://127.0.0.1/VHQWatchWS/VHQWatchWS.asmx&lt;/value>
</setting>
  • VHCallbackResponse web service (\\Virtual Hold Technology\VirtualHoldPub\VHCallbackResponse\web.config):
<add key="VHQMWS.VHQMWS" value="http://127.0.0.1/VHQMWS/VHQMWS.asmx"></add>
<setting name="VHCallbackResponse_VHQMWS_VHQMWS" serializeAs="String">
    <value>http://127.0.0.1/VHQMWS/VHQMWS.asmx</value>
</setting>
  • VHQMWS web service (\\Virtual Hold Technology\VirtualHoldPub\VHQMWS\web.config):
<add key="VHACDWS.VHACDConfigWS" value="http://127.0.0.1/VHACDConfigWS/VHACDConfigWS.asmx"></add>
<add key="VHGlobalWS.VHGlobalConfigWS" value="http://127.0.0.1/VHGlobalConfigWS/VHGlobalConfigWS.asmx"></add>
<add key="VHSysWS.VHSysConfigWS" value="http://127.0.0.1/VHSysConfigWS/VHSysConfigWS.asmx"></add>
<setting name="VHQMWS_VHACDWS_VHACDConfigWS" serializeAs="String">
    <value>http://127.0.0.1/VHACDConfigWS/VHACDConfigWS.asmx</value>
</setting>
<setting name="VHQMWS_VHGlobalWS_VHGlobalConfigWS" serializeAs="String">
    <value>http://127.0.0.1/VHGlobalConfigWS/VHGlobalConfigWS.asmx</value>
</setting>
<setting name="VHQMWS_VHSysWS_VHSysConfigWS" serializeAs="String">
    <value>http://127.0.0.1/VHSysConfigWS/VHSysConfigWS.asmx</value>
</setting>
  • VHQWatch web service (\\Virtual Hold Technology\VirtualHoldPub\VHQWatch\web.config):
<add key="VHQWatchWS.VHQWatchWS" value="http://127.0.0.1/VHQWatchWS/VHQWatchWS.asmx"></add>
<setting name="VHQWatch_VHQWatchWS_VHQWatchWS" serializeAs="String">
    <value>http://127.0.0.1/VHQWatchWS/VHQWatchWS.asmx</value>
</setting>
  • For each of the following files, update the specified references, if present:
Configuration filesReferences to update
  • \\Virtual Hold Technology\VirtualHoldPub\...
    • ConfigurationManagement\settings.js
    • dashboards\settings.js
    • launchpad\settings.js
    • LegacyReports\settings.js
    • LegacyUsers\settings.js
    • Licensing\settings.js
    • SystemManagement\settings.js
    • SmartRulesEngineUi\settings.js
  • References of :2800 to /auth
  • References of :2900 to /stats
  • References of :8000 to /system
  • References of :8001 to /config
  • References of :8002 to /license
  • References of :8012 to /mgmt

Restart Callback components

After the previous procedures are completed on each Management server, restart Callback servers for the changes to take effect. The services start automatically when Callback starts. If the server cannot be restarted, restart each Callbackservice on each server.

Ports used in Callback with SSL/NGINX

When using NGINX hosting on port 8080, the Auth Service(2800), Stats Service(2900), Management API(8000), and Configuration Management(8001) all host locally 127.0.0.1 on their respective ports. However with NGINX introduced as a reverse proxy, these services listed above are all hosted on SSL port 8080. IIS would also have a new port used instead of 80, the default SSL port being 443.

Application NamePortVersionPurposeConfigurable
Queue Manager9999N/ACore component of the Callback applicationNot recommended
Operation Mode (OpMode) Server9100N/AService responsible for sending Operation Mode changes based on schedule to Queue ManagerNot recommended
Message Bus2136N/ACommunication layer between QueueManager and various web services, allowing information to be sent to and retrieved from QueueManager
IIS4436 or 7Web server used by Virtual HoldY
SQL Server14332008 R2,2012 (8.8.x or later),2014 (8.8.x or later)Server running the MS SQL instance containing the VHT_Config and VHT_RPT databasesY
IVRControls the IVR ports for the Interactive Voice Response portion of Callback
Auth API

8080 (NGINX-SSL)

2800 (locally)

N/AUsed by the Authorization API (127.0.0.1:2800)Y
Stats API

8080(NGINX-SSL)

2900 (locally)

N/AUsed by the Stats API (127.0.0.1:2900)Y
Management API

8080(NGINX-SSL)

8000 (locally)

N/AUsed by the System Management API (127.0.0.1:8000)Y
License Manager

8080 (NGINX-SSL)

8002 (locally

N/A

Used by the License Manager API

(127.0.0.1:8002

Y
Configuration Management (8.1 and higher)

8080(NGINX-SSL)

8001 (locally)

N/AUsed by the Configuration Management API (127.0.0.1:8001)Y
Notification Server25N/AUsed for System Management email notificationsY
Erlang (empd.exe)4369The Erlang Port Mapper Daemon (epmd.exe) listens on this portN - This is an Erlang standard port number and should not be changed.
Erlang (erl.exe, werl.exe)Contiguous range of at least 1000 portsN/AUsed for dynamically assigning listening sockets for each Erlang virtual machine (erl.exe, werl.exe) on which they will listen for incoming communications from other nodesY - Ideally above 49152.

Adding X-Frame-Options headers to Launchpad/Eyequeue

You can add X-Frame-Options headers to the Eyequeue web.config file to incorporate best-practice security guidelines. To add these headers, follow the steps below.

  • Open the Eyequeue web.config file for editing (located at \\Virtual Hold Technology\VirtualHoldPub\EyeQueue\web.config by default).
  • Add an X-Frame-Options custom header by adding the following element into the existing <system.webServer> element:
<httpProtocol>
    <customHeaders>
        <add name="X-Frame-Options" value="SAMEORIGIN" />
    </customHeaders>
</httpProtocol>
  • Save the web.config file.
  • Restart the Eyequeue Application Pool in IIS, then reload Launchpad/Eyequeue.

Example

The following example shows a complete <system.webServer> element with the X-Frame-Options header added:

...
<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="X-Frame-Options" value="SAMEORIGIN" />
        </customHeaders>
    </httpProtocol>
    <validation validateIntegratedModeConfiguration="false"></validation>
    <handlers accessPolicy="Read, Script">
        <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit"></remove>
        <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit"></remove>
        <remove name="ExtensionlessUrlHandler-Integrated-4.0"></remove>
        <remove name="svc-ISAPI-2.0"></remove>
        <remove name="svc-Integrated"></remove>
        <add name="svc-ISAPI-2.0" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%SystemRoot%\
Microsoft.Net\Framework\v2.0.50727\aspnet_isapi.dll" resourceType="Unspecified" preCondition="classicMode,
runtimeVersionv2.0,bitness32"></add>
        <add name="svc-Integrated" path="*.svc" verb="*" type="System.ServiceModel.Activation.HttpHandler, 
System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" resourceType="Unspecified" 
preCondition="integratedMode"></add>
    </handlers>
    <directoryBrowse enabled="false"></directoryBrowse>
    <defaultDocument>
        <files>
            <clear></clear>
            <add value="Login.aspx"></add>
        </files>
    </defaultDocument>
    <httpErrors>
        <clear></clear>
    </httpErrors>
</system.webServer>
...

TLS 1.2 support

TLS 1.2 support for SQL 2012

Transport Layer Security (TLS) 1.2 for Callback requires updates to Windows, SQL Server, and Callback configuration. Use the following instructions to enable TLS 1.2 with SQL Server 2012.

Before you begin

Verify the correct versions of Windows, IIS, SQL server, and additional components have been downloaded and installed from Microsoft. Use the following table to identify the correct versions of each:

Windows versionWindows 2012 (64-bit) and Windows 2012 R2 (64-bit)
IIS6, 7, 8 and 8.5 (with Windows 2012 R2)
Framework.NET Framework 4.6.1, 4.6.2 and 4.7.0
SQL ServerMS SQL Server 2012 SP3 GDR (11.0.6216.27) TLS 1.2
SQL Server DriverOne that supports TLS 1.2
Command Line UtilitiesSupplied by Microsoft for the driver

Updating Windows

  • Ensure compatible versions of Windows and IIS are currently installed. Refer to the Compatibility and Integration Matrix to determine the correct version numbers.
  • Add/change the following registry settings to disable .NET using SSL3, TLS 1.0, and TLS 1.1:
    • Set HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\ v4.0.30319\SchUseStrongCrypto to dword:00000001.
    • Set HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319\SchUseStrongCrypto to dword:00000001.
  • Restart Windows.

Upgrading Callback configuration and database

Callback can be configured to use Object Linking and Embedding (OLE) or Open Database Connectivity (ODBC) to communicate with the SQL reporting database (default value of VHT_RPT) within Callback.

IMPORTANT

If using Erlang, you must configure Callback to use both OLE and ODBC if you want to configure other components with OLE.

To configure for OLE access:

  • Configure the Management API, Core Monitor, and Configuration Manager site.config files to use the desired driver:
    • Set the Driver option to {driver, "<SQL_Driver_Name>"}. where SQL_Driver_name is usually SQL Server Native Client 11.0.
  • Edit the ReportDBConnectionString variable in the VHT_Config > ApplicationSettings table similar to the following example:
Provider=SQLNCLI11;Data Source=Pi3;Initial Catalog=VHT_RPT;persist security info=False;User ID=sa;Password=Pass123For OLE DB Windows Authentication:Provider=SQLNCLI11;Data Source=Pi3;Initial Catalog=VHT_RPT;Integrated Security=SSPI;persist security info=False...

To configure for ODBC access:

  • Configure the Management API, Core Monitor, and Configuration Manager site.config files to use the desired driver:
    • Set the Driver option to {driver, "<SQL_Driver_Name>"}. where SQL_Driver_name is usually SQL Server Native Client 11.0.
  • Restart all Virtual Hold services.

TLS 1.2 support for SQL 2016

Transport Layer Security (TLS) 1.2 for Callback requires updates to Windows, SQL Server, and Callback configuration. Use the following instructions to enable TLS 1.2 with SQL 2016.

Before you begin

Verify the correct versions of Windows, IIS, SQL server, and additional components have been downloaded and installed from Microsoft. Use the following table to identify the correct versions of each:

Windows versionWindows 2016 64-bit
IIS10
Framework.NET Framework 4.7.0 or 4.7.1
SQL ServerMS SQL Server 2016 (Enterprise or Standard edition)
SQL Server DriverOne that supports TLS 1.2
Command Line UtilitiesSupplied by Microsoft for the driver

Updating Windows

Upgrading Callback configuration and database

Callback can be configured to use Object Linking and Embedding (OLE) or Open Database Connectivity (ODBC) to communicate with the SQL reporting database (default value of VHT_RPT) within Callback.

IMPORTANT

If using Erlang, you must configure Callback to use both OLE and ODBC if you want to configure other components with OLE.

To configure for OLE access:

  • Configure the Management API, Core Monitor, and Configuration Manager site.config files to use the desired driver:
    • Set the Driver option to {driver, "<SQL_Driver_Name>"}. where SQL_Driver_name is usually SQL Server Native Client 11.0.
  • Edit the ReportDBConnectionString variable in the VHT_Config > ApplicationSettings table similar to the following example:
For OLE DB SQL Server Authentication:Provider=SQLNCLI11;Data Source=Pi3;Initial Catalog=VHT_RPT;persist security info=False;User ID=sa;Password=Pass123For OLE DB Windows Authentication:Provider=SQLNCLI11;Data Source=Pi3;Initial Catalog=VHT_RPT;Integrated Security=SSPI;persist security info=False...

To configure for ODBC access:

  • Configure the Management API, Core Monitor, and Configuration Manager site.config files to use the desired driver:
    • Set the Driver option to {driver, "<SQL_Driver_Name>"}. where SQL_Driver_name is usually SQL Server Native Client 11.0.
  • Restart all Virtual Hold services.

TLS 1.2 support for SQL 2017

Transport Layer Security (TLS) 1.2 for Callback requires updates to Windows, SQL Server, and Callback configuration. Use the following instructions to enable TLS 1.2 with SQL 2017.

Before you begin

Verify the correct versions of Windows, IIS, SQL server, and additional components have been downloaded and installed from Microsoft. Use the following table to identify the correct versions of each:

Windows versionWindows 2017 64-bit
IIS10
Framework.NET Framework 4.7.0, 4.7.1, or 4.7.2
SQL ServerMS SQL Server 2017 (Enterprise or Standard edition)
SQL Server DriverOne that supports TLS 1.2
Command Line UtilitiesSupplied by Microsoft for the driver

Updating Windows

Upgrading Callback configuration and database

Callback can be configured to use Object Linking and Embedding (OLE) or Open Database Connectivity (ODBC) to communicate with the SQL reporting database (default value of VHT_RPT) within Callback.

IMPORTANT

If using Erlang, you must configure Callback to use both OLE and ODBC if you want to configure other components with OLE.

To configure for OLE access:

  • Configure the Management API, Core Monitor, and Configuration Manager site.config files to use the desired driver:
    • Set the Driver option to {driver, "<SQL_Driver_Name>"}. where SQL_Driver_name is usually SQL Server Native Client 11.0.
  • Edit the ReportDBConnectionString variable in the VHT_Config > ApplicationSettings table similar to the following example:
For OLE DB SQL Server Authentication:Provider=SQLNCLI11;Data Source=Pi3;Initial Catalog=VHT_RPT;persist security info=False;User ID=sa;Password=Pass123For OLE DB Windows Authentication:Provider=SQLNCLI11;Data Source=Pi3;Initial Catalog=VHT_RPT;Integrated Security=SSPI;persist security info=False...

To configure for ODBC access:

  • Configure the Management API, Core Monitor, and Configuration Manager site.config files to use the desired driver:
    • Set the Driver option to {driver, "<SQL_Driver_Name>"}. where SQL_Driver_name is usually SQL Server Native Client 11.0.
  • Restart all Virtual Hold services.

(9.2 - 9.5.3) Securing your RabbitMQ connection for High Availability solutions

NOTE

You can secure your RabbitMQ connection for a High Availability deployment by adding the certificate details to the RabbitMQ site.config file, and updating the URI for each RabbitMQ federation upstream.

BEFORE YOU BEGIN

  • Securing RabbitMQ connections needs to be performed when On-PremiseCallback is turned off.
  • Verify you have access to the following certificates for RabbitMQ and its clients:
    • ca_certificate.pem
    • server_certificate.pem
    • server_key.pem
    • cert.p12
    • client_key.p12
    • client_certificate.pem
    • client_key.pem

BEST PRACTICE

Version 9.1.0 utilizes RabbitMQ and an older version of jQuery (lower than jQuery 3.5.x). To resolve issues with RabbitMQ, disable the RabbitMQ management plugin.

To disable the RabbitMQ management plugin, run the following command on all Callback servers:

{Virtual Hold Directory}\RabbitMQ Server\rabbitmq_server-3.8.1\sbin\rabbitmq-plugins disable rabbitmq_management

Certificates without a Common Name

IMPORTANT

These certificates must be full chain certificates with the client key, intermediate key, and the CA/root key. They cannot be password protected.

To verify, check the client_cert.p12 file with the following command and see if a password prompt occurs:

openssl pkcs12 -in client_cert.12 -info -nokeys -passin pass

Certificates without a common name

Step 1: Updating the rabbitmq.config

First, update {rabbit} section of the rabbitmq_config.json. The default location of the file is C:\Program Files (x86)\Virtual Hold Technology\RabbitMQ Server.

EXAMPLE:

[
    {rabbit, [
         {log_levels, [connection,debug]}, 
         {ssl_cert_login_from, common_name},
         {tcp_listeners, []},
         {auth_mechanisms, ['EXTERNAL']},
         {ssl_listeners, [5671]},
         {ssl_options, [
                    {cacertfile, "[cert_location]/ca_certificate.pem"},
                    {certfile,   "[cert_location]/server_certificate.pem"},
                    {keyfile,    "[cert_location]/server_key.pem"},
                    {verify, verify_peer},
                    {depth, 2},
                    {versions, ['tlsv1.2']},
                    {fail_if_no_peer_cert, true}]}
   ]}
].
ValueDescriptionDefault
{log_levels, [connection,debug]}Sets the log level to debug to troubleshoot SSL issues.[connection,debug]
{ssl_cert_login_from, common_name}Used if the generated certificate has a Common Name (CN)N/A
{tcp_listeners, []}Disables the standard RabbitMQ communications port of 5672N/A
{auth_mechanisms, ['EXTERNAL']}Required for SSL.['EXTERNAL']
{ssl_listeners, [5671]}Sets the ssl port for rabbit, must match the port in rabbit_config.json5671
{verify, verify_peer}
  • Set to verify_peer - the client does send us a certificate, the node must perform peer verification.
  • Set to verify_none - peer verification will be disabled and certificate exchange won't be performed.
verify_peer
{depth, 2}Indicates the maximum number of non-self-issued intermediate certificates that may follow the peer certificate in a valid certification path. This can be removed if not needed.2
{versions, ['tlsv1.2']}Explicitly disables all but the TLS 1.2 protocol for RabbitMQ communications.N/A

Step 2: Updating the rabbitmq_config.json

You will also need to update the {rabbitConfig} section with the certificate information. The default location of the file is C:\Program Files (x86)\Virtual Hold Technology.

EXAMPLE:

{
    "rabbitConfig": {
        "sslEnabled": true, 
        "sslServerName": "{server_name}",
        "sslVersion": "Tls12",
        "certPathP12": "[cert_location]\\cert.p12",
        "keyFileP12": "[cert_location]\\client_key.p12",
        "caCertFile": "[cert_location]\\ca_certificate.pem",
        "certFile": "[cert_location]\\client_certificate.pem",
        "keyFile":  "[cert_location]\\client_key.pem",
        "hostname": "{server_shortname or fqdn}",
        "port": 5671,
        "vHost": "/"
    }
}
ValueDescriptionDefault
sslEnabled
  • Set to true to enable SSL
  • Set to false to disable SSL
false
sslServerNameSSL server name.The server name can either be shortname of fully-qualified domain name (FQDN).NA
sslVersionThe current supported version of TLS, should be configured to Tls12.Tls12
sslServerNamessl server name can be short name or FQDNNA
hostnameLocal server hostnameNA
portThe port should match the ssl_listeners in the rabbitmq config if configuring for ssl, or tcp_listeners listeners.Otherwise it should be configured to 56725671
vHostConfigure to "/""/"

Step 3: Getting the Federation Upstream names

When enabling TLS on a VHT Callback cluster, the following URI will need to be edited and added to each federation upstream:

  • Navigate to localhost:15672 > admin > federation upstream
  • Use the Name of each Upstream in Step 3 when you update the URI string.

federation upstreams

Step 4: Updating the URI string

Use a command line to update the URI string for each RabbitMQ federation upstream

  • Open an administrator command line at VIRTUAL HOLD INSTALL DIRECTORY\RabbitMQ Server\rabbitmq_server-3.8.1\sbin
  • Run the following command:
rabbitmq-plugins enable rabbitmq_auth_mechanism_ssl
  • Run the following command replacing the [URI string] with the URI string in the URI STRING EXAMPLE.
rabbitmqctl set_parameter federation-upstream [federation_upstream_name] ^ "{""uri"":""[URI_STRING]"",""expires"":300000, ""max-hops"":1, ""ack-mode"":""on-confirm"", ""trust-user-id"":false}"

Where:

  • [federation_upstream_name] - Name of the upstream
  • [URI_STRING] - URI string created using the URI String example

URI STRING EXAMPLE:

amqps://[servershorname]?cacertfile=[dir of certificate]/ca_certificate.pem&certfile=[dir of certificate]/client_certificate.pem&keyfile=[dir of certificate]/client_key.pem&verify=verify_peer&server_name_indication=[servershorname]&auth_mechanism=external

Where:

  • [servershortname] - The shortname of the server that the connection is being made to
  • [dir of certificate] - Directory of the corresponding certificate

Step 5: Restart Callback

Perform a restart of VHT Callback in order for the changes to take effect.

ADDITIONAL RESOURCES

Certificates with a common name

IMPORTANT

These certificates must be full chain certificates with the client key, intermediate key, and the CA/root key. They cannot be password protected.

To verify, check the client_cert.p12 file with the following command and see if a password prompt occurs:

openssl pkcs12 -in client_cert.12 -info -nokeys -passin pass

Step 1: Updating the rabbitmq.config

First, update {rabbit} section of the rabbitmq_config.json. The default location of the file is C:\Program Files (x86)\Virtual Hold Technology\RabbitMQ Server.

EXAMPLE:

[
    {rabbit, [
         {log_levels, [connection,debug]}, 
         {ssl_cert_login_from, common_name},
         {tcp_listeners, []},
         {auth_mechanisms, ['EXTERNAL']},
         {ssl_listeners, [5671]},
         {ssl_options, [
                    {cacertfile, "[cert_location]/ca_certificate.pem"},
                    {certfile,   "[cert_location]/server_certificate.pem"},
                    {keyfile,    "[cert_location]/server_key.pem"},
                    {verify, verify_peer},
                    {depth, 2},
                    {versions, ['tlsv1.2']},
                    {fail_if_no_peer_cert, true}]}
   ]}
].
ValueDescriptionDefault
{log_levels, [connection,debug]}Sets the log level to debug to troubleshoot SSL issues.[connection,debug]
{ssl_cert_login_from, common_name}Used if the generated certificate has a Common Name (CN)N/A
{tcp_listeners, []}Disables the standard RabbitMQ communications port of 5672N/A
{auth_mechanisms, ['EXTERNAL']}Required for SSL.['EXTERNAL']
{ssl_listeners, [5671]}Sets the ssl port for rabbit, must match the port in rabbit_config.json5671
{verify, verify_peer}
  • Set to verify_peer - the client does send us a certificate, the node must perform peer verification.
  • Set to verify_none - peer verification will be disabled and certificate exchange won't be performed.
verify_peer
{depth, 2}Indicates the maximum number of non-self-issued intermediate certificates that may follow the peer certificate in a valid certification path. This can be removed if not needed.2
{versions, ['tlsv1.2']}Explicitly disables all but the TLS 1.2 protocol for RabbitMQ communication.N/A

Step 2: Updating the rabbitmq_config.json

You will also need to update the {rabbitConfig} section with the certificate information. The default location of the file is C:\Program Files (x86)\Virtual Hold Technology.

EXAMPLE:

{
    "rabbitConfig": {
        "sslEnabled": true, 
        "sslServerName": "{server_name}",
        "sslVersion": "Tls12",
        "certPathP12": "[cert_location]\\cert.p12",
        "keyFileP12": "[cert_location]\\client_key.p12",
        "caCertFile": "[cert_location]\\ca_certificate.pem",
        "certFile": "[cert_location]\\client_certificate.pem",
        "keyFile":  "[cert_location]\\client_key.pem",
        "hostname": "{server_shortname or fqdn}",
        "port": 5671,
        "vHost": "/",
        "serverNameIndication": "CN={CommonName}"
    }
}
ValueDescriptionDefault
sslEnabled
  • Set to true to enable SSL
  • Set to false to disable SSL
false
sslServerNameSSL server name.The server name can either be shortname of fully-qualified domain name (FQDN).NA
sslVersionThe current supported version of TLS, should be configured to Tls12.Tls12
sslServerNamessl server name can be short name or FQDNNA
hostnameLocal server hostnameNA
portThe port should match the ssl_listeners in the rabbitmq config if configuring for ssl, or tcp_listeners listeners.Otherwise it should be configured to 56725671
vHostConfigure to "/""/"
serverNameIndicationThe Common Name of the certificateNA

Step 3: Getting the Federation Upstream names

When enabling TLS on a VHT Callback cluster, the following URI will need to be edited and added to each federation upstream:

  • Navigate to localhost:15672 > admin > federation upstream
  • Use the Name of each Upstream in Step 3 when you update the URI string.

federation upstreams

Step 4: Updating the URI string

Use a command line to update the URI string for each RabbitMQ federation upstream.

  • Open an administrator command line at VIRTUAL HOLD INSTALL DIRECTORY\RabbitMQ Server\rabbitmq_server-3.8.1\sbin
  • Run the following command:
rabbitmq-plugins enable rabbitmq_auth_mechanism_ssl
  • Run the following command to add a user to each server the Common Name certificate applies to.
rabbitmqctl.bat add_user [CommonName] "clearpassword"    rabbitmqctl clear_password [CommonName]    rabbitmqctl.bat set_user_tags [CommonName] administratorrabbitmqctl.bat set_permissions -p / [CommonName] ".*" ".*" ".*" 

Where:

  • [CommonName] - the common name associated with the certificate
  • Run the following command replacing the [URI string] with the URI string in the URI STRING EXAMPLE.
rabbitmqctl set_parameter federation-upstream [federation_upstream_name] ^ "{""uri"":""[URI_STRING]"",""expires"":300000, ""max-hops"":1, ""ack-mode"":""on-confirm"", ""trust-user-id"":false}"

Where:

  • [federation_upstream_name] - Name of the upstream
  • [URI_STRING] - URI string created using the URI String example

URI STRING EXAMPLE:

amqps://[Common Name]@[servershorname]?cacertfile=[dir of certificate]/ca_certificate.pem&certfile=[dir of certificate]/client_certificate.pem&keyfile=[dir of certificate]/client_key.pem&verify=verify_peer&server_name_indication=[servershorname]&auth_mechanism=external

Where:

  • [Common Name] - the common name associated with the certificate
  • [servershortname] - The shortname of the server that the connection is being made to
  • [dir of certificate] - Directory of the corresponding certificate

Step 5: Restart VHT Callback

Perform a restart of VHT Callback in order for the changes to take effect.

ADDITIONAL RESOURCES

Secure cross-origin resource sharing

Secure resource sharing between points of origin to help prevent malicious applications from communicating with APIs in an inappropriate way, thus preventing attacks like spoofing and data theft.

First, make sure that your servers are configured for HTTPS – see the HTTPS protocol support section earlier in this article.

After following the configuration steps in HTTPS protocol support, you can add the following directives to the On-Premise Callback Nginx config to resolve the CORS vulnerabilities.

Directive 1: $http_origin header

The first directive checks the $http_origin header on the request and matches it against a single regex domain or list of domains. If there is a match, it sets $cors_origin_header equal to the $http_origin, otherwise it will default to an empty string. This directive must be added outside of the server block, just above the SSL server block.

EXAMPLE

map $http_origin $cors_origin_header {     default "";     "~*(^https://)(server01\.vhtlab\.vhtcx\.com$)" "$http_origin";     "~*(^https://)(server02\.vhtlab\.vhtcx\.com$)" "$http_origin"; }  

Directive 2: $cors_origin_header

This second directive takes the $cors_origin_header that you set in the above step and adds the response Access-Control-Allow-Origin header with this value. This should be added within the SSL server block, but outside of the location blocks.

add_header Access-Control-Allow-Origin $cors_origin_header always; 

Directive 3: proxy_hide_header

The third directive is used to overwrite the existing Access-Control-Allow-Origin header that our individual components may be setting already. This is to ensure only the response header from Nginx is used. This should be added at the beginning of each location block within the SSL server block.

proxy_hide_header 'Access-Control-Allow-Origin'; 

EXAMPLE

The three directives in context of the On-Premise Callback proxy package.

worker_processes  1;

events {
    worker_connections  1024;
}

http {
  include       mime.types;
  default_type  application/octet-stream;

  sendfile        on;

  keepalive_timeout  65;
  
  log_format custom '$remote_addr - $http_origin [$time_local] '
					'"$request" $status $body_bytes_sent '
					'"$http_referer" "$http_user_agent"';

  server {
    listen       8081;
    server_name  localhost;
	
	access_log "C:/Program Files (x86)/Virtual Hold Technology/proxy/nginx/logs/http.log" custom;
	
	proxy_set_header Host $host;
	proxy_set_header X-Real-IP $remote_addr;

    location / {
      proxy_pass https://w20193rmhzphh6o.vhtlab.vhtcx.com:8080;
    }
  }
  
  map $http_origin $cors_origin_header {
    default "";									
    "~*(^https://)(w20193rmhzphh6o\.vhtlab\.vhtcx\.com$)" "$http_origin";
  }

  server {
    listen       8080 ssl;
    server_name  localhost;
	
	access_log "C:/Program Files (x86)/Virtual Hold Technology/proxy/nginx/logs/https.log" custom;

    ssl_certificate      vht_callback_ssl.crt;
    ssl_certificate_key  vht_callback_ssl.key;

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	
	add_header Access-Control-Allow-Origin $cors_origin_header always;

    location /auth/ {
	  proxy_hide_header 'Access-Control-Allow-Origin';
	  proxy_pass  http://127.0.0.1:2800/;
    }

    location /config/ {
	  proxy_hide_header 'Access-Control-Allow-Origin';
	  if ($request_uri ~* "(^\/config\/)(.*\/)(.*$)") {
	    proxy_pass http://127.0.0.1:8001/$2$3/;
	  }
		proxy_pass  http://127.0.0.1:8001/;
    }

    location /stats/ {
	  proxy_hide_header 'Access-Control-Allow-Origin';
      proxy_pass  http://127.0.0.1:2900/;
    }

    location /system/ {
	  proxy_hide_header 'Access-Control-Allow-Origin';
      proxy_pass  http://127.0.0.1:8000/;
    }
	
	location /license/ {
	  proxy_hide_header 'Access-Control-Allow-Origin';
      proxy_pass  http://127.0.0.1:8002/;
    }
	
    location /mgmt/ {
	  proxy_hide_header 'Access-Control-Allow-Origin';
      proxy_pass  http://127.0.0.1:8012/;
    }

    location /vhqmws/ {
	  proxy_hide_header 'Access-Control-Allow-Origin';
      proxy_pass  https://w20193rmhzphh6o.vhtlab.vhtcx.com;
    }
    
    location /vhqwatchws/ {
	  proxy_hide_header 'Access-Control-Allow-Origin';
      proxy_pass  https://w20193rmhzphh6o.vhtlab.vhtcx.com;
    }
  }
}

Additional IIS Hardening

The following tips can further enhance the security of IIS apps in an On-Premise Callback solution.

Configuring a custom error page

You can use a custom error page to prevent detailed information from being returned after an exception. One way to do this is detailed below:

  • Open a command line with administrator privileges.
  • Execute the following command, replacing the "-defaultPath" with the correct HTTP protocol and server name:
%systemroot%\system32\inetsrv\appcmd set config "Default Web Site" -section:httpErrors -errorMode:"Custom"-defaultResponseMode:"Redirect" -defaultPath:"https://<FQDN>/EyeQueue/EyeQErrorPage.aspx"