Install a RedHat Enterprise Linux 8.10 VM on VirtualBox with vboxmanage

These steps can be used to setup a RHEL 8.10 VirtualBox guest that can be used as the base OS for the other blog posts. The host system in my case is Windows 10.

Preparation

Download the RHEL 8.10 iso file from RedHat here to the folder c:\sw. If you dont have an RedHat Account you need to create one.
Add the path of vboxmanage to the Windows Path environment variable. This has to be done only once. For example with Win+r and then enter:

rundll32 sysdm.cpl,EditEnvironmentVariables

Add C:\Program Files\Oracle\VirtualBox to the User variable Path.
A directory c:\vms for the virtual machines on the host system should exist:

mkdir c:\vms

Then open a new command prompt to begin the installation.

Install a new RHEL 8.10 VM

Configure the Virtual Machine

In the command prompt set the name of the new virtual machine:

set /p VHOST=Enter VM name: 

Then run these steps to perform the unattended installation. You probably need to adjust the parameter –bridgeadapter1 to the name of your primary interface of the Windows host system (ipconfig /all => see Description)

vboxmanage createvm --name %VHOST% --ostype RedHat8_64 --register
vboxmanage modifyvm %VHOST% --clipboard-mode=bidirectional --drag-and-drop=bidirectional
vboxmanage modifyvm %VHOST% --memory=8192 --cpus=4 --vram=128 --graphicscontroller=vmsvga --usb-ehci=on
vboxmanage setextradata %VHOST% GUI/ScaleFactor 2
vboxmanage storagectl %VHOST% --name "IDE" --add ide
vboxmanage createmedium disk --filename c:\vms\%VHOST%\%VHOST%_1.vdi --size 122880 --variant Standard
vboxmanage storagectl %VHOST% --name "SATA" --add sata --bootable on
vboxmanage storageattach %VHOST% --storagectl "SATA" --port 0 --device 0 --type hdd --medium c:\vms\%VHOST%\%VHOST%_1.vdi
vboxmanage modifyvm %VHOST% --nic1 bridged --bridgeadapter1 "Intel(R) Ethernet Connection (2) I219-LM"
rem if you would like to specify a dedicated mac address:
rem vboxmanage modifyvm %VHOST% --mac-address1=080027EAC935 
vboxmanage sharedfolder add %VHOST% --name=sw --hostpath=c:\sw --automount --auto-mount-point=/sw
vboxmanage showvminfo %VHOST%|findstr /C:"NIC 1"

The last command shows the mac address that the VM will use. Add the IP/mac address to your local dns so that the new machine can retrieve the IP address you want to use for the VM. Now start the unattended installation:

Perform the OS installation

vboxmanage unattended install %VHOST% --iso=c:\sw\rhel-8.10-x86_64-dvd.iso --user=user1 --user-password=root --install-additions --additions-iso=c:\sw\VBoxGuestAdditions_7.1.4.iso --locale=en_US --country=DE --time-zone="Europe/Berlin" --hostname=%VHOST%.fritz.box --start-vm=gui

The installation takes about 20 minutes. Now you are able to login to the system with the IP or hostname you specified in the DNS server (username: root password: root). Now perform these steps:

bash -c "
# change password of root and user1:
passwd root && passwd user1
# set the keyboard if needed
localectl set-keymap de
# register the system with RedHat:
subscription-manager register
# install and update packages:
dnf -y update && dnf -y groupinstall 'Server with GUI' && dnf -y install libnsl bc binutils compat-openssl10 elfutils-libelf glibc glibc-devel ksh libaio libXrender libX11 libXau libXi libXtst  libgcc libnsl libstdc++ libxcb libibverbs make smartmontools sysstat libnsl2 net-tools nfs-utils libstdc++-devel libaio-devel iotop kernel-devel-$(uname -r)
# Recompile Guest Addition kernel modules:
/sbin/rcvboxadd quicksetup all
# disable screen lock for user root
gsettings set org.gnome.desktop.session idle-delay 0
# disable selinux:
sed -i s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
systemctl set-default graphical.target
init 6"

Your system is now ready to use! Have fun.

Further info

If there are errors during the installation you can clean up and do a fresh install with:

set /p VHOST=Enter VM name: 
vboxmanage controlvm %VHOST% poweroff
vboxmanage unregistervm %VHOST% --delete-all
rmdir /S/Q c:\vms\%VHOST%

Some useful Links:

Install SAP NetWeaver 7.52 SP04 TestDrive on Linux

The following steps show how to install a test system of SAP NetWeaver 7.52 SP04 on RHEL 8 (running as a VirtualBox guest). SAP Sybase ASE 16.0.2 is used as the database. SAP GUI will be installed on a client machine running Windows 10 and will be used to access the SAP NetWeaver Application Server. The system will give you an overview of the current SAP ABAP Application server and enable you to develop web applications or explore the SAP client/server architecture in general.

Download the software

Download all files from here under the section SAP NetWeaver AS ABAP Developer Edition 7.52 SP04 You need to create an SAP account to do that. The files should be available on the linux machine under /sw/sap.

Prepare the installation

Unpack the SAP ABAP AS software to /sw/sap/as and add the license

# this step is only needed to install unar since it is not included in RHEL 8 by default
subscription-manager repos --enable codeready-builder-for-rhel-8-$(arch)-rpms
dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
dnf -y install unar
# unpack the software to /sw/sap/as
cd /sw/sap && unar -D -o as TD752SP04part01.rar
# extract license file SYBASE_ASE_TestDrive.lic to /sw/sap/TD752SP04/server/TAR/x86_64/SYBASE_ASE_TestDrive.lic
unar -o - /sw/sap/License.rar License/SYBASE_ASE_TestDrive/SYBASE_ASE_TestDrive.lic > /sw/sap/as/server/TAR/x86_64/SYBASE_ASE_TestDrive.lic
# install required OS packages
dnf -y install uuidd csh
# adjust /etc/hosts and set hostname
echo "11.1.1.172 lin.fritz.box lin" >> /etc/hosts
echo lin > /etc/hostname
init 6

Installation of SAP NetWeaver AS

