Tag: linux

  • Fix GPG Check Failed Error on RHEL 10.1

    Overview

    On some RHEL 10.1 installs users are running into this error, post-install, when attempting to install packages via dnf.

    Unsure if the issue is isolated to users attempting to install RHEL via the full DVD ISO, from the minimal boot ISO, and users deploying RHEL 10.1 via kickstart.

     GPG Keys are configured as: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
    The GPG keys listed for the "Red Hat Enterprise Linux 10 for x86_64 - AppStream (RPMs)" repository are already installed but they are not correct for this package.
    Check that the correct key URLs are configured for this repository.. Failing package is: gnupg2-smime-2.4.5-3.el10_1.x86_64
     GPG Keys are configured as: file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
    The downloaded packages were saved in cache until the next successful transaction.
    You can remove cached packages by executing 'yum clean packages'.
    Error: GPG check FAILED

    More Details

    The issue is caused by GPG keys installed in /etc/pki/rpm-gpg, specifically RPM-GPG-KEY-redhat-release

    This issue is being tracked via BUG RHEL-144980


    Workaround

    I am currently aware of two workaround, one manual, one much more simple. Details below


    Workaround #1 (Simple)

    Use dnf to install new GPG keys used via dnf

    $ sudo dnf update redhat-release

    After doing so you should run the following

    $ sudo dnf clean all

    You should now be able to update RHEL and install additional RPMs.


    Workaround #2 (manual)

    You can delete the current key in “/etc/pki/rpm-gpg”

    Delete the following

    • RPM-GPG-KEY-redhat-release
    • RPM-GPG-KEY-redhat-beta (if applicable)

    Then SCP known working copies of the keys that you just deleted from a RHEL 10.1 host that is not experiencing this issue. I would suspect an earlier build of RHEL 10.1 or possibly a later build or RHEL 10.1 once available will not experience this issue.

    Once you replace the keys, clean up dnf cache

    $ sudo dnf clean-all
  • Moving Beyond OMSA: A Guide to Dell iSM Installation on RHEL 10 and PowerEdge R730

    Moving Beyond OMSA: A Guide to Dell iSM Installation on RHEL 10 and PowerEdge R730

    The shift from srvadmin (OMSA) to iSM (iDRAC Service Module) marks the end of bloated, “in-band” server management. This occurred between Dell 12th gen and Dell 13th gen server.

    If you have a 12th Gen Dell Server, you can still leverage Dell srvadmin (Idrac 7). I wrote a post on it here.

    While OMSA ran as a heavy suite of services directly on the host, the modern dcism acts as a lightweight bridge that offloads the heavy lifting to the dedicated iDRAC hardware.

    For RHEL 10 users, this transition is no longer optional but necessary, trading the aging omreport ecosystem for a more secure, stable, and kernel-friendly management experience.

    So in this post we are going to go through the install of DISM (Dell IDRAC Service Module), on RHEL 10, running on a Dell R730.


    Set Up the Dell Repository

    First we need to setup the official Dell System Update (DSU) utility. Install Dell GPG keys when prompted.

    curl -O https://linux.dell.com/repo/hardware/dsu/bootstrap.cgi
    bash bootstrap.cgi

    Install the ISM Package

    dnf install dcism

    Also install racadm

    sudo dnf install srvadmin-idracadm7

    Start and Enable the Service

    sudo systemctl enable --now dcismeng.service
    systemctl status dcismeng.service

    Example Commands

    This first command will make sure that DISM is healthy

    /opt/dell/srvadmin/iSM/bin/dcismcfg --getismstatus

    And ensure that racadm is functioning properly

    /opt/dell/srvadmin/sbin/racadm getsysinfo

    You can also reset the idrac from the OS

    /opt/dell/srvadmin/iSM/bin/Invoke-iDRACHardReset

    You can generate a full hardware diagnostic bundle directly from the (TSR).

    Note that the used Dell R730 that I just purchased on Ebay is actually under hardware support till October of 2026 – so if I need on-site hardware support a Dell technician will be dispatched to my house. I will provide snacks and a static strap.

    /opt/dell/srvadmin/iSM/bin/Invoke-SupportAssistCollection

    Note: The SupportAssist Collection feature is not supported on systems earlier than 14th generation. 🙁

    You can check your disks for SMART errors

    /opt/dell/srvadmin/iSM/bin/ismsmartlog --dev=/dev/sdb

    Local RAID & Storage Management

    Since omreport storage is gone, use racadm. With the iSM bridge active, Local RACADM is now your primary interface for your raid controller

    racadm storage get pdisks
    racadm storage get vdisks
    racadm storage get controllers

    The “Full Power Cycle” (The “Cold Boot” Tool) – Flea Power Drain

    On an R730, if you have a hardware component acting up (like a hung NIC), a standard OS reboot often isn’t enough because the motherboard stays powered.

    • What it does: It tells the iDRAC to perform a “virtual” AC power pull. The server will shut down, the flea power will be drained, and it will cold-boot. This is a powerful feature to have in a remote RHEL 10 environment.
     /opt/dell/srvadmin/iSM/bin/Invoke-FullPowerCycle

    Real-Time “Tech Support Report” (TSR)

    If you ever need to open a support ticket with Dell, they will ask for a TSR. Previously, you had to log into the iDRAC web UI and wait 10 minutes.

    • What it does: It triggers the iDRAC to gather every log, firmware version, and hardware event into a .zip file and saves it directly to the iDRAC (or can be pulled to the OS).
    /opt/dell/srvadmin/iSM/bin/Invoke-SupportAssistCollection

    Viewing Active Hardware Alerts

    The racadm utility (which uses the iSM bridge) is the best way to see why your server has an amber light or a “System Health” warning.

    • View the System Event Log (SEL): This is the “Hardware Event Viewer.” It shows power supply failures, memory errors, and thermal trips.
    /opt/dell/srvadmin/sbin/racadm getsel

    Installing perccli

    PERCCLI (PowerEdge RAID Controller Command Line Interface) is the specialized successor to the older MegaCLI tool. While RACADM is great for general server health, PERCCLI is the “surgical tool” specifically for your RAID controller (like the H730 in your R730).

    Install as shown below

    dnf -y install perccli.noarch

    Now you can show all controllers

     /opt/MegaRAID/perccli/perccli64 show

    Show events.

     /opt/MegaRAID/perccli/perccli64 /c0 show eventloginfo

    Show all disks

    /opt/MegaRAID/perccli/perccli64 /c0/eall/sall show

    Epilogue

    So in a nutshell. Dell srvadmin was replaced with DISM starting on Dell 13th gen servers. You have a couple powerful commands at your disposal with a ton of various ways to run both of them.

    Also available is perccli, which is also a nice tool on its own.

  • Dell OpenManage Server Administrator: Comprehensive Guide for Hardware Monitoring (RHEL)(Dell 12 Gen)

    Dell OpenManage Server Administrator: Comprehensive Guide for Hardware Monitoring (RHEL)(Dell 12 Gen)

    Dell OpenManage Server Administrator (OMSA) is Dell’s on-host hardware management and monitoring framework for PowerEdge servers. 

    It runs inside the operating system and provides direct visibility into system hardware such as RAID controllers, physical and virtual disks, power supplies, fans, temperatures, memory, processors, and chassis health. 

    OMSA communicates with the server’s iDRAC and hardware controllers to retrieve real-time status and exposes this information through command-line tools like omreport, optional web interfaces, and SNMP for monitoring systems.

     It is primarily used for hardware diagnostics, RAID and storage monitoring, fault detection, and health reporting, allowing administrators to verify system integrity and troubleshoot hardware issues without leaving the operating system.

    So now that we have an idea of what it is, lets install it.

    Note: Our system under test is a Dell R720. I probably should have lead with that.


    Installation

    First you will need to download the bootstrap script as shown below.

    curl -O https://linux.dell.com/repo/hardware/dsu/bootstrap.cgi

    Now we will make it executable.

    chmod +x bootstrap.cgi

    And then we run it.

    sudo ./bootstrap.cgi

    Now we have completed the following.

    • Added Dell’s official repo
    • Installed Dell signing keys
    • Configured OMSA package sources

    Now Install OpenManage (omreport)

    sudo dnf install srvadmin*

    This installs:

    • omreport
    • omconfig
    • Storage monitoring
    • RAID tools
    • CIM providers

    Starting and Enabling Services

    Apparently, service names can vary from OS to OS, so run the command below to verify the correct service names

    systemctl list-unit-files | grep -Ei 'dsm|omsa|srvadmin'
    dsm_om_connsvc.service enabled disabled
    dsm_om_shrsvc.service disabled disabled
    dsm_sa_datamgrd.service enabled disabled
    dsm_sa_eventmgrd.service enabled disabled
    dsm_sa_snmpd.service enabled disabled

    Now that we have the names of the services we can start and enable them as shown below

    # sudo systemctl enable --now dsm_om_connsvc dsm_sa_datamgrd dsm_sa_eventmgrd dsm_sa_snmpd dsm_om_shrsvc

    OpenManage Server Administrator (OMSA) Services
    Service NameFull NamePurposeRequired?Notes
    dsm_om_connsvcOMSA Connection ServiceProvides the web-based interface (HTTPS/1311) used to access OMSA remotely or locally✅ Yes (if using OMSA web UI)This is what allows access via https://<host&gt;:1311
    dsm_om_shrsvcOMSA Shared ServicesProvides shared libraries and backend support for other OMSA components⚠️ UsuallyRequired by other OMSA components; often left disabled unless needed
    dsm_sa_datamgrdSystems Management Data ManagerCollects and maintains hardware inventory and system data✅ YesRequired for hardware monitoring (disks, temps, fans, etc.)
    dsm_sa_eventmgrdSystems Management Event ManagerHandles hardware events, alerts, and logs✅ YesRequired for alerts and log reporting
    dsm_sa_snmpdOMSA SNMP AgentProvides SNMP interface for monitoring tools (LibreNMS, Zabbix, etc.)⚠️ OptionalNeeded only if using SNMP monitoring

    Service Review

    Now let’s review each service in detail, and see how we can leverage each one.


    dsm_om_connsvc

    First we need to ensure our Firewall allows this traffic. So run the commands below (RHEL), ubuntu may use ufw.

    # firewall-cmd --permanent --add-port=1311/tcp
    # firewall-cmd --reload

    Now in your web browser, navigate to https://viper.lab:1311/ (Note https, and change host name accordingly).

    Similar in appearance to the Idrac – you can find system information here, some of which does not appear in the Idrac itself. Everything is read-only.

    Screenshot of Dell OpenManage Server Administrator showing Fan Probes Information, including fan redundancy status and probe list with readings, thresholds, and status indicators.

    dsm_om_shrsvc

    (OMSA Shared Services) is a supporting service, not a management interface or monitoring agent.

    It provides:

    • Shared libraries
    • Inter-process communication
    • Authentication helpers
    • Common backend utilities

    These are required by other OMSA components to function correctly. So nothing really to see here.


    dsm_sa_datamgrd.service

    This is the service that collects all the data that is displayed in the WebUI (port 1311)


    dsm_sa_eventmgrd.service

    dsm_sa_snmpd.service is the OMSA component responsible for exposing Dell hardware monitoring data to external systems using the SNMP protocol. 

    This service does not collect or analyze hardware information itself; instead, it serves as the communication layer that allows remote systems to query or receive notifications about server health. When enabled, it allows OMSA to participate in centralized monitoring environments and enterprise alerting workflows, making it essential in environments where hardware status must be visible outside the server itself.

    This service relies entirely on the existing system SNMP configuration, so no need to modify anything if you already have snmp configured and running with your specfic community string.


    dsm_sa_snmpd.service

    dsm_sa_snmpd.service is the OMSA component responsible for exposing Dell hardware monitoring data to external systems using the SNMP protocol. 

    It acts as the interface between the data collected internally by OMSA and third-party monitoring platforms such as LibreNMS, Zabbix, or Nagios. 

    This service does not collect or analyze hardware information itself; instead, it serves as the communication layer that allows remote systems to query or receive notifications about server health. When enabled, it allows OMSA to participate in centralized monitoring environments and enterprise alerting workflows, making it essential in environments where hardware status must be visible outside the server itself.

    dsm_sa_snmpd.service acts as the Dell OMSA integration layer between the server’s hardware telemetry and the system’s SNMP stack, allowing Dell-specific health, storage, and sensor data to be exposed through standard SNMP queries. 

    It does not replace or conflict with existing monitoring agents such as Zabbix or LibreNMS (which I am using) Instead, it complements them by extending the SNMP data they can read

    dsm_sa_snmpd provides access to Dell-specific MIBs that Zabbix Agent and LibreNMS Agent (or any other agent you may use) can query via the system’s SNMP daemon. 

    Basically, dsm_sa_snmpd is the bridge that exposes OMSA’s hardware awareness to your existing monitoring stack.
    Note that if you are using Zabbix you will need to install additional templates. For example, this one, note that I have not tried it yet.

    Ompreport

    Omreport is the command-line interface (CLI) frontend for OMSA. It queries the OMSA backend services and formats the results for humans or scripts

    Note we have to use the absolute path to run this as the working dir is not in our $PATH.

    /opt/dell/srvadmin/sbin/omreport system summary

    If you want to add to your $PATH, run the command below

    echo 'export PATH=$PATH:/opt/dell/srvadmin/sbin' | sudo tee /etc/profile.d/dell-omsa.sh
    source /etc/profile

    Example usage below.

    omreport system summary
    omreport chassis temps
    omreport chassis fans
    omreport chassis power

    Here is an example I found useful. For some reason my raid controller keeps throwing these errors which do not seem to go away despite the fact that both SAS cables are connected (tried switching them) and all disks are healthy.

    # omreport system esmlog
    Severity : Critical
    Date and Time : Sat Jan 31 21:15:18 2026
    Description : The storage BP1 SAS B cable is not connected, or is improperly connected.
    Severity : Ok
    Date and Time : Sat Jan 31 21:15:20 2026
    Description : The chassis is closed while the power is off.
    Severity : Critical
    Date and Time : Sat Jan 31 21:15:21 2026
    Description : The storage BP1 SAS A cable is not connected, or is improperly connected.

    Enter omconfig.


    omconfig

    omconfig is the configuration and control interface for Dell OpenManage Server Administrator (OMSA). 

    Unlike omreport, which is strictly read-only, omconfig is used to change system and OMSA behavior—including alerting, storage actions, and certain hardware-related settings exposed by OMSA. 

    Omconfig It operates by issuing commands to the OMSA backend services (primarily dsm_sa_datamgrd and dsm_sa_eventmgrd) and applying those changes at the software management layer, not directly to hardware firmware. 

    Common uses include enabling or disabling alert actions, configuring storage-related behavior, managing notification settings, and triggering maintenance operations such as consistency checks. 
    Because omconfig can modify system behavior and suppress alerts, it should be used carefully—especially on production systems—and is best suited for controlled configuration changes rather than routine monitoring.

    Because omconfig can modify system behavior and suppress alerts, it should be used carefully—especially on production systems—and is best suited for controlled configuration changes rather than routine monitoring.

    So back to my two SAS cable alerts. Lets leverage omreport and omconfig to diagnose and hopefully ether determine that there is an actual issue, or suppress the alerts.


    OMCONFIG and OMREPORT – Real world Usage

    First lets take a sneaky-peak at my raid controller.

    omreport storage controller
    Controller PERC H730 Adapter(Slot 4)
    Controller
    ID : 0
    Status : Ok
    Name : PERC H730 Adapter
    Slot ID : PCIe Slot 4
    State : Ready
    Firmware Version : 25.5.9.0001
    -----truncated---

    According to chatgpt I am getting these errors because the system expects that I have an external enclosure connected. I do not think that is the case, as that seems dumb. More than likely this alert is due to the fact that I am using an H730 (a 13G controller) (and its cables) in an R720 (a 12G server) in Slot 4, which is a PCIe Adapter and not the integrated “mini” version.

    So let’s look at the disks and make sure all is well

    Here we can see that the PERC H730 adapter does not “See” the connector states as connected, rather just ready

    omreport storage connector controller=0
    List of Connector(s) on Controller PERC H730 Adapter (Slot 4)
    ID : 0
    Status : Ok
    Name : Connector 0
    State : Ready
    Connector Type : SAS Port RAID Mode
    Termination : Not Applicable
    SCSI Rate : Not Applicable
    ID : 1
    Status : Ok
    Name : Connector 1
    State : Ready
    Connector Type : SAS Port RAID Mode
    Termination : Not Applicable
    SCSI Rate : Not Applicable

    In order to use this 13th gen raid controller in a 12th gen Dell Server I could not use the original SAS cables. Rather I used SFF-8087 to SFF-8643 cables Which can cause the sideband signals (SGPIO / SES) which tell the iDRAC everything is okay which is why we are seeing the errors.

    As stated above this is not actually a problem as I can see my disks. Lets do that below.

    omreport storage pdisk controller=0 | awk '
    /^ID[[:space:]]*:/ {id=$3; state=""; status=""}
    /^State[[:space:]]*:/ {state=$3}
    /^Status[[:space:]]*:/ {status=$3}
    (state!="" && status!="" && id!="") {print id, state, status; id=""; state=""; status=""}
    '
    0:0 Online Non-Critical
    0:1 Online Non-Critical
    0:2 Online Non-Critical
    0:3 Online Non-Critical
    0:4 Online Non-Critical
    0:5 Online Non-Critical
    0:6 Online Non-Critical
    0:7 Online Non-Critical

    Here we can see we have 8 disks, no critical errors

    First lets clear the esmlog with omconfig – this will clear the error till we reboot

    omconfig system esmlog action=clear

    Sadly there is not a permanent fix. I would need to get a different raid controller that uses the original cables.


  • Setting up Chrony/NTP Server with GPS on Ubuntu 22.04

    Setting up Chrony/NTP Server with GPS on Ubuntu 22.04

    Introduction

    In this post I will cover setting up a ntp/chrony server on Ubuntu 22.04 using a Satellite GPS Receiver. I have also recently published another post on Chrony, which goes a bit more into basic commands. That post can be found here.


    Hardware

    Note: the GlobalSat BU-353-W11 does not support 1pps. It’s designed primarily for positioning and navigation, not precision timing. We can use it as our timesource for chrony, with a typical accuracy: ±50–150 ms. Good enough for a lab.


    Hardware Detection

    After plugging in the USB cable on the GNSS module, check for a new USB device.

    # lsusb
    Bus 001 Device 004: ID 1546:01a7 U-Blox AG [u-blox 7]

    Output from dmegs also shows the device was detected properly

    [347055.572498] usb 1-2.4: new full-speed USB device number 4 using tegra-xusb
    [347055.768706] cdc_acm 1-2.4:1.0: ttyACM0: USB ACM device
    [347055.768784] usbcore: registered new interface driver cdc_acm
    [347055.768788] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters

    In the output above you can see the device was detected ttyACM0. Now we need to confirm how the device was enumerated. As you can see the device is owned by root and the group is dialout

    # ls -l /dev/ttyACM*
    crw-rw---- 1 root dialout 166, 0 Dec 29 13:40 /dev/ttyACM0
    
    

    You can run a quick check to confirm that the device is functioning as shown below

    # cat /dev/ttyACM0
    $GPTXT,01,01,02,u-blox ag - www.u-blox.com*50
    
    $GPTXT,01,01,02,HW  UBX-G70xx   00070000 FF7FFFFFo*69
    
    $GPTXT,01,01,02,ROM CORE 1.00 (59842) Jun 27 2012 17:43:52*59
    
    $GPGGA,201055.00,3356.15827,N,08345.15611,W,2,12,0.80,280.0,M,-31.5,M,,0000*67
    
    -----------truncated----------------

    GPSD

    To use a GPS/GNSS antenna with chronyd on Linux for time synchronization and location sharing, we will use the gpsd service to manage the GPS hardware and make its data accessible to other applications, including chronyd

    Package Installation

    # sudo apt update
    # sudo apt install gpsd gpsd-clients chrony pps-tools 

    GPSD Configuration

    Identify the GPS device: The device will likely be /dev/ttyUSB0, /dev/ttyACM0, or similar. You can verify this by running cat /dev/ttyUSB0 (replace ttyUSB0 with your suspected device) and looking for NMEA strings (lines starting with $GPGGA, $GNRMC, etc.).

    Edit the gpsd configuration file: Open /etc/default/gpsd and set the DEVICES, GPSD_OPTIONS, and USBAUTO variables.

    START_DAEMON="true"
    GPSD_OPTIONS="-n -b"
    DEVICES="/dev/ttyACM0"
    USBAUTO="false"
    GPSD_SOCKET="/var/run/gpsd.sock"
    

    For reference here are configuration params for GPSD_OPTIONS

    FlagArgumentMeaningNotes
    -nnoneStart reading GPS immediatelyRequired for chrony/NTP
    -bnoneRead-only mode (no device writes)Recommended for USB pucks
    -NnoneRun in foregroundDebug only
    -D<level>Debug verbosityUse -D 2 or -D 3
    -F<path>Control socket pathNeeded for manual runs
    -s<baud>Force serial baud rateUART devices only
    -S<port>TCP listening portRare; usually disabled
    -GnoneAllow remote TCP clientsAvoid on servers
    -lnoneList drivers and exitDiagnostic
    -VnoneShow version and exitInformational
    -hnoneHelp outputReference

    Enable and start gpsd

    # sudo systemctl enable gpsd
    # sudo systemctl restart gpsd

    Verify gpsd is receiving data

    # cgps -s
    

    Output below

    Screen output from a GPSD client showing real-time GPS data, including time, latitude, longitude, altitude, speed, and satellite information.

    Interpreting the output from cgps

    High-Level Status (The Big Picture)

    • (Satellites) Seen / Used: 13 / 11
    • Fix: 3D DGPS FIX – means the receiver has solved all three spatial dimensions: (Latitude, Longitude, Altitude)
    • Time is valid
    • Position accuracy: ~5–10 feet horizontal

    Satellite Section (Right Pane)

    Seen 13 / Used 11
    

    This means:

    • The receiver can currently see 13 satellites
    • 11 of those are strong enough to be used in the solution

    This is quite a healthy signal for a device sitting inside up against a window.

    Anything above:

    • 4 used → valid 3D fix
    • 8+ used → very solid geometry
    • 10–12 used → excellent (we are here)

    Constellations

    • GP = GPS
      • U.S. GPS constellation
      • Medium Earth Orbit (≈20,200 km)
      • ~30 active satellites worldwide
    • SB = SBAS (WAAS corrections)
      • Satellite-Based Augmentation System
      • Broadcast correction data
      • Improve accuracy of GPS measurements
      • Do not provide independent position fixes

    The presence of SBAS satellites indicates differential reminder data is available, improving accuracy.

    Fix & Timing (Left Pane)

    Fix State

    Status: 3D DGPS FIX (1 secs)
    
    • 3D = Latitude, longitude, altitude solved
    • DGPS = WAAS corrections applied
    • (1 secs) = Fix age (very fresh)

    Time Quality

    Time: 2025-12-29T20:32:22.000Z
    Time offset: 0.078609772 s
    


    Chrony

    Install Chrony via apt

    # apt install chrony -y

    Configure Chrony

    Edit /etc/chrony/chrony.conf. This config has been tested on Ubuntu 22.04, YMMV on other Linux versions.

    ###############################################################################
    # Chrony configuration
    #
    # Purpose:
    # – Discipline system time using a USB GPS receiver via gpsd (NMEA-only)
    # – No PPS available, so accuracy is milliseconds (not microseconds)
    # – Act as a low-priority NTP server for the local network
    #
    # Notes:
    # – Chrony always operates internally in UTC
    # – GPS time is provided by gpsd over a UNIX socket
    ###############################################################################
    #——————————————————————————
    # Include additional configuration snippets
    #——————————————————————————
    # Allows drop-in configuration files (not required, but standard on Ubuntu)
    confdir /etc/chrony/conf.d
    ###############################################################################
    # Debug / observability
    ###############################################################################
    # Where chrony writes its own detailed log streams
    logdir /var/log/chrony
    # Enable detailed logs:
    # – tracking: disciplined clock state (offset/freq/skew, etc.)
    # – measurements: raw samples from sources (very useful for refclocks)
    # – statistics: aggregate stats per source
    log tracking measurements statistics
    # Log when chrony makes a clock correction bigger than the thresholds
    # (units: seconds). Helps correlate “why did time jump?” events.
    logchange 0.5
    #——————————————————————————
    # GPS reference clock (via gpsd)
    #——————————————————————————
    # Use gpsd's UNIX socket as a reference clock.
    #
    # SOCK /var/run/gpsd.sock
    # – Chrony does NOT talk to the GPS device directly
    # – gpsd parses NMEA and provides time samples
    #
    # refid GPS
    # – Human-readable label shown in chronyc output
    #
    # poll 4
    # – Poll interval = 2^4 seconds = 16 seconds
    #
    # precision 1e-1
    # – Declare expected precision (~100 ms)
    # – REQUIRED for NMEA-only GPS to avoid sample rejection
    #
    # delay 0.2
    # – Account for USB + NMEA sentence latency
    #
    # trust
    # – Explicitly allow chrony to accept this low-precision refclock
    #
    #refclock SOCK /run/gpsd.sock refid GPS poll 4 precision 1e-1 delay 0.2 trust prefer
    refclock SHM 0 refid GPS poll 4 precision 1e-1 delay 0.2 trust prefer
    #——————————————————————————
    # Standalone operation policy
    #——————————————————————————
    # Allow chrony to discipline the system clock even if:
    # – No network NTP servers are configured
    # – GPS is the only available reference
    #
    # Advertise this host as stratum 10 to NTP clients:
    # – Prevents it from being treated as an authoritative time source
    # – Avoids NTP loops
    # – Appropriate for NMEA-only GPS (no PPS)
    #
    local stratum 2
    #——————————————————————————
    # Clock stepping behavior
    #——————————————————————————
    # Allow the system clock to be stepped (jumped) instead of slewed
    # if the offset is larger than 1 second, but ONLY during startup
    # and only for the first 3 updates.
    #
    # This prevents long convergence times on boot while avoiding
    # disruptive time jumps during normal operation.
    #
    makestep 1.0 3
    #——————————————————————————
    # Frequency drift handling
    #——————————————————————————
    # Persist the measured frequency error of the system clock.
    #
    # This allows chrony to:
    # – Start with a good frequency estimate after reboot
    # – Converge faster
    # – Free-run more accurately if all time sources disappear
    #
    driftfile /var/lib/chrony/chrony.drift
    #——————————————————————————
    # NTP server behavior (serving time to clients)
    #——————————————————————————
    # Allow NTP clients from the local subnet to query this server
    #
    allow 10.1.10.0/24
    # Bind NTP service explicitly to this interface/address
    # (prevents listening on unintended interfaces)
    #
    bindaddress 10.1.10.11
    #——————————————————————————
    # Optional dynamic source handling
    #——————————————————————————
    # Allow chrony to use NTP servers provided via DHCP (if present)
    #
    sourcedir /run/chrony-dhcp
    # Allow additional NTP source files to be added modularly
    #
    sourcedir /etc/chrony/sources.d
    #——————————————————————————
    # Security and key material
    #——————————————————————————
    # File containing NTP authentication keys (if used)
    #
    keyfile /etc/chrony/chrony.keys
    # Directory used to store NTS (Network Time Security) cookies and keys
    #
    ntsdumpdir /var/lib/chrony
    #——————————————————————————
    # Logging
    #——————————————————————————
    # Directory where chrony logs are written
    #
    logdir /var/log/chrony
    # Uncomment the following line to enable detailed logging:
    # log tracking measurements statistics
    #——————————————————————————
    # Stability and safety controls
    #——————————————————————————
    # Prevent chrony from applying updates if clock estimates become unstable
    #
    maxupdateskew 100.0
    # Periodically sync the system time back to the hardware RTC
    # (every ~11 minutes)
    #
    rtcsync
    #——————————————————————————
    # Leap second handling
    #——————————————————————————
    # Obtain leap second and TAI-UTC offset information from the system
    # timezone database, operating in strict UTC mode.
    #
    leapsectz right/UTC
    view raw gistfile1.txt hosted with ❤ by GitHub

    Explanation of Chrony Config for GPSD

    OptionPurpose
    SOCK /var/run/gpsd.sockRead time from gpsd
    refid GPSLabel in chrony output
    poll 4Poll every 16 seconds
    precision 1e-1~100 ms accuracy (realistic for NMEA)
    delay 0.2USB + NMEA latency
    makestep 1.0 3Allow initial step corrections

    Start and Enable

    # systemctl enable chrony.service
    # systemctl start chrony.service

    After a few minutes, we should start to see pre-configured clients appear in the output of the command below

     # chronyc clients
    Hostname                      NTP   Drop Int IntL Last     Cmd   Drop Int  Last
    =============================================================================
    scar.lab                        5      0   6   -    30       0      0   -     -
    

    Chrony Client-side Setup

    Ubuntu Client

    $ sudo apt install chrony -y

    Configure the to listen to the chrony server address 10.1.10.10. Comment out any other server or pool directives in /etc/chrony/chrony.conf.

    server 10.1.10.11

    Start and enable the service.

    $ sudo systemctl enable chrony --now
    

    Check configured time source for chrony

    $ chronyc -n sources -v

    What the above output tells you

    • All NTP servers/pools configured for this client
    • Which source is currently selected
    • Reachability and time quality

    Key indicators

    SymbolMeaning
    ^*Current sync source
    ^+Candidate source
    ^-Reachable, not selected
    ^?Unusable / not trusted yet

    Cisco Catalyst Client Config

    Use the commands below to configure your Cisco switch to use the new timesource

    # Enter global configuration mode
    configure terminal
    
    # Define the NTP server
    ntp server 10.1.10.11
    
    # (Optional) Set the switch to use its own hardware clock if it loses sync
    ntp master 10
    
    # Exit and save
    end
    write memory
  • RHEL 10 – Install and Configure NUT UPS Tools and Monitor Via Zabbix.

    RHEL 10 – Install and Configure NUT UPS Tools and Monitor Via  Zabbix.

    In my personal lab I do not have a network managed UPS. My rack mount UPS can only be monitored via USB from a directly connected host.

    This guide details the installation and configuration of Network UPS Tools (NUT) to monitor a Tripp Lite USB PDU and prepare it for Zabbix integration.


    Prerequisites & Installation

    Install the necessary NUT packages. RHEL 10 uses the 2.8.x branch, which introduces an “instantiated” service model.

    sudo dnf install nut nut-client nut-server
    

    Directory Structure Setup

    RHEL 10 defaults to /etc/ups, we will use /etc/nut to ensure our configuration files are in the correct location and we will create a symbolic link for legacy compatibility.

    # Move config if it exists in the old /etc/ups location
    sudo mkdir -p /etc/nut
    sudo mv /etc/ups/* /etc/nut/ 2>/dev/null
    sudo ln -s /etc/nut /etc/ups
    

    Configuration Files

    The following files in /etc/nut/ must be configured:

    nut.conf

    Set the operation mode:

    MODE=netserver
    

    NUT (Network UPS Tools) Netserver Mode is a configuration where one machine (the server) connects to a UPS, monitors it, and then broadcasts the power status and alerts (like “on battery”) across the local network

    ups.conf

    Define the hardware driver. Note the exact spelling of the section name [tripplite].

    [tripplite]
        driver = usbhid-ups
        port = auto
        desc = "Tripp Lite USB PDU"
    

    upsd.conf

    Control network listening. To allow remote connections (like from a Zabbix server), you must listen on the host’s IP or all interfaces (0.0.0.0).

    LISTEN 127.0.0.1 3493
    LISTEN 10.1.10.21 3493
    

    upsd.users

    Define a user for Zabbix or remote monitoring:

    [zabbix]
        password = your_secure_password
        upsmon master
    

    USB Permissions (udev)

    Create a rule to allow the nut user to access the USB bus for Tripp Lite devices (Vendor ID 09ae).

    Create file: /etc/udev/rules.d/99-nut-ups.rules and add content shown below.

    ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="09ae", GROUP="nut", MODE="0660"

    Then apply

    sudo udevadm control --reload-rules && sudo udevadm trigger

    Firewall

    You need to allow inbound port 3493 since we want to be able to poll the ups remotely from a Zabbix host.

    # Open port 3493 permanently
    sudo firewall-cmd --permanent --add-port=3493/tcp
    sudo firewall-cmd --reload

    Service Management

    RHEL 10 uses a specific sequence. You must trigger the “enumerator” to generate the systemd units for your specific PDU name.

    # Force the system to recognize the [tripplite] section
    sudo /usr/libexec/nut-driver-enumerator.sh
    
    # Enable and start the driver instance
    sudo systemctl enable --now nut-driver@tripplite.service
    
    # Start the data server and monitoring daemon
    sudo systemctl enable --now nut-server.service
    sudo systemctl enable --now nut-monitor.service
    

    Manual Check Commands

    Use these commands to verify health:

    CommandPurpose
    upsc -lLists all configured UPS/PDU devices.
    upsc tripplite@localhostDumps all current PDU metrics (voltage, load, etc.).
    systemctl status nut-driver@trippliteChecks if the USB driver is active and running.
    journalctl -u nut-driver@tripplite -fFollow live logs if the USB connection drops.

    Test Remotely

    From another host, install the nut-client. If this step does not work, but the same commands worked locally, you should double check your Firewall settings.

    $ sudo apt install nut-client

    And test

    $ upsc tripplite@10.1.10.21

    Prepare the Zabbix Agent Permissions

    To allow Zabbix to collect this data automatically. Run the two commands below on the host connected to UPS via USB

    # sudo usermod -a -G nut zabbix
    # sudo systemctl restart zabbix-agent

    Create the Zabbix Agent UserParameters

    sudo vi /etc/zabbix/zabbix_agentd.d/nut_tripplite.conf

    Paste the following lines into the file above

    # Discovery rule to find the UPS name
    UserParameter=nut.ups.discovery,upsc -l | awk '{print "{\"{#UPSNAME}\":\"" $1 "\"}"}' | paste -sd "," | sed 's/^/{"data":[/' | sed 's/$/]}/'
    
    # Fetch specific values (e.g., ups.load, output.voltage)
    UserParameter=nut.ups.value[*],upsc $1@localhost $2 | grep -v "Value:"

    Now restart the zabbix agent

    # sudo systemctl restart zabbix-agent

    Now verify that the Zabbix agent returns UPS data

    # zabbix_agentd -t "nut.ups.value[tripplite,ups.load]"
    nut.ups.value[tripplite,ups.load]             [t|24]
    

    Setting up the Zabbix Web UI

    Lets create a simple template for zabbix. Follow the steps shown below.

    Manual Item Creation

    If you just want the most important metrics, go to your Host in Zabbix and create these Items:

    NameTypeKeyType of Information
    PDU LoadZabbix Agentnut.ups.value[tripplite,ups.load]Numeric (float)
    Input VoltageZabbix Agentnut.ups.value[tripplite,input.voltage]Numeric (float)
    Battery ChargeZabbix Agentnut.ups.value[tripplite,battery.charge]Numeric (float)
    PDU StatusZabbix Agentnut.ups.value[tripplite,ups.status]Character

    Configuring SELinux

    If you check the zabbix webui, you are going to see some failures, as we need to configure selinux.

    Note that we configured Zabbix “items” first so that we would be able to capture the failures in the audit log and generate a policy.

    So now that we have failures, we can tell RHEL to look at all recent security denials involving the zabbix_agent and write a “policy” that allows those specific actions.

    # Search the audit log for zabbix-related denials and create a policy module
    grep "zabbix" /var/log/audit/audit.log | audit2allow -M zabbix_nut_final

    Install the Policy

    The previous command created a file called zabbix_nut_final.pp. Now, load it into the kernel:

     semodule -i zabbix_nut_final.pp

    You should now see data returning in the Zabbix WebUI. You may need to wait a few second or re-run the check.

    Screenshot of a Zabbix web interface displaying the item 'Battery Charge' with details on the last check and last value.

  • Mastering Chrony: Essential Commands and Configurations

    Mastering Chrony: Essential Commands and Configurations

    Chrony is a flexible and modern implementation of the Network Time Protocol (NTP). It is designed to synchronize the system clock with NTP servers, reference clocks, or manual input with high accuracy. It excels in environments where the connection to the time source is intermittent or when the system clock is frequently interrupted (such as virtual machines)

    chrony officially replaced the traditional ntpd (NTP Daemon, provided by the legacy ntp package) as the default time synchronization service starting in RHEL 7.

    FeatureChrony (chronyd)ntpd (Legacy)
    Clock CorrectionSlewing Only (Default): Adjusts the clock gradually and precisely. Can handle frequent clock interruptions without losing accuracy.Slewing & Stepping: Slews for small adjustments but uses disruptive stepping (jumping the time) for large offsets, which can impact applications.
    Start-Up TimeFast: Uses makestep at startup to quickly correct large initial errors, then immediately begins slewing.Slow: Waits for the clock to slowly adjust, often taking longer to achieve synchronization.
    NetworkBetter for Intermittent Connections: Handles situations where the server connection is lost or the clock frequently changes (e.g., suspend/resume).Requires Constant Connectivity: Struggles with intermittent network loss and frequent system time changes.
    Resource UseLow: Very small memory footprint and fewer CPU cycles required.Moderate: Larger memory and CPU consumption.
    SecurityMore Secure: Designed with security in mind, often running with fewer privileges.Older Codebase: Has had more vulnerabilities over the years.

    Chrony Basic Commands

    CommandPurposeNotes
    chronyc sourcestats -vShows long-term source stability. Displays long-term statistics for each source, including clock drift and frequency estimation.Useful for spotting an unstable NTP server or bad hardware clock.
    chronyc clientsShows who is using your server. If you are configured as an NTP server, this command lists the hosts that are currently querying you for time (requires the ntpserver directive in your config).Useful for confirming if your NetApp LIF is actually reaching your RHEL box and making a request.
    chronyc makestepForces an immediate time correction. If your clock is severely off (more than a few minutes), this commands the daemon to immediately jump the clock to the correct time, instead of gradually slewing it.Use with Caution! Sudden time jumps can affect applications like databases.
    chronyc ntpdata $IPThis performs a one-time query to the specified server, simulating how the client would communicate with it.$IP seems to need to exist as source in chronyd.conf
    chronyc add server <IP>Adds a server dynamically. Adds a new NTP server to the running configuration without restarting the service.Changes made this way are not permanent and will be lost if chronyd restarts.

    Service Configuration File

    The main configuration file for chronyd is /etc/chrony.conf

    After any config file change, you need to restart the chronyd service

    # systemctl restart chrony

    Show Chrony Clients

    Running “chronyc -n clients -v” will show you the clients currently using a chrony server as a timesource

    ~# chronyc -n clients -v
    Hostname                      NTP   Drop Int IntL Last     Cmd   Drop Int  Last
    ===============================================================================
    10.1.10.10                     59      0   9   -   115       0      0   -     -
    10.1.10.21                     29      0   9   -    49       0      0   -     -
    10.1.10.49                     44      0   7   -   117       0      0   -     -
    10.1.10.45                     50      0   6   -    10       0      0   -     -
    10.1.10.13                     36      0   7   -    56       0      0   -     -
    10.1.10.18                     39      0   6   -    20       0      0   -     -
    10.1.10.20                     37      0   7   -    27       0      0   -     -
    10.1.10.15                     35      0   7   -    54       0      0   -     -
    10.1.10.50                     24      0   7   -   160       0      0   -     -
    

    Below is a breakdown of the command output

    Hostname

    • The IP address (or hostname) of each NTP client querying this Chrony server.
    • In this case: multiple clients in the 10.1.10.0/24 subnet.

    NTP

    • Total number of valid NTP packets received from that client.
    • This is cumulative since Chrony started.
    • Example: 10.1.10.10 → 59. Means this client has successfully sent 59 NTP requests.

    What to expect

    • Steadily increasing numbers = healthy client
    • Very low numbers = new client or infrequent polling

    Drop (NTP side)

    • Number of NTP packets dropped from this client.
    • Drops occur if packets are malformed, too frequent, or violate limits.

    Int

    • Current polling interval (log2 seconds).
    • Chrony uses exponential polling.
    IntActual Interval
    664 seconds
    7128 seconds
    8256 seconds
    9512 seconds

    IntL

    • Previous polling interval
    • - means no recent change

    Last (NTP side)

    • Seconds since the last NTP packet was received from that client.

    What to expect

    • Should generally be less than or near the polling interval
    • Larger numbers are fine if the client polls slowly

    Command (Cmd) columns

    These relate to Chrony command/control packets, not time sync traffic.

    Cmd

    • Number of chronyc command requests received from that client
    • 0 means the client is only syncing time, not issuing admin commands

    Drop (Cmd)

    • Dropped command packets
    • 0 is ideal

    Int (Cmd)

    • Poll interval for command packets
    • - means none used

    Last (Cmd)

    • Time since last command packet
    • - means no commands received

    Show Chrony Sources

    # chronyc sources -v
    
      .-- Source mode  '^' = server, '=' = peer, '#' = local clock.
     / .- Source state '*' = current best, '+' = combined, '-' = not combined,
    | /             'x' = may be in error, '~' = too variable, '?' = unusable.
    ||                                                 .- xxxx [ yyyy ] +/- zzzz
    ||      Reachability register (octal) -.           |  xxxx = adjusted offset,
    ||      Log2(Polling interval) --.      |          |  yyyy = measured offset,
    ||                                \     |          |  zzzz = estimated error.
    ||                                 |    |           \
    MS Name/IP address         Stratum Poll Reach LastRx Last sample               
    ===============================================================================
    ^- prod-ntp-3.ntp4.ps5.cano>     2  10   377   625  +1096us[+1096us] +/-   49ms
    ^- prod-ntp-4.ntp4.ps5.cano>     2  10   377   504   +144us[ +144us] +/-   51ms
    ^- alphyn.canonical.com          2  10   377   756   +619us[ +804us] +/-   40ms
    ^- prod-ntp-3.ntp1.ps5.cano>     2  10   377   759  +1352us[+1537us] +/-   51ms
    ^+ chi2.us.ntp.li                2  10   377   552  -1204us[-1204us] +/-   20ms
    ^- ovh.maxhost.io                2  10   377   628  -3688us[-3688us] +/-   58ms
    ^* atl-ntp2-0.mattnordhoffd>     2  10   377   741  +1002us[+1188us] +/- 7918us
    ^- 2a01:7e04::2000:5dff:fe1>     4  10   377   739  -1535us[-1535us] +/-   49ms
    
    

    MS (Mode / State)

    • ^ = NTP server
    • = = peer
    • # = local reference clock

    State indicator:

    • * = current best source (in use)
    • + = combined (used with others)
    • - = selectable but not used
    • x = faulty
    • ~ = too variable
    • ? = unreachable

    Stratum

    • Distance from a reference clock (lower is better)
    • GPS/PPS = stratum 0
    • Typical upstream servers = stratum 1–3

    Poll

    • Polling interval (log2 seconds)
    PollInterval
    664 seconds
    7128 seconds
    8256 seconds

    Reach

    • Octal reachability register (last 8 polls)
    • 377 (octal) = perfect reachability
    • Lower values = packet loss or intermittent connectivity

    LastRx

    • Seconds since last successful response
    • First value = adjusted offset
    • Bracketed value = raw measured offset
    • +/- = estimated error margin

    Units:

    • ns = nanoseconds
    • us = microseconds
    • ms = milliseconds

    Show Source Stats

    # chronyc sourcestats -v
                                 .- Number of sample points in measurement set.
                                /    .- Number of residual runs with same sign.
                               |    /    .- Length of measurement set (time).
                               |   |    /      .- Est. clock freq error (ppm).
                               |   |   |      /           .- Est. error in freq.
                               |   |   |     |           /         .- Est. offset.
                               |   |   |     |          |          |   On the -.
                               |   |   |     |          |          |   samples. \
                               |   |   |     |          |          |             |
    Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
    ==============================================================================
    prod-ntp-3.ntp4.ps5.cano>  31  14  106m     +0.120      0.212  +1317us   596us
    prod-ntp-4.ntp4.ps5.cano>  33  19  108m     -0.021      0.542   +316us  1235us
    alphyn.canonical.com       33  14  104m     -0.036      0.234   +594us   635us
    prod-ntp-3.ntp1.ps5.cano>  33  19  104m     +0.096      0.342  +1156us   761us
    chi2.us.ntp.li             33  18  107m     -0.087      0.341  -1596us   873us
    ovh.maxhost.io             31  14   96m     +0.147      0.382  -2735us   765us
    atl-ntp2-0.mattnordhoffd>  33  16  104m     +0.083      0.331   +762us   889us
    2a01:7e04::2000:5dff:fe1>  33  19  104m     -0.284      0.513  -1432us  1236us
    

    This shows:

    • Average offset
    • Standard deviation (jitter)
    • Frequency correction
    • Stability over time

    Show Selected Source

    chronyc tracking
    Reference ID    : EE1C3393 (atl-ntp2-0.mattnordhoffdns.net)
    Stratum         : 3
    Ref time (UTC)  : Fri Dec 26 20:54:37 2025
    System time     : 0.000375564 seconds fast of NTP time
    Last offset     : +0.000185856 seconds
    RMS offset      : 0.000497939 seconds
    Frequency       : 33.487 ppm slow
    Residual freq   : +0.008 ppm
    Skew            : 0.299 ppm
    Root delay      : 0.014126181 seconds
    Root dispersion : 0.002563612 seconds
    Update interval : 1033.8 seconds
    Leap status     : Normal
    

    Reference ID

    • The active NTP source currently disciplining your clock.
    • EE1C3393 is the hexadecimal reference identifier.
    • The hostname confirms DNS resolution of the upstream server.

    ✔ This tells you exactly which server is in use.


    Stratum

    • Indicates the distance from a reference clock.
    • Stratum hierarchy:
      • 0 → GPS / atomic clock (not directly used)
      • 1 → Directly connected to stratum 0
      • 2 → Syncing from stratum 1
      • 3 → Syncing from stratum 2

    ✔ Stratum 3 is normal and acceptable for internet-sourced NTP.


    Ref time (UTC)

    • Timestamp of the last successful synchronization sample.
    • Expressed in UTC.

    ✔ Confirms recent and valid sync.


    System time

    • Your local clock is ahead of true NTP time by ~0.38 ms.
    • Chrony is actively correcting this.

    ✔ Sub-millisecond offset is excellent.


    Last offset

    • Offset measured during the most recent update.
    • Positive = system clock was fast.

    ✔ Very small deviation (~0.19 ms).


    RMS offset

    • Root Mean Square of offsets over recent samples.
    • Represents overall synchronization quality.

    ✔ <1 ms RMS is very good for non-GPS NTP.


    Frequency

    • How far your system clock naturally drifts without correction.
    • ppm = parts per million.
    • “Slow” means your hardware clock loses ~33 µs per second.

    ✔ Completely normal for commodity hardware.


    Residual freq

    • Remaining frequency error after corrections.
    • Shows how well Chrony has tuned the clock.

    ✔ Near-zero = excellent convergence.


    Skew

    0.299 ppm
    
    • Estimated uncertainty in frequency measurement.
    • Lower = higher confidence.

    ✔ <1 ppm is strong stability.


    Root delay

    0.014126181 seconds
    
    • Total round-trip delay to the reference clock.
    • Includes network latency through the NTP chain.

    ✔ ~14 ms is expected for internet NTP.


    Root dispersion

    • Estimated maximum error relative to true time.
    • Accumulates over time since last sync.

    ✔ ~2.5 ms is very good.


    Update interval

    • Time between Chrony updates (~17 minutes).
    • Increases as clock stability improves.

    ✔ Indicates a stable and trusted source.


    Leap status

    • No leap second pending or in progress.

    ✔ Required for accurate timekeeping.

  • How to Install and Configure Dnsmasq with Web Frontend on RHEL 9

    How to Install and Configure Dnsmasq with Web Frontend on RHEL 9

    In this post we are going to install and configure dnsmasq with a simple webUI acting as a front end for our less technical users. Our goal is to simplify dns in our lab sandboxes, and keep users from directly modifying our dnsmasq config files.

    Installation

    First we need to install dnsmasq.

    # dnf -y install dnsmasq

    Now lets enable and start the service. We will also check the status of the service to ensure that we do not have any issues with the default config.

    # systemctl start dnsmasq
    # systemctl enable dnsmasq
    # systemctl status dnsmasq

    Configuration

    Next let’s make a backup of the default configuration file before we start making modification.

    cp /etc/dnsmasq.conf /etc/dnsmasq.conf.orig

    I made the following modifications.

    1. listen-address is the loopback and our routable ip address
    2. expand-hosts, we uncomment this in order to allow dnsmasq to automatically expand the hostnames to fully qualified domain names
    3. domain – this is the local domain that we will serve via dnsmasq
    4. dhcp-range – this is the range of IP addresses that dnsmasq is allowed to hand out
    interface=enp1s0
    listen-address=127.0.0.1,192.168.65.7
    expand-hosts
    domain=sandbox3.localdomain
    dhcp-range=192.168.65.20,192.168.65.40,255.255.255.128,12h
    

    Next we check our config file for any errors

    # dnsmasq --test
    dnsmasq: syntax check OK.

    Now lets restart dnsmasq

    # systemctl restart dnsmasq

    Firewall Config

    Now we need to modify firewalld

    [root@dns ~]#  firewall-cmd --add-service=dns --permanent
    success
    [root@dns ~]# firewall-cmd --add-service=dhcp --permanent
    success
    [root@dns ~]# firewall-cmd --reload
    success

    Testing

    I prefer to use nslookup for testing, so lets install it

    # dnf -y install bind-utils

    Now let’s make sure we are able to resolve addresses, using our local instance of dnsmasq.

    # nslookup
    > server localhost
    Default server: localhost
    Address: ::1#53
    Default server: localhost
    Address: 127.0.0.1#53
    > google.com
    Server:		localhost
    Address:	::1#53
    
    Non-authoritative answer:
    Name:	google.com
    Address: 142.251.40.174
    Name:	google.com
    Address: 2607:f8b0:4006:821::200e
    

    Install and Configure the Webui

    For the webui – we are going to use a simple one that I found via the link below. https://github.com/akivajp/dnsmasq-webconf

    First, we need to install git and pip

    # dnf -y install git
    # dnf -y install pip

    Then we follow the directions which I will repeat here.

    # mkdir -p ~/git && cd ~/git
    # git clone https://github.com/akivajp/dnsmasq-webconf.git

    Then we use pip to install jinja2

    # pip install --user bottle jinja2

    Now change directory

    # cd dnsmasq-webconf/

    We now need to poke a hole for http traffic in our local firewall

    # firewall-cmd --add-service=http --permanent
    # firewall-cmd --reload

    Now start the front end

    #  python ~/git/dnsmasq-webconf/app/index.py 80 --leases /var/lib/dnsmasq/dnsmasq.leases --hosts /etc/hosts --config /etc/dnsmasq.conf

    Creating a Service

    So far we have dnsmasq configured and running, and we have installed a web front end and have been able to start it on the command line. Now we need to configure the front end to start as a service when the OS boots. So we now need to turn the webUI into a systemd service.

    First we create the following service file

    # vi /etc/systemd/system/dnsmasq-webconf.service

    The contents of which are below. Note that we have modified relative paths to be absolute paths.

    [Unit]
    Description=DNSMasq WebConf
    After=network.target
    
    [Service]
    ExecStart=/usr/bin/python3 /root/git/dnsmasq-webconf/app/index.py 80 --leases /var/lib/dnsmasq/dnsmasq.leases --hosts /etc/hosts --config /etc/dnsmasq.conf
    Restart=always
    User=root
    WorkingDirectory=/root/git/dnsmasq-webconf/app
    StandardOutput=journal
    StandardError=journal
    
    [Install]
    WantedBy=multi-user.target

    Now we need to reload systemd

    # systemctl daemon-reload

    Now we can start the service

    # systemctl start dnsmasq-webconf.service