Deployment guide

Virtuoso Open Source Edition 7.2.17

Overview

Virtuoso is a multi-model data server from OpenLink Software. A single self-contained daemon (virtuoso-t) acts as an RDF triplestore with a SPARQL endpoint, a relational SQL engine and a built-in HTTP server, and you administer it through the Conductor web console. It is the engine behind DBpedia, and Virtuoso Open Source Edition is licensed under the GNU General Public License, version 2.

This guide covers launching and using the Virtuoso Open Source Edition 7.2.17 AMI from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud Hardened Neo4j & Graph and RDF Databases AMIs listing on AWS Marketplace, and you pick it as the software version when you subscribe and launch. Every product in the listing is described at /guides/graph-databases-aws/.

What you get:

  • Ubuntu 24.04 LTS with Virtuoso Open Source Edition 7.2.17 (the official OpenLink build 07.20.3243, with the Conductor installed) in /opt/virtuoso, nginx, and the SecureAnyCloud first-boot service
  • No default login. Virtuoso ships dba/dba and a dav account. On first boot, the image creates a fresh database for the instance, sets dba and dav to unique 24-character passwords, and re-keys every other built-in account to a random value that nobody records. Nothing listens until that has finished, and if any step fails, Virtuoso and nginx stay stopped.
  • HTTPS from the first boot. nginx serves the Conductor, the SPARQL endpoint and WebDAV on port 443 with a certificate generated on the instance for its own hostname. Port 80 only redirects to HTTPS, and requests for any other hostname are dropped.
  • Database ports kept private. The SQL / ODBC server (127.0.0.1:1111) and Virtuoso's HTTP server (127.0.0.1:8890) listen on loopback only. Only SSH, 80 and 443 are reachable.
  • Instance metadata blocked for the database. Virtuoso can fetch remote URLs (SPARQL LOAD, the Sponger, http_get()). The virtuoso and nginx services cannot reach the EC2 instance metadata service, and the AMI requires IMDSv2.
  • Fully patched at build time, with Ubuntu's unattended security updates left on
  • 24/7 SecureAnyCloud support

Connecting to your instance

Use these connection details for Virtuoso Open Source Edition 7.2.17 on Ubuntu 24.04:

  • SSH user: ubuntu
  • Web console: https://<public-dns>/conductor/

Prerequisites

  • An AWS account and permission to launch EC2 instances
  • An EC2 key pair in the Region you launch in
  • A security group that allows TCP 22 from your own address, and TCP 443 (and optionally 80, which only redirects) from the clients that will use the Conductor, SPARQL or WebDAV. Never open 1111 or 8890, because they listen on loopback only.

Recommended instance type: m5.large (2 vCPU, 8 GiB). The memory settings in /etc/virtuoso/virtuoso.ini (NumberOfBuffers, MaxDirtyBuffers) are sized for this instance type. For large datasets, raise them as you increase the instance size.

1

Launch the instance

Option A: AWS Marketplace console

  • Open the SecureAnyCloud Hardened Neo4j & Graph and RDF Databases AMIs listing on AWS Marketplace, choose View purchase options, then choose Subscribe. One subscription covers every version in the listing.
  • Choose Launch your software. In Version, choose Virtuoso Open Source Edition 7.2.17 on Ubuntu 24.04 - YYYY-MM-DD, and select your Region.
  • Set the instance type. m5.large is recommended.
  • Choose your EC2 key pair.
  • Configure the security group to allow TCP 22 from your own address and TCP 443 (and 80) from your clients.
  • Launch the instance. First boot takes about a minute after the instance is reachable.

Option B: AWS CLI

Run this command on your own workstation. Replace the AMI ID with the one shown for your Region on the Marketplace launch page, and replace the key pair, security group and subnet with your own:

aws ec2 run-instances \
  --image-id ami-0123456789abcdef0 \
  --instance-type m5.large \
  --key-name my-key-pair \
  --security-group-ids sg-0123456789abcdef0 \
  --subnet-id subnet-0123456789abcdef0 \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=virtuoso}]'

The AMI already requires IMDSv2, so you do not need --metadata-options.

2

Connect over SSH

ssh -i my-key-pair.pem ubuntu@<public-ip>

