License Server Administration
Introduction
The Hex-Rays License Server is a single self-contained program. If you are coming from an earlier one, this is what changed:
Nothing to install. Unzip the download and run it; there is no installer and no runtime to add.
One command sets it up.
setupwrites the configuration, creates the database, makes the first administrator account, and registers the system service.license-clientreplaceslsadm, with the same commands.The server license is no longer tied to a MAC address, so a deployment can move between machines.
setupcan migrate an existing deployment, while leaving the old installation available as a rollback point.
Existing IDA clients remain protocol-compatible. Update their server address only if the deployment address changes.
This manual describes the installation, management, and interaction with a Hex-Rays License Server deployment. It is primarily intended for administrators, and will focus on the setup and management of the Hex-Rays License Server.
Installing the Hex-Rays License Server
Prerequisites
After your purchase of a Hex-Rays product with floating licenses, open the Download Center, select the appropriate release channel, then open ida-license-server and the release you want to install. Before you begin, have:
the Hex-Rays License Server download for your platform
the installer for the product you have purchased
the
license_server_<LID>.hexlicand certificate bundle issued for this deployment (where <LID> is your license ID)
The server will not start without both of those files, so download them before you begin.
You need root on the host only if you want the server to run as a system service that starts at boot. Running it as an ordinary user needs no special privileges.
Supported platforms
The Hex-Rays License Server runs on Linux x64 and Linux arm64. We have tested it on Debian and Ubuntu, but other major flavors of Linux should be fine too.
Version numbering and compatibility
The License Server has its own version and release schedule. Check the installed version with ./license-server version.
What governs whether a client can talk to a server is the protocol between them, not the version numbers — and on that, nothing has narrowed: this server speaks the same protocol as the one it replaces and still accepts the older revisions of it, so an IDA installation that worked with your previous Hex-Rays License Server works with this one. Only the address it connects to may need changing. (IDA 8.4 and earlier used Flexera-based licensing and cannot connect to any Hex-Rays License Server — see Migrate from the Flexera-based license server.)
Run a current server release and include the output of ./license-server version when reporting a problem.
Installation
What you download
The download is one zip per platform, and it contains a folder with everything in it:
Unzip it and both programs are ready to run — the executable bit survives the archive, so there is no chmod step. cd into the folder, and every command in this manual works as written.
Both programs say which platform they are for. ./license-server version prints the version, build date and target, so if you have lost track of which file is which, ask the file itself.
Where to unzip it, and whether to use sudo
Where the folder goes depends on how the server will run, so decide the two together. sudo is what makes the deployment belong to the machine rather than to your user account, and only a machine-wide deployment can be registered as a system service that starts at boot. Nothing else in setup needs root.
Try it out, or run it yourself
./license-server setup
anywhere
A system service, started at boot
sudo ./license-server setup
somewhere the service account can read
The second row carries a constraint the first does not. A system service runs under an account of its own — license-server, created by setup — which is in neither the owner nor the group of your home directory. To read the deployment's data it needs execute permission for others on every directory on the path, and a home directory does not give it (0750 on Ubuntu since 21.04, 0700 on RHEL).
So for a system service, put the folder somewhere that account can reach. /opt is where add-on software goes, and every account can pass through it:
If you run sudo ./license-server setup from somewhere the service cannot reach, setup says so and stops before writing anything, naming the directory that is closed and the ways forward. Nothing is left to clean up.
Running setup
Hand setup the two files issued for this deployment and it does the rest:
setup writes the configuration, creates the data directory and database, records where your license file is, unpacks the certificate bundle, creates the first administrator account, and registers and starts the system service.
The administrator password is printed once, in the closing summary, and only to the terminal — never to a log. Store it before you close the terminal. If it is lost, reset it with ./license-server admin reset-password.
Run setup with no flags for the guided version. It asks the same questions, and it looks for your two files in the folder holding the program and in the one your terminal is in, offering the newest match it can read. For a license file it also prints when that license expires — read that line, because a folder that has been through a renewal still holds the old file, and an expired license gives you a setup that reports success and a server that will not start.
The deployment keeps its data in data/ beside the program:
data/config/config.yaml
ports, session and borrow settings, TLS paths
data/config/acl.yml
access rules
data/db/license-server.db
sessions, seat allocations, audit log, accounts
data/licenses/
the license bundle the server hands out
Activating the server license
The server needs its own .hexlic to start. Unlike the previous license server, it is not bound to a MAC address: there is no host ID to collect and no activation step tied to a network interface, so a deployment can move machines or run in a container without the license being reissued.
The gate checks the signature, that the file is a license-server license, that it has at least one seat, and that it is still valid. It runs before any listener binds, so a refusal leaves nothing running.
Expiry follows a 30/30-day pattern: more than 30 days out it boots silently; inside 30 days it boots and warns; expired it boots and warns for another 30 days; past that it refuses. A perpetual license never warns.
To renew, put the new file beside the old one. A license that passes cleanly beats one that only passes with warnings, so the renewal takes effect as soon as it is there.
Creating the initial database
There is nothing to do: setup creates the database, and schema changes are applied automatically when a newer version starts. There is no separate initialization step and no schema flag.
Testing the server
If you installed it as a system service:
If you are running it yourself, start it in the foreground and leave it running:
Either way, confirm the server answers on the administration console port — 8080 unless you changed it:
Then check that your licenses are actually being served, which is the thing that matters to IDA users:
That should list your licenses with their seat counts, and the startup log names the bundle it loaded.
The first time the client connects to a server it shows you that server's certificate and asks whether to record it, so run this from a terminal. An empty list means the server is up but has nothing to hand out; check the Licenses page and the startup log to see which bundle was loaded.
The administration console
The server serves a web console on its admin port — http://<host>:8080/admin by default — where you can see the licenses in force, who holds which seat, live sessions, the access rules and the audit log, and return a seat that a departed client is still holding.
Sign in with the administrator account setup created. Manage accounts from the command line with ./license-server admin create|list|reset-password|delete.
Every console account is an administrator, and the pages disclose who is connected from where and who holds which seat. The console port is also where the unauthenticated health check is served, so keep that port on a trusted network. Only the RPC port needs to be reachable by your IDA users.
Management
Backup and restore
Nothing is backed up automatically. Back up before every upgrade.
Everything worth keeping is in the deployment's data directory — /opt/license-server/data if you followed the steps above:
data/db/license-server.db (+ -wal, -shm)
sessions, seat allocations, audit log, accounts
data/config/config.yaml
ports, session and borrow settings, TLS paths
data/config/acl.yml
access rules
data/licenses/*.hexlic
the licenses the server hands out
The database is in WAL mode, so copy it the way SQLite intends rather than with cp:
Check the backup is not empty. sqlite3 creates a database it cannot find, so pointing the command at the wrong path succeeds and writes a valid, empty file — which looks exactly like a good backup until the day you need it.
To restore, stop the server, put the files back, and start it again.
Upgrading the server
The upgrade is a replacement of the program, in place:
Stop it:
sudo ./license-server service stopBack up the database (above).
Put the new
license-serverwhere the old one was — the folder the deployment was set up from.Start it:
sudo ./license-server service start
Schema changes are applied automatically at startup. A previous binary can read the newer additive schema and warns that the database is ahead, but it does not reverse schema or data changes. The CLI does not prepare an automatic rollback point, which is another reason to take the backup.
License borrowing limits
The maximum duration a license can be borrowed for is borrow.maxHours in data/config/config.yaml. Zero means no limit. Restart the server after changing it.
A borrow that is refused is logged with the reason and the duration the client asked for, so the log answers "why can't this user borrow?" directly.
Migrating to the latest version
setup can migrate an existing Hex-Rays License Server deployment. The new server reads the old configuration, TLS material, access rules and license, and copies the old database into its own data directory.
Stop and disable the old server first. Migration takes over its RPC port and copies its database, so anything the old server writes afterwards would be lost:
setup refuses to migrate while it can see the old server running, still enabled, or something answering on its RPC port, and it says which of the three it found before anything is written.
There are two ways to ask for the migration. Interactively, setup asks as its very first question — Migrate an existing Hex-Rays License Server install? — and, if you say yes, asks for the directory, offering /opt/hexlicsrv:
Or name the directory up front, which is what a script does:
Read the summary. It lists every file carried across and everything that could not be, and it flags access rules whose meaning changes:
A product filter on a rule is dropped, because the old server never applied its own — keeping it would make the migrated rule narrower than the one it replaces.
*and?in a user name or machine name become wildcards. The old server compared names literally, so a rule namingcontractor-*matched nobody; here it matches the whole family.Name matching is now case-insensitive, so a rule naming
Alicealso matchesalice.
Review data/config/acl.yml before serving, especially if the old deployment's rules were never actually in effect.
Rolling back
Your old install is opened read-only and never written to, so it is still exactly as it was. To go back, remove the new server's service and start the old one:
A rollback loses the seats issued after the migration. The two servers no longer share a database, so borrows taken by the new server are in its copy and invisible to the old one. Those clients hold a record the rolled-back server does not know about, and their seats stay free until the original borrow period elapses.
Configuration
Settings live in data/config/config.yaml, written by setup. The file covers ports, session timeouts, borrow limits, audit retention and the TLS material. Restart the server after editing it.
The two ports are the ones most often changed, and they can be set at install time instead — --rest-port for the administration console, --rpc-port for the port IDA connects on. setup writes them into the configuration file, so they hold however the server is started.
Some settings also have an LS_-prefixed environment variable; the tuning knobs in config.yaml do not. The file wins over the environment, so a value setup wrote cannot be contradicted by one.
A broken database: or tls: block stops the server rather than falling back, because the fallback would be a different database or a different certificate. A borrow limit (borrow.maxHours) that is present but unreadable stops it too, for the same reason — its default, 0, means unlimited, the opposite of the cap you meant to set. Every other setting falls back to its default with a warning.
TLS
The RPC listener normally terminates TLS itself, with the certificate from your bundle. IDA verifies the endpoint certificate against a single Hex-Rays root, so a certificate from any other authority will not work. A fronting load balancer can either pass TCP through, or terminate TLS only if it presents the issued Hex-Rays certificate. For TLS termination at the load balancer, explicitly disable RPC TLS between it and the server with LS_RPC_TLS=false or a tls configuration whose mode is disabled.
To rotate a certificate, put the new pair in place, point config.yaml at it, and restart. The listener reads its material only at startup, so there is no hot reload.
An expired certificate passes every startup check and fails only at the TLS handshake, which reaches IDA as an unexplained connection error while the server looks healthy. Track the expiry date rather than waiting to be told.
The console is served as plain HTTP on its own port. Keep it on a trusted network, or terminate TLS in front of it.
Access Control Lists (ACL)
Access rules live in data/config/acl.yml, and the console's Access Control page edits the same file. A new deployment starts permissive:
Rules match on user name, machine, product and license, and the default policy decides what happens when no rule matches. Name matching is case-insensitive, and * and ? are wildcards.
License Server Command Line
setup
Set up the deployment: configuration, data directory, first administrator, service
start
Run the server in this terminal
service
Manage the installed service: register, unregister, start, stop, restart, status, logs
admin
Manage console accounts: create, list, reset-password, delete
teardown
Stop and unregister the service and forget the deployment; --purge also deletes the data
version
Print the version, build date and platform
notices
Print the third-party notices for the libraries the program is built from
./license-server --help lists them all, and --help after any of them explains that one.
Reading the log
Log lines are plain text with no colour codes, so they read the same in a terminal, in journalctl, or in a file. LS_LOG_LEVEL is debug, info, warn or error; at info a busy server logs a line per request and IDA clients send regular keepalives, so warn is a reasonable setting for a large deployment.
For a service deployment, ./license-server service logs shows them.
Refusals carry a stable, greppable name and the identity involved, so grep refuse. answers most "why can't my user get a seat?" questions directly:
refuse.acl_deny
an access rule, or the default policy, denied it
refuse.checkout
no seat available, license expired, or unknown license
refuse.borrow
past the license's own expiry, over the borrow limit, or already borrowed
refuse.helo
the session could not be created, usually a version mismatch
license.file_rejected
a .hexlic was skipped at startup, with the reason
A checked-out seat left by a client that vanished uncleanly is reclaimed when the session times out, and the console can return it sooner. A borrowed seat survives session cleanup and remains held until it is returned, its borrow period expires, or an administrator force-returns it.
license-client Command-Line Tool
license-client replaces lsadm and keeps its commands.
info
show server information
list
list the licenses the server offers
checkout / checkin
take and return a seat
borrow / return
borrow a license for offline use, and return it
force-return
return a license held by another user
active
list the licenses currently in use
Give it the server with -h <host>:<rpc port>; -u acts as a specific user@machine-id, and -j prints JSON for scripting.
Run it with no command for an interactive session.
Connecting IDA
In IDA, open the License manager, select Use floating license server, enter the host name your administrator gave you, and click Connect. See Getting started with floating licenses for the full client-side walkthrough.
IDA connects on the RPC port, 65434 by default. The administration console shows the RPC port in use.
Troubleshooting
The service starts, then keeps restarting
Almost always a missing or rejected server license: the server refuses to start, and the service restarts it. ./license-server service logs names the reason. A license placed by hand must be readable by the service account.
The admin client refuses to connect: the server is not recorded
license-client remembers the certificate a server presented the first time it connected, and will not connect to one it has not recorded:
Run the command once from a terminal and it shows you the certificate and asks, recording your answer for next time. In a script, check the fingerprint against the server first and then pass it:
The same message appears if a server is reinstalled with a new certificate. If you cannot explain the change, treat it as one worth investigating rather than approving.
Connection issues
The console and the IDA-facing listener are two different ports. The console is plain HTTP on the admin port; IDA connects on the RPC port over TLS. Check that the RPC port is the one IDA was given. If an upstream device terminates RPC TLS, it must present the issued Hex-Rays certificate.
A seat is held by someone who is not there
A checkout left by a client that vanished uncleanly is reclaimed when its session times out. A borrowed seat instead lasts until return or expiry. The console's Allocations page can return either one sooner, as can license-client force-return.
The server refuses to start after config.yaml was edited
A broken database: or tls: block stops the server rather than falling back to a different database or a different certificate. The message names the key and the problem.
Last updated
Was this helpful?
