Oracle Instant Client 23.26 on AWS User Guide
Overview
This guide covers launching and using the Oracle Instant Client 23.26 on Oracle Linux 9 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg Oracle Database Client listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.
Oracle Instant Client is Oracle's lightweight client: the libraries and command-line tools that applications and administrators use to connect to an Oracle Database, without a full Oracle client installation. Instant Client 23.26 is the client of the Oracle AI Database 26ai release family, which is under Oracle Premier Support. Use it to connect applications and SQL*Plus to any Oracle Database release that Oracle supports with this client (Oracle's client and server interoperability note on My Oracle Support, Doc ID 207303.1, lists the combinations): on Amazon RDS for Oracle, on another EC2 instance, on premises over a VPN or AWS Direct Connect, or in Oracle Cloud. The image carries three Instant Client packages:
- Basic: the OCI, OCCI and JDBC-OCI client libraries (
libclntsh.so,libocci.so,libocijdbc23.so) for your own applications, plusadrciandgenezi - SQL*Plus: the
sqlpluscommand-line tool for SQL and PL/SQL - Tools: SQL*Loader (
sqlldr), the Data Pump clients (expdp,impdp), the original export and import clients (exp,imp) and the Workload Replay client (wrc)
The ODBC driver, the SDK (header files) and the JDBC Thin driver packages are not included. Instant Client has no tnsping; SQL*Plus tests a connection instead (step 6).
Oracle's release, unmodified. The packages are Oracle's own Instant Client 23.26.4.0.0 RPMs for Oracle Linux 9, from Oracle's Instant Client download page. Before installing them cloudimg checks each one against the size, checksum and SHA-256 that Oracle publishes for it and against Oracle's RPM signature, and the installed files are exactly as Oracle ships them (rpm -V reports no change). Instant Client releases are complete releases that Oracle publishes for everyone, so newer ones come straight from Oracle (step 10). The Oracle Linux 9 packages are fully patched when the image is built.
Bring your own licence. This image includes no Oracle licence. Oracle Instant Client is used under Oracle's Instant Client license terms (the license files are in /usr/share/oracle/23/client64/doc), and you need your own Oracle Database licence for every database you connect to.
The cloudimg image adds:
- A verified client. On the first boot of your instance,
cloudimg-oracle-client-firstboot.servicechecks every Instant Client file against Oracle's own package checksums (rpm -V) and against the SHA-256 checksums cloudimg recorded when it built the image, and checks that SQL*Plus is release 23.26.4.0.0. If anything differs the unit fails, so the instance reports a degraded boot, and/root/oracle-client-FIRSTBOOT-FAILED.txtexplains why. - Ready to use from any shell.
sqlplusis on every user's path, every login shell also gets the Instant Client tools on itsPATHandNLS_LANGfrom/etc/profile.d/oracle-instantclient.sh, andsqlldr,expdp,impdp,exp,imp,wrcandadrciare linked into/usr/local/binfor scripts and cron. The libraries are in the system library path through Oracle's own/etc/ld.so.conf.d/oracle-instantclient.conf, and cloudimg checked that no Instant Client library has the name of a system library, so none can replace one. - No listening service but SSH. The image runs no Oracle listener and no other network service: only SSH listens on port 22. The client only makes outbound connections to your databases.
- Hardened Oracle Linux 9. Key-only SSH, SELinux enforcing, the host firewall allowing SSH only, no password on any account, no C compiler, the IMDSv2-only instance metadata service, the Amazon Time Sync Service as the preferred clock source, time zone UTC, and daily automatic Oracle Linux security updates.
- No shared identity. Each instance generates its own SSH host keys and machine identity on first boot, and no build credential, log or key is left in the image. The client needs no secret of its own, so the image creates none; Oracle wallets are yours to create (step 7).
This is a headless image with no web interface; you work over SSH.
Default user: ec2-user · Architecture: x86_64 · Recommended instance type: m5.large
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet.
- A security group that allows TCP 22 (SSH) from your own networks only. No other inbound port is needed.
- Outbound network access from the instance to each database's listener port (usually TCP 1521), through the security groups, network ACLs and routes between them.
- The host name or address, port and service name of each database you want to reach, and a database account.
- Your own Oracle Database licence for the databases you connect to.
Instance type: m5.large (2 vCPU, 8 GiB) suits interactive SQL*Plus work, application connections and most batch loads; choose a larger type for heavy SQL*Loader or Data Pump work.
Step 1: Launch from AWS Marketplace
Open the listing on AWS Marketplace, choose View purchase options and Subscribe. When the subscription is active choose Launch your software, then in Version pick Oracle Instant Client 23.26 on Oracle Linux 9. Choose your Region, an instance type (m5.large is recommended), your key pair and a security group that opens port 22 from your own networks only, then launch.
The instance is ready about two minutes after launch.
Step 2: Launch from the AWS CLI
Replace <ami-id> with the AMI ID of this version in your Region, and the other placeholders with your own values. The command requires IMDSv2:
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=oracle-instant-client-23-26}]'
Retrieve the public address once the instance is running:
aws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text
Step 3: Connect over SSH and Check First Boot
| Version | SSH user |
|---|---|
| Oracle Instant Client 23.26 on Oracle Linux 9 | ec2-user |
ssh -i <your-key.pem> ec2-user@<public-ip>
Check that the first boot verification has run:
systemctl status cloudimg-oracle-client-firstboot.service --no-pager | head -5
sudo cat /var/log/cloudimg/oracle-client-firstboot.log
The unit is active (exited) with status=0/SUCCESS, and the log records how many Instant Client files were checked:
● cloudimg-oracle-client-firstboot.service - cloudimg: verify Oracle Instant Client on first boot
Loaded: loaded (/etc/systemd/system/cloudimg-oracle-client-firstboot.service; enabled; preset: disabled)
Active: active (exited) since Thu 2026-10-22 01:15:52 UTC; 2min 38s ago
Main PID: 8752 (code=exited, status=0/SUCCESS)
CPU: 2.096s
2026-10-22T01:15:50Z first boot verification started
2026-10-22T01:15:52Z verified 26 Instant Client files (rpm -V clean); SQL*Plus 23.26.4.0.0
If the unit failed, read /root/oracle-client-FIRSTBOOT-FAILED.txt and contact support.
Step 4: Confirm the Client Release and Tools
sqlplus -V
rpm -q oracle-instantclient-basic oracle-instantclient-sqlplus oracle-instantclient-tools
ls /usr/lib/oracle/23/client64/bin | tr '\n' ' '; echo
SQL*Plus: Release 23.26.4.0.0 - Production
Version 23.26.4.0.0
oracle-instantclient-basic-23.26.4.0.0-1.el9.x86_64
oracle-instantclient-sqlplus-23.26.4.0.0-1.el9.x86_64
oracle-instantclient-tools-23.26.4.0.0-1.el9.x86_64
adrci exp expdp genezi imp impdp sqlldr sqlplus wrc
The release line is the exact Instant Client release: 23.26.4.0.0, as Oracle built it.
| Path | Purpose |
|---|---|
/usr/lib/oracle/23/client64/bin |
The Instant Client tools |
/usr/lib/oracle/23/client64/lib |
The OCI, OCCI and JDBC-OCI libraries (libclntsh.so, libocci.so, libocijdbc23.so), in the system library path |
/usr/lib/oracle/23/client64/lib/network/admin |
Instant Client's default Oracle Net directory: sqlnet.ora and tnsnames.ora |
/usr/share/oracle/23/client64/doc |
Oracle's license and readme files for each package |
/etc/profile.d/oracle-instantclient.sh |
PATH and NLS_LANG for login shells |
/usr/share/doc/cloudimg/oracle-instantclient-23-26/README.txt |
A summary of this image |
Step 5: Run the Self-Test
The image carries a self-test that repeats the first boot checks and proves the client works end to end without a database: Oracle Net name resolution, a connection attempt that reaches the network layer, the tools from a login shell and from an empty environment, the exact listening ports, SELinux and every SSH setting:
sudo /usr/local/sbin/cloudimg-oracle-client-selftest
PASS: first-boot verification marker present
PASS: no first-boot failure note
PASS: rpm -V clean for oracle-instantclient-basic oracle-instantclient-sqlplus oracle-instantclient-tools
PASS: Instant Client matches the build manifest (26 files)
PASS: login shell: sqlplus -V = 23.26.4.0.0
PASS: empty environment: sqlplus -V = 23.26.4.0.0
PASS: login shell: SQL*Loader 23.26.4.0.0
PASS: empty environment: Data Pump expdp 23.26.4.0.0
PASS: sqlplus: unknown alias refused by name resolution (ORA-12154)
PASS: sqlplus: no listener on this instance (ORA-12541)
PASS: only TCP 22 listens
PASS: no Oracle listener process
PASS: SELinux enforcing
PASS: firewalld public: dhcpv6-client ssh
PASS: no account carries a password hash
PASS: sshd -T PasswordAuthentication no
PASS: sshd -T KbdInteractiveAuthentication no
PASS: sshd -T PermitEmptyPasswords no
PASS: sshd -T PermitRootLogin no
PASS: sshd -T PubkeyAuthentication yes
PASS: sshd -T X11Forwarding no
PASS: sshd -T AllowTcpForwarding yes
PASS: sshd -T MaxAuthTries 4
PASS: sshd -T ClientAliveInterval 300
PASS: sshd -T ClientAliveCountMax 3
PASS: sshd -T LoginGraceTime 60
PASS: no compiler (gcc, cc, c++, g++, make) on the PATH
PASS: no core dump or crash report
ORACLE_CLIENT_SELFTEST_OK
ORA-12154 and ORA-12541 are the expected answers here: the self-test asks for an alias that does not exist and connects to port 1521 on the instance itself, where no listener runs. The self-test checks for the release this image shipped, so after you install a newer Instant Client (step 10) its release checks report the new release as a failure.
Step 6: Add Your Databases to tnsnames.ora
sqlnet.ora resolves names through tnsnames.ora first and then EZCONNECT (host:port/service), so you can connect without any configuration, or give each database a short alias. Look at the shipped files:
grep -v '^#' /usr/lib/oracle/23/client64/lib/network/admin/sqlnet.ora
cat /usr/lib/oracle/23/client64/lib/network/admin/tnsnames.ora
NAMES.DIRECTORY_PATH = (TNSNAMES, EZCONNECT)
SQLNET.EXPIRE_TIME = 10
SQLNET.OUTBOUND_CONNECT_TIMEOUT = 60
# cloudimg Oracle Instant Client 23.26 - Oracle Net service names.
# Add one entry per database, for example:
#
# MYDB =
# (DESCRIPTION =
# (ADDRESS = (PROTOCOL = TCP)(HOST = db.example.com)(PORT = 1521))
# (CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = ORCLPDB1))
# )
The files belong to root, so edit them with sudo. To add an alias, append an entry with your database's host, port and service name, then test it with a connection that SQL*Plus will prompt you to complete:
sudo tee -a /usr/lib/oracle/23/client64/lib/network/admin/tnsnames.ora > /dev/null <<'TNS'
MYDB =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = <db-host>)(PORT = 1521))
(CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = <service-name>))
)
TNS
sqlplus <db-user>@MYDB
ORA-12154 means the alias is not in tnsnames.ora; ORA-12170 or a timeout means the network path to the database (security groups, network ACLs, routes) does not allow the connection; ORA-12514 means the listener answered but does not know the service name. To keep your own tnsnames.ora and sqlnet.ora elsewhere, set TNS_ADMIN to that directory in your shell profile or your application's environment.
Step 7: Connect with SQL*Plus
Connect with the alias, or directly with EZCONNECT. SQL*Plus prompts for the password, which keeps it out of your shell history and the process list:
sqlplus <db-user>@MYDB
sqlplus <db-user>@//<db-host>:1521/<service-name>
For Amazon RDS for Oracle, <db-host> is the DB instance endpoint shown in the RDS console and <service-name> is the database name (ORCL by default). Once connected:
SELECT banner_full FROM v$version;
SELECT sys_context('USERENV', 'SERVICE_NAME') FROM dual;
Never put a password on the command line (sqlplus user/password@db): it is visible to every user of the instance in the process list. For unattended scripts, keep the credentials in an Oracle wallet (a secure external password store) in a directory only your account can read, add WALLET_LOCATION and SQLNET.WALLET_OVERRIDE = TRUE to your own sqlnet.ora and connect with sqlplus /@MYDB. Instant Client does not include mkstore or orapki, so create the wallet with a full Oracle Database Client (another version in this listing) or on the database host and copy it over. The image ships no wallet; every wallet you use is your own.
Step 8: Encrypt the Connection to the Database
Oracle Net traffic is not encrypted unless the client and the server agree to encrypt it. sqlnet.ora carries commented settings for both methods:
- Oracle Native Network Encryption. Uncomment the
SQLNET.ENCRYPTION_CLIENTandSQLNET.CRYPTO_CHECKSUM_CLIENTlines (REQUIRED, AES256 and SHA256) to refuse any unencrypted session. The database must accept encryption; Amazon RDS for Oracle enables it with theNATIVE_NETWORK_ENCRYPTIONoption. - TLS (TCPS). Point
WALLET_LOCATIONat a wallet holding your database's CA certificate and use(PROTOCOL = TCPS)and the database's TLS port in the alias. Amazon RDS for Oracle provides TLS with itsSSLoption and publishes its CA certificates.
grep -n 'ENCRYPTION\|CRYPTO\|WALLET' /usr/lib/oracle/23/client64/lib/network/admin/sqlnet.ora
10:# SQLNET.ENCRYPTION_CLIENT = REQUIRED
11:# SQLNET.ENCRYPTION_TYPES_CLIENT = (AES256)
12:# SQLNET.CRYPTO_CHECKSUM_CLIENT = REQUIRED
13:# SQLNET.CRYPTO_CHECKSUM_TYPES_CLIENT = (SHA256)
15:# WALLET_LOCATION = (SOURCE = (METHOD = FILE) (METHOD_DATA = (DIRECTORY = /path/to/your/wallet)))
Edit sqlnet.ora with sudo, as in step 6. If the database is only reachable through a bastion, an SSH tunnel also works: ssh -N -L 1521:<db-host>:1521 ec2-user@<bastion> and connect to //localhost:1521/<service-name>.
Step 9: Use the Client from Scripts, Cron and Applications
Instant Client needs no ORACLE_HOME and no LD_LIBRARY_PATH: the libraries are in the system library path, sqlplus is in /usr/bin, and the other tools are linked into /usr/local/bin, so they work from scripts and cron with a plain PATH:
cat /etc/ld.so.conf.d/oracle-instantclient.conf
ls -l /usr/bin/sqlplus /usr/local/bin/sqlldr /usr/local/bin/expdp | awk '{print $9,$10,$11}'
env -i PATH=/usr/local/bin:/usr/bin:/bin sqlldr -help | sed -n '1,3p'
/usr/lib/oracle/23/client64/lib
/usr/bin/sqlplus -> /usr/lib/oracle/23/client64/bin/sqlplus
/usr/local/bin/expdp -> /usr/lib/oracle/23/client64/bin/expdp
/usr/local/bin/sqlldr -> /usr/lib/oracle/23/client64/bin/sqlldr
SQL*Loader: Release 23.26.4.0.0 - Production on Thu Oct 22 01:18:34 2026
Version 23.26.4.0.0
A cron job's default PATH is /usr/bin:/bin, so call the tools other than sqlplus by their /usr/local/bin path there, or set PATH at the top of the crontab. Applications use the libraries directly:
- OCI (C, C++, python-oracledb thick mode, node-oracledb thick mode, PHP OCI8, Perl DBD::Oracle, Go godror): the drivers find
libclntsh.sothrough the system library path; for python-oracledb, calloracledb.init_oracle_client()with no arguments. Install the language driver itself with your own package manager. - Java: the Basic package provides the native JDBC-OCI library (
libocijdbc23.so) for the JDBC OCI driver. The JDBC Thin driver (ojdbc11.jar) is not part of this image: get it from Oracle's JDBC download page or Maven Central (com.oracle.database.jdbc:ojdbc11). - ODBC: the Instant Client ODBC package is not included in this image.
Step 10: Updates
This image ships Oracle's Instant Client release 23.26.4.0.0 as Oracle built it; cloudimg applies no Oracle patch to it. Oracle publishes new Instant Client releases (23.26.x) for everyone, about once a quarter, on its Instant Client download page and in its Oracle Linux 9 Instant Client yum repository, which can lag the download page by some weeks:
- Oracle Instant Client downloads:
https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html - Oracle's Critical Patch Update advisories, which list the security fixes in each quarterly update:
https://www.oracle.com/security-alerts/
To take a newer release from the yum repository, add Oracle's repository definition and upgrade the Instant Client packages; dnf only moves to a release newer than the one installed:
sudo dnf install oracle-instantclient-release-26ai-el9
sudo dnf upgrade 'oracle-instantclient*'
sqlplus -V
To take a release that is on the download page but not yet in the repository, download its el9 Basic, SQL*Plus and Tools RPMs from Oracle, check them against the SHA-256 values on that page, and install them together with sudo dnf install ./oracle-instantclient-*.rpm.
The Oracle Linux packages update themselves: dnf-automatic applies Oracle Linux security errata every day. Check it with:
grep -E '^(upgrade_type|apply_updates)' /etc/dnf/automatic.conf
systemctl is-enabled dnf-automatic.timer
rpm -q --qf '%{NAME} %{VERSION} built %{BUILDTIME:date} by %{VENDOR}\n' oracle-instantclient-basic
upgrade_type = security
apply_updates = yes
enabled
oracle-instantclient-basic 23.26.4.0.0 built Thu 08 Oct 2026 21:31:54 UTC by Oracle Corporation
To apply every available update now, run sudo dnf upgrade and reboot if a new kernel was installed.
Step 11: Security Defaults
sudo ss -tlnp
sudo firewall-cmd --list-services
getenforce
sudo sshd -T | grep -E '^(passwordauthentication|permitrootlogin|x11forwarding|pubkeyauthentication) '
chronyc -n sources | sed -n '1,3p'
State Recv-Q Send-Q Local Address:Port Peer Address:PortProcess
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=668,fd=7))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=668,fd=8))
dhcpv6-client ssh
Enforcing
permitrootlogin no
pubkeyauthentication yes
passwordauthentication no
x11forwarding no
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 169.254.169.123 3 4 177 3 -11us[ -28us] +/- 498us
- Only SSH listens. The image never needs an inbound port beyond 22; keep port 1521 closed on this instance.
- The SSH settings live in
/etc/ssh/sshd_config.d/00-cloudimg.conf, which is read before every other SSH setting. Your EC2 key pair is the only way in; root login and passwords are refused. - SELinux is enforcing and the host firewall (
firewalld) allows SSH only, alongside your security group. - The instance metadata service accepts IMDSv2 requests only (the AMI requires a session token).
- The clock follows the Amazon Time Sync Service (
169.254.169.123), which every subnet reaches without internet access; the time zone is UTC.
Support and licensing
This image is bring your own licence: it includes no Oracle licence. Oracle Instant Client is used under Oracle's Instant Client license terms, and you need your own Oracle Database licence for every database you connect to. The AMI price covers cloudimg's hardening, first boot verification and support for the image.
- Email: support@cloudimg.co.uk
- Website: https://www.cloudimg.co.uk
- Support: 24/7, with a 24 hour response SLA
- Every version in this listing: Oracle Database Client on AWS
For the client tools, see Oracle's Instant Client documentation and the Oracle AI Database 26ai documentation at https://docs.oracle.com/en/database/oracle/oracle-database/26/, in particular the SQL*Plus User's Guide, the Database Utilities guide (SQL*Loader and Data Pump) and the Net Services Administrator's Guide.
Oracle and Java are registered trademarks of Oracle and/or its affiliates. cloudimg is not affiliated with or endorsed by Oracle.