# this is needed as a workaround to avoid the database being stuck
until [ -f /sybase/NPL/ASE-16_0/install/RUN_NPL ] ; do sleep 0.1 ; done && sed -i 's/NPL.cfg \\/NPL.cfg -T11889 \\/g' /sybase/NPL/ASE-16_0/install/RUN_NPL &
# start the installation
cd /sw/sap/as && ./install.sh

agree to license terms: yes
password (min 8 characters): sapsapsap
The installation takes around 20 minutes.

If the Installation fails with an error you can use the following to clean up and afterwards restart the installation:

pkill -9 -u sapadm
pkill -9 -u npladm
pkill -9 -u sybnpl
userdel -r sapadm 
userdel -r npladm
userdel -r sybnpl
rm -rf /usr/sap/ /sapmnt/ /sybase/ /tmp/sapinst_instdir/
init 6

Installation and Setup of SAP GUI for Windows 7.5

Copy and unzip the SAP Front End installer located in /sw/sap/as/client/SAPGUI4Windows. Start the installation by running 50144807_6\BD_NW_7.0_Presentation_7.50_Comp.2\PRES1\GUI\WINDOWS\Win32\SapGuiSetup.exe Select SAP GUI for Windows 7.50 (Compilation2) and press Next/Next to start the installation


Start SAP Logon and select New Item. Press Next. Configure a New System Entry and press Finish:

Request and Install the license

Get the hardware key of the system by running:

su - npladm -c "/usr/sap/NPL/SYS/exe/run/saplicense -get"

Go to http://www.sap.com/minisap, select NPL - SAP NetWeaver 7.x (Sybase ASE) and request a license key.

Logon to the system with the SAP GUI (Client: 000 User: SAP* Password: Down1oad):


Start transaction slicense (by entering slicense in the text field and pressing Enter). Delete the two existing licenses (right click => Delete License) and add the requested license (right click => Install License, select license file NPL.txt). The demo system is now activated.

Accounts created during the installation

Database Accounts

usernamepassworddescription
SAPSR3master_passwordABAP Schema User
samaster_passwordSuperuser
sapsamaster_passwordSuperuser
sapssomaster_passwordSuperuser

SAP Accounts (can be used with SAP GUI to logon)

usernameclient(s)passworddescription
DEVELOPER001Down1oadDeveloper User
BWDEVELOPER001Down1oadDeveloper User
DDIC000/001Down1oadData Dictionary User
SAP*000/001Down1oadSAP Administrator

Start and Stop of SAP NetWeaver AS

# stop AS and DB
su - npladm -c stopsap
# start AS and DB
su - npladm -c startsap
# check the status of the AS and the DB
su - npladm -c "startsap check"

Further Information

Further information can be found here:
community.sap.com (using the tag #ABAP_trial)
SAP Trial Downloads
readme file: /sw/sap/as/readme.html

AVX on VirtualBox Linux Guest is missing

During the installation of Splunk on a Linux guest I encountered an error where mongod was not able to start. But first an overview of the environment:

  • Host OS: Windows 10 Build 19045
  • Host CPU: Intel Core i7-6700
  • Virtualization software: Oracle VirtualBox 7.1.4
  • Guest OS: Red Hat Enterprise Linux 8.1

After the startup of Splunk I could see the following error messages in the splunk logfile:

12-29-2024 17:35:04.217 +0100 ERROR SidecarThread [33800 MainThread] -  reading standard input
12-29-2024 17:35:04.219 +0100 ERROR SidecarThread [33800 MainThread] -  2024/12/29 17:35:04 Supervisor logs printed at : /opt/splunk/var/log/splunk
12-29-2024 17:35:04.369 +0100 ERROR MongodRunner [34134 MongodLogThread] - mongod exited abnormally (exit code 4, status: PID 34135 killed by signal 4: Illegal instruction) - look at mongod.log to investigate.
12-29-2024 17:35:04.369 +0100 ERROR KVStoreBulletinBoardManager [34134 MongodLogThread] - KV Store process terminated abnormally (exit code 4, status PID 34135 killed by signal 4: Illegal instruction). See mongod.log and splunkd.log for details.
12-29-2024 17:35:04.369 +0100 WARN  KVStoreConfigurationProvider [34134 MongodLogThread] - Action scheduled, but event loop is not ready yet
12-29-2024 17:35:04.369 +0100 ERROR KVStoreBulletinBoardManager [34134 MongodLogThread] - KV Store changed status to failed. KVStore process terminated..

The important bit is:

mongod exited abnormally (exit code 4, status: PID 34135 killed by signal 4: Illegal instruction)

Also starting mongod as root failed (core dumped). After some investigation it looked like the linux guest was missing AVX (can be checked by looking at the flags under cat /proc/cpuinfo) which is needed by mongod.

The solution was to disable Hyper-V as described here:

  • in Windows start a Command Prompt with Administrator privileges
  • Disable Hypervisor Launch: bcdedit /set hypervisorlaunchtype off
  • Disable Microsoft Hyper-V: DISM /Online /Disable-Feature:Microsoft-Hyper-V

The last point required a reboot of Windows. After restarting Windows and the Linux guest AVX was available and mongod started successfully:

[root@lin ~]# cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 94
model name      : Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz
stepping        : 3
cpu MHz         : 3407.996
cache size      : 8192 KB
physical id     : 0
siblings        : 4
core id         : 0
cpu cores       : 4
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 22
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid tsc_known_freq pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single pti fsgsbase bmi1 avx2 bmi2 invpcid rdseed adx clflushopt arat md_clear flush_l1d arch_capabilities
bugs            : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit srbds mmio_stale_data retbleed gds bhi
bogomips        : 6815.99
clflush size    : 64
cache_alignment : 64
address sizes   : 39 bits physical, 48 bits virtual
power management:
[root@lin ~]# /opt/splunk/bin/mongod --version
db version v7.0.14
Build Info: {
    "version": "7.0.14",
    "gitVersion": "ce59cfc6a3c5e5c067dca0d30697edd68d4f5188",
    "openSSLVersion": "OpenSSL 1.0.1e-fips 11 Feb 2013",
    "modules": [
        "enterprise"
    ],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "rhel70",
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}
[root@lin ~]#

How to install Splunk Enterprise on Linux

Basic Installation

These are the steps to install the 60 days trial version of Splunk Enterprise 9.4.0 on RedHat Enterprise Linux 8.1. I used Oracle VirtualBox as the virtualization software running on Windows 10. First we create an account on splunk.com and download the Linux rpm file via wget. As the root user we install the rpm file as follows:

rpm -i splunk-9.4.0.x86_64.rpm
[root@lin Downloads]# rpm -i splunk-9.4.0.x86_64.rpm
warning: splunk-9.4.0.x86_64.rpm: Header V4 RSA/SHA256 Signature, key ID b3cd4420: NOKEY
no need to run the pre-install check
complete
[root@lin Downloads]#

The installation created a user and a group named splunk. We change the password of the splunk user as follows:

passwd splunk << EOF
splunk
splunk
EOF
Changing password for user splunk.
New password: BAD PASSWORD: The password is shorter than 8 characters
Retype new password: passwd: all authentication tokens updated successfully.
[root@lin ~]#

Now we start splunk for the first time. Enter admin as the username and choose a password:

su - splunk
cd /opt/splunk/bin/
./splunk start --accept-license
[root@lin Downloads]# su - splunk
[splunk@lin ~]$ cd /opt/splunk/bin/
[splunk@lin bin]$ ./splunk start --accept-license

This appears to be your first time running this version of Splunk.

Splunk software must create an administrator account during startup. Otherwise, you cannot log in.
Create credentials for the administrator account.
Characters do not appear on the screen when you type in credentials.

Please enter an administrator username: admin
Password must contain at least:
   * 8 total printable ASCII character(s).
Please enter a new password:
Please confirm new password:
Copying '/opt/splunk/etc/openldap/ldap.conf.default' to '/opt/splunk/etc/openldap/ldap.conf'.
Generating RSA private key, 2048 bit long modulus
..+++++
...........................................................+++++
e is 65537 (0x10001)
writing RSA key

Generating RSA private key, 2048 bit long modulus
.......+++++
.................................+++++
e is 65537 (0x10001)
writing RSA key

Moving '/opt/splunk/share/splunk/search_mrsparkle/modules.new' to '/opt/splunk/share/splunk/search_mrsparkle/modules'.

Splunk> Now with more code!

Checking prerequisites...
        Checking http port [8000]: open
        Checking mgmt port [8089]: open
        Checking appserver port [127.0.0.1:8065]: open
        Checking kvstore port [8191]: open
        Checking configuration... Done.
                Creating: /opt/splunk/var/lib/splunk
                Creating: /opt/splunk/var/run/splunk
                Creating: /opt/splunk/var/run/splunk/appserver/i18n
                Creating: /opt/splunk/var/run/splunk/appserver/modules/static/css
                Creating: /opt/splunk/var/run/splunk/upload
                Creating: /opt/splunk/var/run/splunk/search_telemetry
                Creating: /opt/splunk/var/run/splunk/search_log
                Creating: /opt/splunk/var/spool/splunk
                Creating: /opt/splunk/var/spool/dirmoncache
                Creating: /opt/splunk/var/lib/splunk/authDb
                Creating: /opt/splunk/var/lib/splunk/hashDb
                Creating: /opt/splunk/var/run/splunk/collect
                Creating: /opt/splunk/var/run/splunk/sessions
New certs have been generated in '/opt/splunk/etc/auth'.
        Checking critical directories...        Done
        Checking indexes...
                Validated: _audit _configtracker _dsappevent _dsclient _dsphonehome _internal _introspection _metrics _metrics_rollup _telemetry _thefishbucket history main summary
        Done
        Checking filesystem compatibility...  Done
        Checking conf files for problems...
        Done
        Checking default conf files for edits...
        Validating installed files against hashes from '/opt/splunk/splunk-9.4.0-6b4ebe426ca6-linux-amd64-manifest'
        All installed files intact.
        Done
All preliminary checks passed.

Starting splunk server daemon (splunkd)...
Generating a RSA private key
......+++++
..............................+++++
writing new private key to 'privKeySecure.pem'
-----
Signature ok
subject=/CN=lin.fritz.box/O=SplunkUser
Getting CA Private Key
writing RSA key
PYTHONHTTPSVERIFY is set to 0 in splunk-launch.conf disabling certificate validation for the httplib and urllib libraries shipped with the embedded Python interpreter; must be set to "1" for increased security
Done
                                                           [  OK  ]

Waiting for web server at http://127.0.0.1:8000 to be available..................... Done


If you get stuck, we're here to help.
Look for answers here: http://docs.splunk.com

The Splunk web interface is at http://lin.fritz.box:8000

[splunk@lin bin]$

Now we activate systemd to start splunk at boot time:

/opt/splunk/bin/splunk stop
exit
/opt/splunk/bin/splunk enable boot-start -systemd-managed 1 -user splunk
init 6
[splunk@lin bin]$ /opt/splunk/bin/splunk stop
Stopping splunkd...
Shutting down.  Please wait, as this may take a few minutes.
...                                                        [  OK  ]
Stopping splunk helpers...
                                                           [  OK  ]
Done.
[splunk@lin bin]$ exit
logout
[root@lin Downloads]# /opt/splunk/bin/splunk enable boot-start -systemd-managed 1 -user splunk
Systemd unit file installed at /etc/systemd/system/Splunkd.service.
Configured as systemd managed service.
[root@lin Downloads]# init 6

After the server restart we see that the Splunkd service is running:

systemctl status Splunkd
[root@lin ~]# systemctl status Splunkd
● Splunkd.service - Systemd service file for Splunk, generated by 'splunk enable boot-start'
   Loaded: loaded (/etc/systemd/system/Splunkd.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2024-12-29 17:55:30 CET; 5min ago
  Process: 1138 ExecStartPost=/bin/bash -c chown -R splunk:splunk /sys/fs/cgroup/memory/system.slice/Splunkd.service (code=exited, status=0/SUCCESS)
  Process: 1055 ExecStartPost=/bin/bash -c chown -R splunk:splunk /sys/fs/cgroup/cpu/system.slice/Splunkd.service (code=exited, status=0/SUCCESS)
 Main PID: 1054 (splunkd)
    Tasks: 166 (limit: 74402)
   Memory: 1.2G (max: 11.4G)
   CGroup: /system.slice/Splunkd.service
           ├─1054 splunkd --under-systemd --systemd-delegate=yes -p 8089 _internal_launch_under_systemd
           ├─2790 [splunkd pid=1054] splunkd --under-systemd --systemd-delegate=yes -p 8089 _internal_launch_under_systemd [process-runner]
           ├─3972 compsup daemon
           ├─4023 /opt/splunk/var/run/supervisor/pkg-run/pkg-identity4241153237/identity
           ├─4027 /opt/splunk/var/run/supervisor/pkg-run/pkg-agent-manager2026604619/agent-manager
           ├─4070 /opt/splunk/bin/splunkd instrument-resource-usage -p 8089 --with-kvstore
           ├─4125 /opt/splunk/bin/python3.9 /opt/splunk/etc/apps/splunk_secure_gateway/bin/ssg_alerts_ttl_modular_input.py
           ├─4137 /opt/splunk/bin/python3.9 -O /opt/splunk/lib/python3.9/site-packages/splunk/appserver/mrsparkle/root.py --proxied=127.0.0.1,8065,8000
           └─4139 /opt/splunk/bin/python3.9 /opt/splunk/etc/apps/splunk_secure_gateway/bin/ssg_enable_modular_input.py

Dec 29 17:55:38 lin.fritz.box splunk[2446]:                 Validated: _audit _configtracker _dsappevent _dsclient _dsphonehome _internal _introspection _metrics _metrics_rollup _telemetry _thefishbucket history main summary
Dec 29 17:55:38 lin.fritz.box splunk[2446]:         Done
Dec 29 17:55:41 lin.fritz.box splunk[1054]:         Checking filesystem compatibility...  Done
Dec 29 17:55:41 lin.fritz.box splunk[1054]:         Checking conf files for problems...
Dec 29 17:55:41 lin.fritz.box splunk[1054]:         Done
Dec 29 17:55:41 lin.fritz.box splunk[1054]:         Checking default conf files for edits...
Dec 29 17:55:41 lin.fritz.box splunk[1054]:         Validating installed files against hashes from '/opt/splunk/splunk-9.4.0-6b4ebe426ca6-linux-amd64-manifest'
Dec 29 17:55:42 lin.fritz.box splunk[1054]: PYTHONHTTPSVERIFY is set to 0 in splunk-launch.conf disabling certificate validation for the httplib and urllib libraries shipped with the embedded Python interpreter; must be set to "1" for increased security
Dec 29 17:55:42 lin.fritz.box splunk[1054]: 2024-12-29 17:55:42.694 +0100 splunkd started (build 6b4ebe426ca6) pid=1054

At that point I hit an error where the mongod process was not able to start and the log showed:

mongod exited abnormally (exit code 4, status: PID 34135 killed by signal 4: Illegal instruction)

I solved the problem by applying the steps described here. After applying the fix the service starts without error. The desktop / mobile web interface can be accessed with the URL: http://<hostname>:8000 using the username: admin and the password specified during the installation:

Installation of Splunk Mobile

If you want to use the mobile app Splunk Mobile you need to perform some additional tasks. First on the Apps section on the main page select “Splunk Secure Gateway”. I selected the defaults and choose Europe (Central) as the Spacebridge Location as this had the fastest response time for my location. Then select splunk mobile and click next:

A QR code shows up. Now install Splunk Mobile on your mobile and select Sign In and click on the + next to Private Instances. In the Code tab you can select Open Camera to scan this QR code. Thats it. We now have a basic splunk installation running on Linux and the possibility to login with our Desktop or with the mobile app.

Administration of a Oracle Standby Database

This post covers some basic tasks regarding Oracle Standby Databases that can pop up from time to time. The tasks are based on a already existing primary/standby database configuration with Oracle Data Guard Broker. The steps used to setup such a configuration are described here.

Check the health of the Data Guard configuration

Display the overall status

show configurations displays the status of the Data Guard configuration. It should return a Configuration Status: SUCCESS. Be aware that the command does not run any checks. It only outputs the result of the last check which by default could be 60 seconds ‘old’.

show configuration
[oracle@lin ~]$ dgmgrl sys/oracle
DGMGRL for Linux: Release 19.0.0.0.0 - Production on Thu Dec 26 12:58:57 2024
Version 19.25.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

Welcome to DGMGRL, type "help" for information.
Connected to "orcl_lin"
Connected as SYSDBA.
DGMGRL> show configuration

Configuration - dgconf

  Protection Mode: MaxPerformance
  Members:
  orcl_lin  - Primary database
    orcl_lin2 - Physical standby database

Fast-Start Failover:  Disabled

Configuration Status:
SUCCESS   (status updated 45 seconds ago)

DGMGRL>

If you would like to get a ‘fresh’ status of the configuration (by actually running the checks) do this instead:

show configuration verbose
DGMGRL> show configuration verbose

Configuration - dgconf

  Protection Mode: MaxPerformance
  Members:
  orcl_lin  - Primary database
    orcl_lin2 - Physical standby database

  Properties:
    FastStartFailoverThreshold      = '30'
    OperationTimeout                = '30'
    TraceLevel                      = 'USER'
    FastStartFailoverLagLimit       = '30'
    CommunicationTimeout            = '180'
    ObserverReconnect               = '0'
    FastStartFailoverLagGraceTime   = '0'
    FastStartFailoverAutoReinstate  = 'TRUE'
    FastStartFailoverPmyShutdown    = 'TRUE'
    BystandersFollowRoleChange      = 'ALL'
    ObserverOverride                = 'FALSE'
    ExternalDestination1            = ''
    ExternalDestination2            = ''
    PrimaryLostWriteAction          = 'CONTINUE'
    ConfigurationWideServiceName    = 'orcl_CFG'
    FastStartFailoverLagType        = 'APPLY'

Fast-Start Failover:  Disabled

Configuration Status:
SUCCESS

DGMGRL>

Display the database status

show database orcl_lin
DGMGRL> show database orcl_lin

Database - orcl_lin

  Role:               PRIMARY
  Intended State:     TRANSPORT-ON
  Instance(s):
    orcl

Database Status:
SUCCESS

DGMGRL>

Display the transport / apply lag

show configuration lag
DGMGRL> show configuration lag

Configuration - dgconf

  Protection Mode: MaxPerformance
  Members:
  orcl_lin  - Primary database
    orcl_lin2 - Physical standby database
                Transport Lag:      0 seconds (computed 0 seconds ago)
                Apply Lag:          0 seconds (computed 0 seconds ago)

Fast-Start Failover:  Disabled

Configuration Status:
SUCCESS   (status updated 15 seconds ago)

DGMGRL>

Perform a database switchover

A switchover transitions the roles of the primary database and standby database. This means the primary will become a standby and the standby database will become the primary database. To perform a switchover both databases need to be able to communicate with each other.

dgmgrl sys/oracle << EOF
set time on
switchover to orcl_lin2
host sleep 30
show configuration verbose
EOF
[oracle@lin ~]$ dgmgrl sys/oracle
DGMGRL for Linux: Release 19.0.0.0.0 - Production on Thu Dec 26 13:33:47 2024
Version 19.25.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

Welcome to DGMGRL, type "help" for information.
Connected to "orcl_lin"
Connected as SYSDBA.
DGMGRL> set time on
13:33:51 DGMGRL> show configuration

Configuration - dgconf

  Protection Mode: MaxPerformance
  Members:
  orcl_lin  - Primary database
    orcl_lin2 - Physical standby database

Fast-Start Failover:  Disabled

Configuration Status:
SUCCESS   (status updated 22 seconds ago)

13:33:52 DGMGRL> switchover to orcl_lin2
Performing switchover NOW, please wait...
Operation requires a connection to database "orcl_lin2"
Connecting ...
Connected to "orcl_lin2"
Connected as SYSDBA.
New primary database "orcl_lin2" is opening...
Oracle Clusterware is restarting database "orcl_lin" ...
Connected to an idle instance.
Connected to an idle instance.
Connected to an idle instance.
Connected to an idle instance.
Connected to an idle instance.
Connected to "orcl_lin"
Switchover succeeded, new primary is "orcl_lin2"
13:35:20 DGMGRL> show configuration verbose

Configuration - dgconf

  Protection Mode: MaxPerformance
  Members:
  orcl_lin2 - Primary database
    orcl_lin  - Physical standby database

  Properties:
    FastStartFailoverThreshold      = '30'
    OperationTimeout                = '30'
    TraceLevel                      = 'USER'
    FastStartFailoverLagLimit       = '30'
    CommunicationTimeout            = '180'
    ObserverReconnect               = '0'
    FastStartFailoverAutoReinstate  = 'TRUE'
    FastStartFailoverPmyShutdown    = 'TRUE'
    BystandersFollowRoleChange      = 'ALL'
    ObserverOverride                = 'FALSE'
    ExternalDestination1            = ''
    ExternalDestination2            = ''
    PrimaryLostWriteAction          = 'CONTINUE'
    ConfigurationWideServiceName    = 'orcl_CFG'

Fast-Start Failover:  Disabled

Configuration Status:
SUCCESS

13:35:52 DGMGRL>

Perform a database failover

A failover can be done when a primary database fails or has become unreachable. Make sure to connect to the current standby database:

dgmgrl sys/oracle << EOF
set time on
failover to orcl_lin2
show configuration verbose
EOF
[oracle@lin2 ~]$ dgmgrl sys/oracle
DGMGRL for Linux: Release 19.0.0.0.0 - Production on Thu Dec 26 13:49:43 2024
Version 19.3.0.0.0

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

Welcome to DGMGRL, type "help" for information.
Connected to "orcl_lin2"
Connected as SYSDBA.
DGMGRL> set time on
13:49:47 DGMGRL> failover to orcl_lin2
Performing failover NOW, please wait...
Failover succeeded, new primary is "orcl_lin2"
13:51:03 DGMGRL> show configuration verbose

Configuration - dgconf

  Protection Mode: MaxPerformance
  Members:
  orcl_lin2 - Primary database
    orcl_lin  - Physical standby database (disabled)
      ORA-16661: the standby database needs to be reinstated

  Properties:
    FastStartFailoverThreshold      = '30'
    OperationTimeout                = '30'
    TraceLevel                      = 'USER'
    FastStartFailoverLagLimit       = '30'
    CommunicationTimeout            = '180'
    ObserverReconnect               = '0'
    FastStartFailoverAutoReinstate  = 'TRUE'
    FastStartFailoverPmyShutdown    = 'TRUE'
    BystandersFollowRoleChange      = 'ALL'
    ObserverOverride                = 'FALSE'
    ExternalDestination1            = ''
    ExternalDestination2            = ''
    PrimaryLostWriteAction          = 'CONTINUE'
    ConfigurationWideServiceName    = 'orcl_CFG'

Fast-Start Failover:  Disabled

Configuration Status:
SUCCESS

13:51:14 DGMGRL>

As we can see after the failover the old primary database is disabled and needs to be reinstated to be part of the Data Guard configuration again.

Reinstate a database after a failover

To reinstate a database after a failover event follow these steps.
on the failed database run:

sqlplus / as sysdba << EOF
shutdown immediate
startup mount
EOF

on the current primary database run:

dgmgrl sys/oracle << EOF
set time on
show configuration verbose
reinstate database orcl_lin
host sleep 20
show configuration verbose
EOF

Configure the DB client to connect to the current primary node

This is a simple example for a client tnsnames.ora that clients can use to connect to the current primary node of the Data Guard setup. First we create a new pdb:

sqlplus -S / as sysdba << EOF
create pluggable database pdb1 admin user pdb1admin identified by oracle;
alter pluggable database pdb1 open;
alter pluggable database pdb1 save state;
alter session set container=pdb1;
grant select on v_\$instance to pdb1admin;
EOF

Now we have a service that will be active on the current primary node:

lsnrctl services
...
Service "pdb1.fritz.box" has 1 instance(s).
  Instance "orcl", status READY, has 1 handler(s) for this service...
    Handler(s):
      "DEDICATED" established:4164 refused:0 state:ready
         LOCAL SERVER
The command completed successfully
[oracle@lin ~]$
...

Next we add the alias pdb1 to the tnsnames.ora of a client (can be on the server machine or on a separate client machine):

echo "
pdb1=
  (DESCRIPTION=(ADDRESS_LIST=
    (ADDRESS=(PROTOCOL=TCP)(HOST=lin.fritz.box)(PORT=1521))
    (ADDRESS=(PROTOCOL=TCP)(HOST=lin2.fritz.box)(PORT=1521)
  ))
  (CONNECT_DATA=(SERVICE_NAME=pdb1.fritz.box)))  
" >> /u01/app/oracle/product/19.0.0/dbhome_1/network/admin/tnsnames.ora

Using this alias we connect to the first node where the service pdb1.fritz.box is available:

echo "select host_name from v\$instance;"|sqlplus -S pdb1admin/oracle@pdb1
HOST_NAME
----------------------------------------------------------------
lin.fritz.box

After performing a switchover or failover we can see that we are connecting to the new primary node now. In case of a failover make sure that the previous primary db is really unavailable (e.g. shutdown).

echo "select host_name from v\$instance;"|sqlplus -S pdb1admin/oracle@pdb1
HOST_NAME
----------------------------------------------------------------
lin2.fritz.box

Delete old patches from an ORACLE_HOME

It is considered good practice to delete unneeded patches from an ORACLE_HOME in order to save space and reduce the time to install new patches. I made some tests to see the effects of that. More information about the removal of inactive patches can be found in Oracle Doc ID 2942102.1 .

On a Linux System I did an software only installation of Oracle EE 19c (19.3). After that Oracle Release Updates (RU) 19.21 up to 19.25 have been installed. You can see the size of the ORACLE_HOME and the time it took to install the patches in the following table:

OH
Version
OH size
(GB)
patch duration
(min)
19.37
19.20910
19.21129
19.221411
19.231717
19.241921
19.252227

The time it took to install a Release Update increased from 10 minutes to 27 minutes! Also the size of the ORACLE_HOME increased around 3 times the size of the initial installation (19.3).

Now let’s take a look at which patches are considered Active and Inactive:

[oracle@lin2]$ $ORACLE_HOME/OPatch/opatch util listorderedinactivepatches
Oracle Interim Patch Installer version 12.2.0.1.43
Copyright (c) 2024, Oracle Corporation.  All rights reserved.


Oracle Home       : /u01/app/oracle/product/19.0.0/dbhome_1
Central Inventory : /u01/app/oraInventory
   from           : /u01/app/oracle/product/19.0.0/dbhome_1/oraInst.loc
OPatch version    : 12.2.0.1.43
OUI version       : 12.2.0.7.0
Log file location : /u01/app/oracle/product/19.0.0/dbhome_1/cfgtoollogs/opatch/opatch2024-12-25_09-49-57AM_1.log

Invoking utility "listorderedinactivepatches"
List Inactive patches option provided

The oracle home has the following inactive patch(es) and their respective overlay patches:

The number of RU chains is  1

***** There are 5 inactive RU patches in chain 1
-Inactive RU/BP 29517242:Database Release Update : 19.3.0.0.190416 (29517242), installed on: Thu Apr 18 09:21:17 CEST 2019, with no overlays
-Inactive RU/BP 35320081:Database Release Update : 19.20.0.0.230718 (35320081), installed on: Tue Dec 24 22:47:56 CET 2024, with no overlays
-Inactive RU/BP 35643107:Database Release Update : 19.21.0.0.231017 (35643107), installed on: Tue Dec 24 23:04:57 CET 2024, with no overlays
-Inactive RU/BP 35943157:Database Release Update : 19.22.0.0.240116 (35943157), installed on: Tue Dec 24 23:21:13 CET 2024, with no overlays
-Inactive RU/BP 36233263:Database Release Update : 19.23.0.0.240416 (36233263), installed on: Tue Dec 24 23:46:57 CET 2024, with no overlays
-Active RU/BP 36582781:Database Release Update : 19.24.0.0.240716 (36582781), installed on: Wed Dec 25 00:21:56 CET 2024, with no overlays

OPatch succeeded.
[oracle@lin2]$

Now we delete all inactive patches. If we had a running database we didn’t have to stop it:

[oracle@lin2]$ $ORACLE_HOME/OPatch/opatch util deleteinactivepatches -silent
Oracle Interim Patch Installer version 12.2.0.1.43
Copyright (c) 2024, Oracle Corporation.  All rights reserved.


Oracle Home       : /u01/app/oracle/product/19.0.0/dbhome_1
Central Inventory : /u01/app/oraInventory
   from           : /u01/app/oracle/product/19.0.0/dbhome_1/oraInst.loc
OPatch version    : 12.2.0.1.43
OUI version       : 12.2.0.7.0
Log file location : /u01/app/oracle/product/19.0.0/dbhome_1/cfgtoollogs/opatch/opatch2024-12-25_10-11-35AM_1.log

Invoking utility "deleteinactivepatches"
Inactive Patches Cleanup option provided
Delete Inactive Patches .......

***** There are 5 inactive RU patches in chain 1

***** 4 inactive patches will be deleted
-To be deleted inactive RU/BP 29517242:Database Release Update : 19.3.0.0.190416 (29517242), installed on: Thu Apr 18 09:21:17 CEST 2019, with no overlays
-To be deleted inactive RU/BP 35320081:Database Release Update : 19.20.0.0.230718 (35320081), installed on: Tue Dec 24 22:47:56 CET 2024, with no overlays
-To be deleted inactive RU/BP 35643107:Database Release Update : 19.21.0.0.231017 (35643107), installed on: Tue Dec 24 23:04:57 CET 2024, with no overlays
-To be deleted inactive RU/BP 35943157:Database Release Update : 19.22.0.0.240116 (35943157), installed on: Tue Dec 24 23:21:13 CET 2024, with no overlays
-To be retained inactive RU/BP 36233263:Database Release Update : 19.23.0.0.240416 (36233263), installed on: Tue Dec 24 23:46:57 CET 2024, with no overlays
-Active RU/BP 36582781:Database Release Update : 19.24.0.0.240716 (36582781), installed on: Wed Dec 25 00:21:56 CET 2024, with no overlays

Do you want to proceed? [y|n]
Y (auto-answered by -silent)
User Responded with: Y
Deleted RU/BP patch: 29517242
Deleted RU/BP patch: 35320081
Deleted RU/BP patch: 35643107
Deleted RU/BP patch: 35943157

OPatch succeeded.
[oracle@lin2]$

The removal of the inactive patches took 20 minutes and the size of the ORACLE_HOME shrunk down to 14GB. The final test was to find out how long it takes to install RU 19.25 after the inactive patches have been deleted. So I did a rollback of 19.25 and reinstalled 19.25 on top of 19.24 in 11 minutes. Pretty impressive!

Setup a Oracle Physical Standby Database

The following steps can be used to setup a Oracle Physical Standby Database managed by Data Guard Broker. The software versions used are: Oracle 19.25 + ASM (RAC One Node) and RHEL 8.1. On the first node a database (orcl) is already running, on the second node only the database software is installed and an ASM instance with configured diskgroups (DATA and FRA) is running.

Prepare the primary node

# prepare and source environment files containing ORACLE_HOME and ORACLE_SID
# ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1 ORACLE_SID=orcl
source ~/ora19.env
sqlplus / as sysdba << EOF
-- enable archivelog mode on primary
shutdown immediate;
startup mount;
alter database archivelog;
alter database open;
-- enable force logging
alter database force logging;
-- enable flashback database
alter database flashback on;
EOF

sqlplus -S / as sysdba << EOF
set head off
-- create the standby redo logfiles (same size as the normal redo logfiles, 1 group more than the number of the normal redo log groups)
spool /tmp/crsblf1.sql
select 'alter database add standby logfile thread '||thread#||' group '||(group#+10)||' size '||bytes||';' from v\$log;
spool off
@/tmp/crsblf1.sql
spool /tmp/crsblf2.sql
select 'alter database add standby logfile thread '||thread#||' group '||(group#+1)||' size '||bytes||';' from v\$standby_log where group#=(select max(group#) from v\$standby_log);
spool off
@/tmp/crsblf2.sql
-- enable automatic standby file management
alter system set standby_file_management=auto;
EOF

# set the db_unique_name of the primary db to a unique value (s.a. Oracle Doc 1604421.1)
# show current config
srvctl config database -d orcl
sqlplus -S / as sysdba << EOF
set head off lines 200
spool /tmp/s1.sql
select 'host echo "spfile='''||value||'''" >> $ORACLE_HOME/dbs/initorcl.ora' from v\$parameter where name='spfile';
select 'startup' from dual;
select 'alter system set db_unique_name='''||lower(name)||'_'||regexp_substr(host_name, '[^.]*')||''' scope=spfile;' from v\$instance, v\$database;
select 'alter user sys identified by oracle;' from dual;
select 'shutdown immediate' from dual;
spool off
EOF

srvctl stop database -d orcl
srvctl remove database -noprompt -d orcl
echo @/tmp/s1 | sqlplus / as sysdba
srvctl add database -db orcl_lin -dbname orcl -instance orcl -oraclehome $ORACLE_HOME -spfile `cat $ORACLE_HOME/dbs/initorcl.ora|awk -F= {'print $2'}|sed s/\'//g`
srvctl modify database -d orcl_lin -a "DATA,FRA"
srvctl start database -d orcl_lin

Setup the network configuration

# add the following lines to the primary and standby tnsnames.ora:
echo "
orcl_lin=
  (DESCRIPTION=
    (ADDRESS_LIST=
      (ADDRESS=(PROTOCOL=TCP)(HOST=lin)(PORT=1521))
    )
    (CONNECT_DATA=(SID=orcl)
    )
  )

orcl_lin2=
  (DESCRIPTION=
    (ADDRESS_LIST=
      (ADDRESS=(PROTOCOL=TCP)(HOST=lin2)(PORT=1521))
    )
    (CONNECT_DATA=(SID=orcl)
    )
  )
" >> /u01/app/oracle/product/19.0.0/dbhome_1/network/admin/tnsnames.ora
# add the following entries to the standby side
echo "
LISTENER_ORCL =
  (ADDRESS = (PROTOCOL = TCP)(HOST = lin2.fritz.box)(PORT = 1521))

" >> /u01/app/oracle/product/19.0.0/dbhome_1/network/admin/tnsnames.ora
echo "
NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT)
" >> /u01/app/oracle/product/19.0.0/dbhome_1/network/admin/sqlnet.ora
# adjust the listener.ora on the primary side:
vi /u01/app/19.0.0/grid/network/admin/listener.ora
LISTENER=
  (DESCRIPTION_LIST=
    (DESCRIPTION=
      (ADDRESS=(PROTOCOL=TCP)(HOST=lin)(PORT=1521))
      (ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521))
    )
  )

SID_LIST_LISTENER=
  (SID_LIST=
    (SID_DESC=
      (GLOBAL_DBNAME=orcl_lin_DGMGRL.fritz.box)  # set to db_unique_name_DGMGRL.db_domain
      (ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1)
      (SID_NAME=orcl)
      (ENVS='TNS_ADMIN=/u01/app/19.0.0/grid/network/admin')
    )
  )
# adjust the listener.ora on the standby side:
vi /u01/app/19.0.0/grid/network/admin/listener.ora
LISTENER=
  (DESCRIPTION_LIST=
    (DESCRIPTION=
      (ADDRESS=(PROTOCOL=TCP)(HOST=lin2)(PORT=1521))
      (ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521))
    )
  )

SID_LIST_LISTENER=
  (SID_LIST=
    (SID_DESC=
      (GLOBAL_DBNAME=orcl_lin2_DGMGRL.fritz.box)  # set to db_unique_name_DGMGRL.db_domain
      (ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1)
      (SID_NAME=orcl)
      (ENVS='TNS_ADMIN=/u01/app/19.0.0/grid/network/admin')
    )
  )
# restart the listeners on both nodes:
srvctl stop listener && srvctl start listener

Setup the standby node and duplicate the database

# prepare and source environment files containing ORACLE_HOME and ORACLE_SID
# ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1 ORACLE_SID=orcl
source ~/ora19.env
# create directories
mkdir -p /u01/app/oracle/admin/orcl/adump
# create password file (same sys pw as primary side)
orapwd file=$ORACLE_HOME/dbs/orapworcl password=oracle format=12 entries=10
# create a temporary pfile
echo "*.db_name='orcl'" > /tmp/pfile
# start the standby db in nomount mode
echo 'startup nomount pfile=/tmp/pfile' | sqlplus / as sysdba
# duplicate the standby database from the primary database via rman
echo "duplicate target database for standby from active database dorecover spfile set db_unique_name='orcl_lin2' nofilenamecheck;" | rman target sys/oracle@orcl_lin auxiliary sys/oracle@orcl_lin2
# create a spfile in ASM
echo "create spfile='+DATA/ORCL_LIN2/PARAMETERFILE/spfileorcl.ora' from memory;" | sqlplus / as sysdba
echo "spfile='+DATA/ORCL_LIN2/PARAMETERFILE/spfileorcl.ora'" > $ORACLE_HOME/dbs/initorcl.ora
rm $ORACLE_HOME/dbs/spfileorcl.ora
# enable flashback logging and shutdown the database
sqlplus / as sysdba << EOF
alter database archivelog;
alter database flashback on;
shutdown immediate
EOF
# add the db to the Oracle RAC config
srvctl add database -db orcl_lin2 -dbname orcl -instance orcl -oraclehome $ORACLE_HOME -spfile `cat $ORACLE_HOME/dbs/initorcl.ora|awk -F= {'print $2'}|sed s/\'//g`
srvctl modify database -d orcl_lin2 -a "DATA,FRA"
srvctl modify database -db orcl_lin2 -startoption mount
srvctl start database -db orcl_lin2

Create and enable the Data Guard Broker configuration

# start the Data Guard Broker on the primary and on the standby node
echo "alter system set dg_broker_start=true;" | sqlplus / as sysdba
# create and enable the dg configuration on the primary node
dgmgrl sys/oracle@orcl_lin << EOF
create configuration dgconf as primary database is orcl_lin connect identifier is orcl_lin;
add database orcl_lin2 as connect identifier is orcl_lin2;
rem connect identifier is a tnsnames alias
enable configuration
enable database orcl_lin2
host sleep 20
show configuration verbose
quit
EOF

Setup tcps / ssl encrypted database connections using orapki and wallets

This post shows how to setup and use tcps / ssl encrypted database connections. Self signed certificates created by orapki and stored in a Oracle Wallet will be used on the database server and on the client machine. The database server is running Oracle 19.25 on RHEL 8.1. The client machine is running Windows 10.

1. Create the server wallet and a self-signed (root) certificate. Run as the Oracle user on the database server.

# Create a wallet
mkdir ~/wallet && cd ~/wallet
orapki wallet create -wallet `pwd` -pwd test123# -auto_login
# Create a self signed certificate (this creates a CA root certificate and creates a user certificate that is signed by it)
orapki wallet add -wallet `pwd` -dn "CN=`hostname`" -keysize 4096 -self_signed -validity 20 -pwd test123#
# Display the contents of the wallet
orapki wallet display -wallet `pwd`

2. Adjust sqlnet.ora and listener.ora on the database server and start the ssl listener

sqlnet.ora:
WALLET_LOCATION=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY=/home/oracle/wallet)))
SQLNET.AUTHENTICATION_SERVICES=(BEQ,TCPS)
SSL_CLIENT_AUTHENTICATION=FALSE

listener.ora:
SSL_CLIENT_AUTHENTICATION = FALSE
WALLET_LOCATION=(SOURCE=(METHOD = FILE)(METHOD_DATA=(DIRECTORY=/home/oracle/wallet)))
LISTENER_SSL=
  (DESCRIPTION_LIST=
    (DESCRIPTION=
      (ADDRESS=(PROTOCOL=TCPS)(HOST=lin2.fritz.box)(PORT=1522))))
SID_LIST_LISTENER_SSL=
  (SID_LIST=
    (SID_DESC=
      (GLOBAL_DBNAME=orcl.fritz.box)
      (ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1)
      (SID_NAME=orcl)))

lsnrctl start listener_ssl

# Adjust the database so that it registers its services with the listener
alter system set local_listener='LISTENER_ORCL,(ADDRESS=(PROTOCOL=TCPS)(HOST=lin2.fritz.box)(PORT=1522))';  (LISTENER_ORCL already existed)
alter system register; (registers the services to the new listener. Can be checked with lsnrctl services listener_ssl)

3. Create a wallet which can be copied and used on a client. Run as the Oracle user on the database server.

mkdir ~/clientwallet && cd ~/clientwallet
orapki wallet create -wallet `pwd` -pwd clienttest123# -auto_login
# Export the server certificate and import in the client wallet
orapki wallet export -wallet ~/wallet -dn "CN=`hostname`" -cert server.cer
orapki wallet add -wallet `pwd` -dn "CN=`hostname`" -trusted_cert -cert server.cer -pwd clienttest123#
# Display the contents of the wallet
orapki wallet display -wallet `pwd`

4. Preparation of the client sqlnet.ora and listener.ora on the database server.

cd ~/clientwallet
sqlnet.ora:
WALLET_LOCATION=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY="C:\sw\cwallet")))
SSL_CLIENT_AUTHENTICATION=FALSE
SSL_SERVER_DN_MATCH=ON

tnsnames.ora:
orcl_ssl=
  (DESCRIPTION=
    (ADDRESS_LIST=
      (ADDRESS=(PROTOCOL=TCPS)(HOST=lin2.fritz.box)(PORT=1522)))
    (CONNECT_DATA=
      (SERVICE_NAME=orcl.fritz.box)
      (SERVER=dedicated))
      (SECURITY=
        (SSL_SERVER_CERT_DN="CN=lin2.fritz.box")))

5. Implement the client wallet in the SQL Developer + use the client wallet with SQL*Plus

cd ~/clientwallet && zip ../cwallet.zip *
Copy cwallet.zip to the client machine
Create a SQL Developer connection of type 'Cloud Wallet' and select cwallet.zip. 
Select the tns alias for the connection
test the tcps connection with: select sys_context('USERENV', 'NETWORK_PROTOCOL') from dual;    (must be tcps)

Test the connection with sqlplus from the client machine:
 mkdir c:\sw\cwallet && cd c:\sw\cwallet && tar -xf c:\sw\cwallet.zip
 set TNS_ADMIN=C:\sw\cwallet
 rem test the tcps connection with:
 tnsping orcl_ssl
 sqlplus sys@orcl_ssl as sysdba  or  sqlplus sys@tcps://lin2.fritz.box:1522/orcl.fritz.box as sysdba
 select sys_context('USERENV', 'NETWORK_PROTOCOL') from dual;  (must be tcps)