The login banner shows the Conductor and SPARQL URLs for this instance.

3

Check the services

systemctl is-active virtuoso nginx virtuoso-opensource-firstboot
active active active

virtuoso-opensource-firstboot is a one-time unit, and it reports active once first boot has finished. virtuoso runs the virtuoso-t daemon as the unprivileged virtuoso user, and nginx fronts it on 80 and 443.

4

Check what listens on the network

sudo ss -tlnp | grep -E ':(22|80|443|1111|8890) '
0.0.0.0:80 nginx 0.0.0.0:22 sshd 0.0.0.0:443 nginx 127.0.0.1:1111 virtuoso-t 127.0.0.1:8890 virtuoso-t [::]:80 nginx [::]:22 sshd [::]:443 nginx

Only SSH and nginx listen on the network. The Virtuoso SQL server (1111) and HTTP server (8890) accept local connections only.

5

Find your credentials

On first boot, the image writes this instance's passwords to a root-only file (mode 0600). List the settings it holds:

sudo grep -oE '^[A-Z_]+=' /root/virtuoso-opensource-credentials.txt
VIRTUOSO_HOST= VIRTUOSO_CONDUCTOR_URL= VIRTUOSO_SPARQL_URL= VIRTUOSO_ADMIN_USER= VIRTUOSO_DBA_PASSWORD= <set-at-first-boot>= VIRTUOSO_DAV_PASSWORD=

To show the whole file, run sudo cat /root/virtuoso-opensource-credentials.txt. It looks like this, with your instance's own values:

VIRTUOSO_HOST=ec2-203-0-113-10.compute-1.amazonaws.com VIRTUOSO_CONDUCTOR_URL=https://ec2-203-0-113-10.compute-1.amazonaws.com/conductor/ VIRTUOSO_SPARQL_URL=https://ec2-203-0-113-10.compute-1.amazonaws.com/sparql VIRTUOSO_ADMIN_USER=dba VIRTUOSO_DBA_PASSWORD=<VIRTUOSO_DBA_PASSWORD> VIRTUOSO_DAV_USER=dav VIRTUOSO_DAV_PASSWORD=<VIRTUOSO_DAV_PASSWORD>

The hostname is the instance's public DNS name from the EC2 instance metadata service. The image never takes it from a web request.

6

Check HTTPS and the certificate

Port 80 redirects to HTTPS, and the HTTPS front end answers with the certificate generated on this instance:

