For the complete documentation index, see llms.txt. This page is also available as Markdown.

License Server Administration

Introduction

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.

Refer to the License Server Installation Checklist for a concise set of steps to follow.

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>.hexlic and certificate bundle issued for this deployment (where <LID> is your license ID)

The certificate bundle contains the certificate and private key used for the TLS encryption between the clients and the license server. You should not try to create them yourself: IDA checks the server certificate against a single Hex-Rays root, and rejects a certificate from any other authority.

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.

These are not the names the previous license server used. It shipped hexlicsrv and lsadm; a script written against that install needs those two words changed.

IDA installs its own lsadm, which is a different program from this one.

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.

What you want
Run setup as
Unzip it

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:

Use an unversioned path. An upgrade replaces the program where it stands and keeps the data beside 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.

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:

Path
What it holds

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

setup records the path of the program it was run from, and every later command reads it back. If you move or delete that file, the deployment stops working — service register refuses, and service status says so.

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.

start and service start are different commands. start runs the program in your terminal; service start drives the installed service. Running both at once makes them collide on the ports.

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.

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:

Path
Why it matters

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:

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:

  1. Stop it: sudo ./license-server service stop

  2. Back up the database (above).

  3. Put the new license-server where the old one was — the folder the deployment was set up from.

  4. 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

Migrating from a Flexera-based server? The procedure in this section is for the previous Hex-Rays License Server shipped with IDA 9.0–9.4. If your old server runs lmadmin or lmgrd together with the hexrays vendor daemon, follow From the Flexera-based license server instead.

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:

The question is asked only when setup is run interactively and you did not pass --from-legacy. An unattended run never guesses: a leftover directory from an old install would otherwise turn a fresh deployment into a migration.

Do not unzip the new server into the old install's directory — it has to stay as it is until the migration has read it.

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 naming contractor-* matched nobody; here it matches the whole family.

  • Name matching is now case-insensitive, so a rule naming Alice also matches alice.

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:

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.

Supported variables: LS_HOST, LS_PORT, LS_RPC_PORT, LS_RPC_TLS, LS_LOG_LEVEL and LS_WORK_DIR, covering the host, the ports, the transport and logging. Further variables may be added over time; config.yaml remains the complete list of settings.

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.

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.

defaultPolicy: deny with no matching rule is the most common reason for a client being refused. Every refusal is logged with the rule that matched, or a note that none did, and the console has a rule tester for checking a rule before you rely on it.

License Server Command Line

Command
What it does

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:

Event
Meaning

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.

Command
What it does

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.

The client records the certificate of each server it has connected to, and asks before recording a new one. A scripted call that has never connected before has nobody to ask, so it refuses unless you pass the fingerprint you have already checked with --fingerprint <sha256>.

borrow list and the wipe commands act on IDA's own local Offline records, not on anything the server holds, so license-client does not carry them out. Manage borrowed licenses from IDA's License manager window, where you can view them and return them.

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?