H=$(sudo grep '^VIRTUOSO_HOST=' /root/virtuoso-opensource-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' --resolve "$H:80:127.0.0.1" "http://$H/conductor/"
curl -s --cacert /etc/ssl/virtuoso/virtuoso.crt --resolve "$H:443:127.0.0.1" -o /dev/null -w '%{http_code}\n' "https://$H/conductor/" openssl x509 -in /etc/ssl/virtuoso/virtuoso.crt -noout -subject -ext subjectAltName
301 https://ec2-203-0-113-10.compute-1.amazonaws.com/conductor/ 200 subject=CN = ec2-203-0-113-10.compute-1.amazonaws.com, O = sac X509v3 Subject Alternative Name: DNS:ec2-203-0-113-10.compute-1.amazonaws.com, IP Address:203.0.113.10, IP Address:172.31.82.241, DNS:ip-172-31-82-241.ec2.internal, IP Address:127.0.0.1, DNS:localhost

The certificate is self-signed, so your browser shows a warning the first time. Before you accept it, check that the fingerprint matches (openssl x509 -in /etc/ssl/virtuoso/virtuoso.crt -noout -fingerprint -sha256 on the instance). Alternatively, install a certificate from your own CA (Step 13).

7

Query the SQL engine

The isql client connects to the loopback SQL server. Use the dba password from the credentials file. The sample DBA.DEMO_CUSTOMERS table returns three rows.

export LD_LIBRARY_PATH=/opt/virtuoso/lib
DBA=$(sudo grep '^VIRTUOSO_DBA_PASSWORD=' /root/virtuoso-opensource-credentials.txt | cut -d= -f2-) /opt/virtuoso/bin/isql 127.0.0.1:1111 dba "$DBA" exec="SELECT ID, NAME, CITY FROM DBA.DEMO_CUSTOMERS ORDER BY ID;"
ID NAME CITY INTEGER NOT NULL VARCHAR NOT NULL VARCHAR _______________________________________________________________________________ 1 Ada Lovelace London 2 Alan Turing Manchester 3 Grace Hopper New York 3 Rows. -- 1 msec.

Virtuoso itself refuses the upstream default dba/dba login:

OUT=$(/opt/virtuoso/bin/isql 127.0.0.1:1111 dba dba exec="SELECT 1;" 2>&1 || true)
grep -o 'Error 28000.*' <<<"$OUT"
Error 28000: [Virtuoso Driver]CL034: Bad login

Virtuoso blocks a client address for 60 seconds after four failed logins (SQL and HTTP together). If you mistype the password several times in a row, you are locked out for a minute.

8

Sign in to the Conductor

Open https://<public-dns>/conductor/ in your browser and accept the self-signed certificate. Sign in with the account dba and VIRTUOSO_DBA_PASSWORD.

The Database tab lists the SQL catalogs and lets you create tables, views and procedures.

Database > Interactive SQL runs SQL in the browser. In this guide's example, the sample table returns its three rows.

Linked Data > SPARQL runs SPARQL with the dba account. With the Default Graph IRI set to http://sac.example/catalog, the sample graph returns its triples.

System Admin shows the server dashboard and holds User Accounts, Parameters, Packages, Backup and the Scheduler.

9

Use the SPARQL endpoint

https://<public-dns>/sparql is the standard SPARQL protocol endpoint, with a query form for browsers.

Read queries need no login (the DBpedia model), so applications can query the endpoint directly:

H=$(sudo grep '^VIRTUOSO_HOST=' /root/virtuoso-opensource-credentials.txt | cut -d= -f2-)
curl -s --cacert /etc/ssl/virtuoso/virtuoso.crt --resolve "$H:443:127.0.0.1" -H 'Accept: text/csv' \
  --data-urlencode 'query=SELECT ?s ?label WHERE { GRAPH <http://sac.example/catalog> { ?s <http://www.w3.org/2000/01/rdf-schema#label> ?label } } ORDER BY ?s' \
  "https://$H/sparql"
"s","label" "http://sac.example/product/1","Virtuoso Open Source Edition" "http://sac.example/product/2","sac AWS Marketplace image"

Virtuoso refuses anonymous updates. INSERT, DELETE, LOAD and the Sponger need an authenticated account with SPARQL update rights:

H=$(sudo grep '^VIRTUOSO_HOST=' /root/virtuoso-opensource-credentials.txt | cut -d= -f2-)
curl -s --cacert /etc/ssl/virtuoso/virtuoso.crt --resolve "$H:443:127.0.0.1" \
  --data-urlencode 'query=INSERT DATA { GRAPH <http://example.org/g> { <http://example.org/s> <http://example.org/p> "x" } }' \
  "https://$H/sparql" | head -1
Virtuoso 42000 Error SR186:SECURITY: No permission to execute procedure DB.DBA.SPARQL_INSERT_DICT_CONTENT with user ID 107, group ID 107

If your data must not be public, allow TCP 443 only from your own networks in the security group. Alternatively, remove the anonymous read grant in the Conductor (System Admin > User Accounts, user SPARQL).

10

Use WebDAV

Virtuoso's WebDAV repository is at https://<public-dns>/DAV/. It refuses anonymous access and accepts the dav account with VIRTUOSO_DAV_PASSWORD:

H=$(sudo grep '^VIRTUOSO_HOST=' /root/virtuoso-opensource-credentials.txt | cut -d= -f2-)
DAV=$(sudo grep '^VIRTUOSO_DAV_PASSWORD=' /root/virtuoso-opensource-credentials.txt | cut -d= -f2-)
curl -s --cacert /etc/ssl/virtuoso/virtuoso.crt --resolve "$H:443:127.0.0.1" -u "dav:$DAV" -X PROPFIND -H 'Depth: 0' -o /dev/null -w 'dav: %{http_code}\n' "https://$H/DAV/"
curl -s --cacert /etc/ssl/virtuoso/virtuoso.crt --resolve "$H:443:127.0.0.1" -X PROPFIND -H 'Depth: 0' -o /dev/null -w 'anonymous: %{http_code}\n' "https://$H/DAV/"
dav: 207 anonymous: 401
11

Reach the SQL port from your workstation

The SQL / ODBC / JDBC port stays on loopback. Instead of opening it, forward it over SSH:

ssh -i my-key-pair.pem -L 1111:127.0.0.1:1111 ubuntu@<public-ip>

Then point a local isql, ODBC or JDBC client at 127.0.0.1:1111 with the dba account.

For an application tier in the same VPC, open 1111 in the security group to that tier's subnet only, and change ServerPort in /etc/virtuoso/virtuoso.ini to the private address.

12

Instance metadata is blocked for Virtuoso

The virtuoso and nginx services carry a systemd rule that denies the instance metadata addresses. As a result, a SPARQL LOAD, a Sponger fetch or http_get() can never read the instance's metadata or role credentials:

systemctl show -p IPAddressDeny virtuoso nginx
IPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32 IPAddressDeny=fd00:ec2::254/128 169.254.169.254/32 168.63.129.16/32

From inside the Virtuoso service, the metadata service does not answer (000):

sudo bash -c 'cg=$(systemctl show -p ControlGroup --value virtuoso.service); echo $$ > /sys/fs/cgroup$cg/cgroup.procs; curl -s -m 5 -o /dev/null -w "IMDS from virtuoso.service: %{http_code}\n" -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 60" http://169.254.169.254/latest/api/token' || true
IMDS from virtuoso.service: 000
13

Use your own hostname and certificate

To serve Virtuoso under your own DNS name, point the name at the instance, then run this command:

sudo virtuoso-set-hostname <your-domain>

The command records the name in /etc/sac/virtuoso-hostname, issues a new self-signed certificate for it, and reloads nginx.

To use a certificate from your own CA, replace /etc/ssl/virtuoso/virtuoso.crt and /etc/ssl/virtuoso/virtuoso.key (keep the key at mode 0600), then run sudo systemctl reload nginx.

14

Manage the service

systemctl status virtuoso --no-pager | head -5 sudo journalctl -u virtuoso -n 20 --no-pager
  • Configuration: /etc/virtuoso/virtuoso.ini. Restart with sudo systemctl restart virtuoso after you change it.
  • Database files: /var/lib/virtuoso/db (virtuoso.db, the transaction log virtuoso.trx and the server log virtuoso.log)
  • Backups: use System Admin > Backup in the Conductor, or stop virtuoso and copy /var/lib/virtuoso/db
  • Passwords: to change one, run DB.DBA.USER_SET_PASSWORD('dba', '<new-password>'); in Interactive SQL or isql, then update the credentials file

Security notes

  • No baked-in credentials. The image carries an inert template database that no instance ever serves. First boot copies it, sets dba and dav to per-instance passwords, re-keys every other account, and only then starts Virtuoso and nginx.
  • Locked built-in accounts. Built-in accounts other than dba and dav (SPARQL, SOAP, WebMeta and others) cannot log in.
  • Trusted client address. nginx passes Virtuoso a fixed hostname and the real client address, overwriting any X-Forwarded-For header that a client sends.
  • Restricted server features. AllowOSCalls = 0 and HTTPProxyEnabled = 0 are set in virtuoso.ini.
  • Per-instance secrets. SSH host keys, the machine ID, the TLS key and every password are generated per instance.

Licensing and support

Virtuoso Open Source Edition is licensed under the GNU General Public License, version 2 (with OpenLink's OpenSSL and client driver exemptions). The image carries the unmodified official OpenLink 7.2.17 build, and /opt/virtuoso/SOURCE.txt names the corresponding source. The commercial Virtuoso Enterprise Edition is a separate product and is not included. Virtuoso is a trademark of OpenLink Software, and SecureAnyCloud is not affiliated with or endorsed by OpenLink Software.

SecureAnyCloud provides 24/7 support by email and live chat for every version in the listing. Contact sales@secureanycloud.com.

Deploy on AWS

Launch Virtuoso Open Source Edition 7.2.17 on Ubuntu 24.04 with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS