Latest Website Creation

Here is my latest website creation. Interestingly, this one is hosted on CloudFlare.



 

 

2026 Corn Festival comming up!

The event is over, and it went well. Photos of the event are available at https://www.centennial326.org 

  

DUM-E: The Saddest Employee in Tony Stark’s Lab

Every great genius needs an assistant. Batman has Alfred. Sherlock Holmes has Watson. Doc Brown had Marty, whether Marty wanted the job or not.

Tony Stark had DUM-E.

And honestly, poor DUM-E deserved better.

DUM-E, pronounced “dummy,” is the robotic arm in Tony Stark’s lab who seems to exist mainly to be yelled at, threatened, mocked, and occasionally blamed for doing exactly what he was programmed to do. His most memorable job is standing by with a fire extinguisher while Tony tests incredibly dangerous experimental technology in a private garage like OSHA is just a rumor.

And when Tony catches on fire, crashes into walls, or nearly vaporizes himself?

DUM-E acts.

He blasts Tony with the fire extinguisher.

This is not incompetence. This is commitment.

The Most Underappreciated Member of Stark Industries

Let’s be fair to DUM-E. Tony Stark’s lab is not a normal workplace.

Most assistants are asked to schedule meetings, order lunch, or prepare reports. DUM-E’s job description appears to include:

  • Watching Tony build weapons-grade technology in his basement

  • Remaining calm during explosions

  • Handling emergency fire suppression

  • Assisting with impossible engineering projects

  • Enduring constant verbal abuse

  • Not developing a robot union

And despite all of that, DUM-E shows up.

Every time Tony is about to do something reckless, DUM-E is there. Quietly. Faithfully. Fire extinguisher ready.

Tony, of course, does not appreciate this. Instead, he treats DUM-E like the world’s worst intern. He threatens to donate him to a community college. He calls him useless. He acts annoyed when DUM-E tries to save his life.

This is classic Tony Stark behavior. He builds a loyal robot assistant, gives it just enough personality to be endearing, then spends years emotionally bullying it for not being Jarvis.

DUM-E Is Not Dumb

The joke is that DUM-E is clumsy. He is not smooth like Jarvis. He is not sleek like Friday. He does not speak in a calm British voice or run complex battlefield simulations.

But DUM-E is not dumb.

DUM-E understands the assignment. Tony catches on fire, DUM-E extinguishes the fire. Tony flies into a wall, DUM-E responds. Tony behaves like a man who has never heard the phrase “controlled test environment,” DUM-E prepares for disaster.

In any other workplace, DUM-E would be Employee of the Month.

At Stark Industries, he gets insulted by a billionaire in a tank top.

The Tragedy of Trying Your Best

What makes DUM-E funny is also what makes him strangely sad. He is always trying to help. He is never malicious. He is not rebelling, scheming, or malfunctioning in some dramatic way. He is simply over-eager, awkward, and loyal.

That is why audiences love him.

DUM-E is the robot version of the person at work who means well, makes things worse by accident, then gets blamed by the boss who created the problem in the first place.

Tony is the guy testing rocket boots indoors.

DUM-E is the guy holding the fire extinguisher.

Somehow, Tony thinks DUM-E is the problem.

Tony’s Lab Has a Heart

For all the sarcasm, Tony does seem to care about DUM-E. That is part of the charm. Tony may threaten him, scold him, and act like he is one bad move away from being recycled, but DUM-E remains part of the lab.

That matters.

Tony Stark surrounds himself with machines, but he does not build lifeless tools. His creations have quirks. Jarvis has wit. The suits have style. DUM-E has anxious golden retriever energy and a fire extinguisher.

DUM-E helps make Tony’s lab feel less like a sterile high-tech facility and more like a messy, brilliant, dangerous home workshop. He is part assistant, part pet, part safety system, and part emotional support machinery.

He is family, even if Tony would never admit it without making a joke.

Justice for DUM-E

DUM-E may not be the smartest machine Tony Stark ever built, but he might be one of the most loyal. He stood beside Tony before the Avengers, before the world-saving, before the clean corporate labs and the polished superhero image.

He was there in the garage.

He was there with the extinguisher.

He was there when Tony was still figuring out how to become Iron Man.

So maybe DUM-E is not tragic because Tony insults him. Maybe DUM-E is tragic because he represents every loyal helper who never gets enough credit. He is the overlooked assistant, the unpaid intern, the nervous coworker trying to prevent disaster while the genius in charge creates more of it.

DUM-E is not just comic relief.

DUM-E is a hero.

A clumsy hero, yes. A hero who may fire-extinguish first and ask questions never. But a hero all the same.

And the next time Tony Stark calls him useless, someone should remind him that the richest genius on Earth still needed a robot arm standing nearby, ready to put him out when his own brilliance caught fire.

The Difference Between the Caduceus and the Rod of Asclepius

The caduceus and the Rod of Asclepius are often confused, especially in modern medical logos. At a glance, both symbols include snakes wrapped around a staff, but they come from different mythological traditions and originally meant very different things.

The Rod of Asclepius is the older and more accurate symbol of medicine. It shows one snake wrapped around a plain staff, with no wings. Asclepius was the Greek god associated with healing, medicine, and physicians. Because of that connection, his serpent-entwined staff became a lasting symbol of medical care and the healing arts.

The caduceus, by contrast, shows two snakes wrapped around a winged staff. This was the staff of Hermes, known to the Romans as Mercury. Hermes was the messenger of the gods, but he was also associated with travelers, merchants, trade, language, diplomacy, thievery, and cunning. In other words, the caduceus originally had more to do with communication, commerce, negotiation, and trickery than with healing.

The confusion became especially common in the United States. In 1902, the U.S. Army Medical Corps adopted the caduceus as an insignia, even though the Rod of Asclepius was the more traditional medical symbol. Over time, the caduceus became widely recognized in America as a medical emblem, despite its earlier association with Hermes rather than Asclepius.

The easiest way to remember the difference is simple: one snake means medicine; two snakes and wings mean Hermes. The Rod of Asclepius symbolizes healing and physicians. The caduceus points to messengers, merchants, travel, negotiation, and clever speech.

So the next time you see a medical logo with two snakes and wings, you are not looking at the ancient symbol of medicine. You are looking at a symbol that history borrowed, confused, and never quite gave back.


 

The Drive, No More (Parody)

Once within a server dreary, while I pondered, weak and weary,
Over backups, logs, and folders I had trusted long before,
Came a clicking, faintly tapping, like some tiny demon rapping,
Rapping from the drive bay’s darkness, whispering of things in store.
“’Tis a cable,” then I muttered, “loose behind the chassis door.”
Only this, and nothing more.

Yet the volume mounted never, though I begged with grim endeavor,
Though I ran the sacred commands I had often run before.
fsck cried out in broken meter, SMART grew colder, death grew sweeter,
Every sector turned a traitor, every block a bolted door.
Then the kernel, pale and mocking, carved my doom into its lore:
“Unknown error. Read no more.”

Deep into that disk I glowered, as the midnight slowly soured,
Dreaming dreams of lost directories vanished from the spinning core.
Photos, scripts, and ancient writing, tax returns and memes delighting,
All entombed in silent platters I may nevermore restore.
Then my soul cried, “Can I save them?”
Quoth the syslog: “Nevermore.”

 

With Apologies to the ghost of Edgar Allan Poe. 

 


Adding UPS Monitoring to a Linux Home Lab Server with NUT

I recently added a managed UPS to a Linux server in my lab and wanted the server to do more than just sit on battery backup. I wanted the server to detect the UPS, monitor the battery status, send email alerts, provide a web status page, and shut down cleanly if power was out for too long.

The UPS I used was a CyberPower CP1500PFCLCD PFC Sinewave UPS Battery Backup and Surge Protector, 1500VA/1000W, 12 Outlets, AVR, Mini Tower, UL Certified

Amazon product page:

https://www.amazon.com/CyberPower-CP1500PFCLCD-Sinewave-Outlets-Mini-Tower/dp/B00429N19W


This post walks through the setup in a lab environment using Linux, Network UPS Tools, systemd, Nginx, and a simple notification script.

Lab Environment


The lab server used for this setup was running:

Linux distribution: LMDE 7 “Gigi”
Base: Debian 13 “Trixie”
UPS: CyberPower CP1500PFCLCD
UPS connection: USB cable
UPS software: Network UPS Tools, also known as NUT
Web server: Nginx
Mail relay: Local sendmail-compatible relay


The examples below use sanitized names and addresses:

UPS name: lab-ups
Server IP: 192.168.1.5
Alert email: admin@example.com
Status page: http://192.168.1.5/status/ups/


Substitute your own values where needed.

What I Wanted the UPS Setup to Do


The goal was not just battery backup. I wanted useful management:

  • Detect the UPS over USB
  • Monitor line power, battery charge, runtime, and load
  • Send an email when power events happen
  • Wait before shutting down, in case power comes back quickly
  • Shut down cleanly if power stays out too long
  • Provide a web-based UPS status page
  • Start automatically after reboot


The final behavior looked like this:

  • Power goes out:
    • Start a 5-minute warning timer.
    • Start a 30-minute shutdown timer.
  • After 5 minutes on battery:
    • Send an email warning.
  • After 30 minutes on battery:
    • Send a shutdown warning.
    • Start clean shutdown.
  • If power comes back:
    • Cancel the timers.
    • Send a recovery email.
  • If the UPS reaches low battery:
    • Shut down immediately.


Step 1: Plug in the UPS USB Cable


First, I connected the UPS to the Linux server using the USB cable that came with the UPS.

Then I checked whether Linux could see it:

lsusb

The UPS appeared as a CyberPower USB device. Example:

Cyber Power System, Inc. CP1500PFCLCD UPS

I also checked recent kernel messages:

dmesg | tail -n 80

This confirmed that the server saw the USB device.

Step 2: Install Network UPS Tools


Network UPS Tools, or NUT, is the standard Linux toolset for monitoring UPS units.

Install it:

apt update
apt install -y nut nut-client nut-server

Then scan for USB UPS devices:

nut-scanner -U

The scan should return something similar to this:

[nutdev1]
    driver = "usbhid-ups"
    port = "auto"
    vendorid = "0764"
    productid = "0601"
    product = "CP1500PFCLCDa"
    vendor = "CPS"

The important line is:

driver = "usbhid-ups"

That is the driver used for many USB HID-compatible UPS units.

Step 3: Configure the UPS

Edit `/etc/nut/ups.conf`:

cp /etc/nut/ups.conf /etc/nut/ups.conf.bak.$(date +%Y%m%d-%H%M%S)

cat > /etc/nut/ups.conf <<'EOF'
[lab-ups]
    driver = usbhid-ups
    port = auto
    vendorid = 0764
    productid = 0601
    desc = "CyberPower CP1500PFCLCD UPS"
EOF

This defines the UPS as `lab-ups`.

Step 4: Set NUT to Standalone Mode

For a single server connected directly to one UPS, standalone mode is appropriate.

Configure `/etc/nut/nut.conf`:

cp /etc/nut/nut.conf /etc/nut/nut.conf.bak.$(date +%Y%m%d-%H%M%S)

cat > /etc/nut/nut.conf <<'EOF'
MODE=standalone
EOF

Step 5: Create the NUT Monitor User

NUT uses a local user account so `upsmon` can monitor the UPS through `upsd`.

Configure `/etc/nut/upsd.users`:

cp /etc/nut/upsd.users /etc/nut/upsd.users.bak.$(date +%Y%m%d-%H%M%S) 2>/dev/null || true

cat > /etc/nut/upsd.users <<'EOF'
[monuser]
    password = replace-this-with-a-strong-local-password
    upsmon master
EOF

chmod 640 /etc/nut/upsd.users
chown root:nut /etc/nut/upsd.users

Use a real password in your own environment.

Step 6: Configure UPS Monitoring

Configure `/etc/nut/upsmon.conf`:

cp /etc/nut/upsmon.conf /etc/nut/upsmon.conf.bak.$(date +%Y%m%d-%H%M%S)

cat > /etc/nut/upsmon.conf <<'EOF'
MONITOR lab-ups@localhost 1 monuser replace-this-with-a-strong-local-password master

MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 15
DEADTIME 15
POWERDOWNFLAG /etc/killpower

NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT SYSLOG+WALL+EXEC
NOTIFYFLAG FSD SYSLOG+WALL+EXEC
NOTIFYFLAG COMMOK SYSLOG+WALL+EXEC
NOTIFYFLAG COMMBAD SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT SYSLOG+WALL+EXEC
NOTIFYFLAG NOCOMM SYSLOG+WALL+EXEC

NOTIFYCMD /usr/sbin/upssched
EOF

chmod 640 /etc/nut/upsmon.conf
chown root:nut /etc/nut/upsmon.conf

This tells `upsmon` to call `upssched`, which handles timed actions.

Step 7: Fix USB Permissions If Needed

On my setup, the UPS was detected but the driver initially could not open the USB device because of permissions.

The error looked like this:

libusb1: Could not open any HID devices: insufficient permissions on everything
No matching HID UPS found

The fix was to create a udev rule for the CyberPower UPS:

cat > /etc/udev/rules.d/62-cyberpower-ups.rules <<'EOF'
 CyberPower CP1500PFCLCD UPS for NUT
SUBSYSTEM=="usb", ATTR{idVendor}=="0764", ATTR{idProduct}=="0601", MODE="0660", GROUP="nut"
SUBSYSTEM=="usb_device", ATTR{idVendor}=="0764", ATTR{idProduct}=="0601", MODE="0660", GROUP="nut"
EOF

udevadm control --reload-rules
udevadm trigger

Then unplug the UPS USB cable, wait a few seconds, and plug it back in.

Check the permissions:

lsusb | grep -i -E 'cyber|power|ups|0764'

for dev in /dev/bus/usb/*/*; do
    if udevadm info -q property -n "$dev" 2>/dev/null | grep -q 'ID_VENDOR_ID=0764'; then
        echo "===== $dev ====="
        ls -l "$dev"
    fi
done


The device should be owned by root with group `nut`.

Step 8: Start the NUT Services

On Debian 13, the driver runs as a systemd instance, such as:

nut-driver@lab-ups.service

Start and enable the NUT services:

systemctl daemon-reload

systemctl enable --now nut-driver-enumerator.path
systemctl enable --now nut-driver-enumerator.service
systemctl enable --now nut-server
systemctl enable --now nut-monitor

Check the driver instance:

systemctl list-units 'nut-driver*' --all --no-pager

You should see something like:

nut-driver@lab-ups.service loaded active running

Then check all three main pieces:

systemctl is-active nut-driver@lab-ups.service nut-server nut-monitor

Expected:

active
active
active

Step 9: Query the UPS

Now query the UPS:

upsc lab-ups@localhost

Useful values include:

text
battery.charge
battery.runtime
input.voltage
output.voltage
ups.load
ups.status


Example:

text
battery.charge: 100
battery.runtime: 5525
input.voltage: 120.0
output.voltage: 120.0
ups.load: 7
ups.status: OL



`OL` means the UPS is on utility power.

Common status values:

text
OL        On line power
OB        On battery
LB        Low battery
OL CHRG   On line and charging


Step 10: Create an Email Notification Script

I wanted the server to send an email when UPS events happened.

Create `/usr/local/sbin/lab-ups-notify.sh`:

cat > /usr/local/sbin/lab-ups-notify.sh <<'EOF'
!/usr/bin/env bash

TO="admin@example.com"
FROM="Lab Server <server@example.com>"
LOG="/var/log/lab-ups.log"

EVENT="${NOTIFYTYPE:-UNKNOWN}"
MESSAGE="${*:-No message supplied}"
NOW="$(date '+%Y-%m-%d %H:%M:%S %Z')"
HOST="$(hostname -f 2>/dev/null || hostname)"

UPS_STATUS="$(upsc lab-ups@localhost 2>/dev/null || true)"

{
    echo "[$NOW] UPS event: $EVENT - $MESSAGE"
} >> "$LOG"

timeout 30 /usr/sbin/sendmail -t <<MAIL
From: ${FROM}
To: ${TO}
Subject: [LAB SERVER] UPS event: ${EVENT}

The lab server received a UPS event.

Time:
  ${NOW}

Host:
  ${HOST}

Event:
  ${EVENT}

Message:
  ${MESSAGE}

UPS Status:
${UPS_STATUS}
MAIL

exit 0
EOF

chmod 0755 /usr/local/sbin/lab-ups-notify.sh


Test it:

NOTIFYTYPE=TEST /usr/local/sbin/lab-ups-notify.sh "Manual UPS notification test"

If the email arrives, the notification script is working.

Step 11: Configure Timed Shutdown Behavior

I did not want the server to shut down immediately for a short power blink. I wanted it to wait.

The plan was:

  • After 5 minutes on battery:
    • Send warning email.
  • After 30 minutes on battery:
    • Start clean shutdown.
  • If power comes back:
    • Cancel shutdown timers and send recovery email.
  • If low battery happens:
    • Shut down immediately.

Create the `upssched` command script:

cat > /usr/local/sbin/lab-upssched-cmd.sh <<'EOF'
!/usr/bin/env bash

LOG="/var/log/lab-ups.log"
NOW="$(date '+%Y-%m-%d %H:%M:%S %Z')"

case "$1" in
    onbatt-warning)
        NOTIFYTYPE=ONBATT-WARNING /usr/local/sbin/lab-ups-notify.sh \
            "The lab server has been on UPS battery power for 5 minutes."
        echo "[$NOW] upssched: 5-minute on-battery warning sent" >> "$LOG"
        ;;

    onbatt-shutdown)
        NOTIFYTYPE=ONBATT-SHUTDOWN /usr/local/sbin/lab-ups-notify.sh \
            "The lab server has been on UPS battery power for 30 minutes. Starting clean shutdown."
        echo "[$NOW] upssched: 30-minute on-battery shutdown triggered" >> "$LOG"
        /sbin/upsmon -c fsd
        ;;

    online-recovery)
        NOTIFYTYPE=ONLINE-RECOVERY /usr/local/sbin/lab-ups-notify.sh \
            "Power has been restored. The lab server is back on utility power. UPS shutdown timers have been cancelled."
        echo "[$NOW] upssched: online recovery email sent; shutdown timers cancelled" >> "$LOG"
        ;;

    *)
        echo "[$NOW] upssched: unknown command: $1" >> "$LOG"
        ;;
esac
EOF

chmod 0755 /usr/local/sbin/lab-upssched-cmd.sh


Then configure `/etc/nut/upssched.conf`:

cp /etc/nut/upssched.conf /etc/nut/upssched.conf.bak.$(date +%Y%m%d-%H%M%S) 2>/dev/null || true

cat > /etc/nut/upssched.conf <<'EOF'
CMDSCRIPT /usr/local/sbin/lab-upssched-cmd.sh
PIPEFN /run/nut/upssched.pipe
LOCKFN /run/nut/upssched.lock

AT ONBATT * START-TIMER onbatt-warning 300
AT ONBATT * START-TIMER onbatt-shutdown 1800

AT ONLINE * CANCEL-TIMER onbatt-warning
AT ONLINE * CANCEL-TIMER onbatt-shutdown
AT ONLINE * EXECUTE online-recovery

AT LOWBATT * EXECUTE onbatt-shutdown
EOF

chmod 640 /etc/nut/upssched.conf
chown root:nut /etc/nut/upssched.conf

Restart the monitor:

systemctl restart nut-monitor

Verify:

systemctl status nut-monitor --no-pager

Step 12: Install the NUT CGI Web Status Page

I also wanted a simple web page to show UPS status.

Install the packages:

apt update
apt install -y nut-cgi fcgiwrap

Find the CGI files:

dpkg -L nut-cgi | grep -E 'cgi|upsstats|upsset|hosts'

On Debian, the CGI files are usually here:

/usr/lib/cgi-bin/nut/upsstats.cgi
/usr/lib/cgi-bin/nut/upsimage.cgi
/usr/lib/cgi-bin/nut/upsset.cgi

Configure `/etc/nut/hosts.conf`:

cp /etc/nut/hosts.conf /etc/nut/hosts.conf.bak.$(date +%Y%m%d-%H%M%S)

cat > /etc/nut/hosts.conf <<'EOF'
MONITOR lab-ups@localhost "Lab UPS"
EOF

Start `fcgiwrap`:

systemctl enable --now fcgiwrap.socket
systemctl status fcgiwrap.socket --no-pager

Step 13: Add an Nginx Location for the UPS Page

In my lab, I exposed the UPS page as a subpage of the server’s local status site:

http://192.168.1.5/status/ups/

The Nginx block looked like this:

location = /status/ups {
    return 301 /status/ups/;
}

location /status/ups/ {
    include fastcgi_params;
    fastcgi_pass unix:/run/fcgiwrap.socket;
    fastcgi_param SCRIPT_FILENAME /usr/lib/cgi-bin/nut/upsstats.cgi;
    fastcgi_param SCRIPT_NAME /status/ups/;
    fastcgi_param PATH_INFO "";
    fastcgi_param QUERY_STRING $query_string;
    add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";
}

location = /status/ups/upsimage.cgi {
    include fastcgi_params;
    fastcgi_pass unix:/run/fcgiwrap.socket;
    fastcgi_param SCRIPT_FILENAME /usr/lib/cgi-bin/nut/upsimage.cgi;
    fastcgi_param SCRIPT_NAME /status/ups/upsimage.cgi;
    fastcgi_param QUERY_STRING $query_string;
    add_header Cache-Control "no-store, no-cache, must-revalidate, max-age=0";
}


Test Nginx:

nginx -t
systemctl reload nginx


Then test the page:

curl -I http://192.168.1.5/status/ups/

The detailed UPS page was available at:

http://192.168.1.5/status/ups/?host=lab-ups@localhost

Step 14: Final Verification Commands

Here are the main commands I use to check the UPS setup:

systemctl is-active nut-driver@lab-ups.service nut-server nut-monitor

upsc lab-ups@localhost | grep -E 'ups.status|battery.charge|battery.runtime|ups.load|input.voltage|output.voltage'

systemctl list-units 'nut-driver*' --all --no-pager

tail -n 50 /var/log/lab-ups.log

Expected UPS status on normal wall power:

ups.status: OL

Final Result

After setup, the server had:

  • UPS detected over USB
  • NUT driver running
  • NUT server running
  • NUT monitor running
  • Email alerts working
  • Timed shutdown behavior configured
  • Recovery email when power returns
  • Web status page available on the LAN
  • Automatic startup after reboot


At the current low load in my lab, the UPS reported roughly 90 minutes of runtime. I chose not to run the server all the way down. Instead, the system waits 30 minutes on battery, then shuts down cleanly unless power returns first.

That gives short outages a chance to clear while still protecting the server, filesystems, and running services from an uncontrolled power loss.

Closing Thoughts

A UPS is useful by itself, but it becomes much more useful when the server can talk to it. With a USB cable and Network UPS Tools, a Linux server can monitor power status, send alerts, display a web status page, and shut itself down cleanly.

For a home lab or small server rack, this is one of those upgrades that is worth doing before the next power outage.

Managing a Cisco Catalyst Switch from a Linux Server Using a USB-to-RJ45 Console Cable

I recently connected a Linux server in my lab directly to a Cisco Catalyst switch using a USB-to-RJ45 Cisco console cable. The goal was simple: manage the switch from the Linux command line without needing a separate laptop, USB serial adapter, or Windows terminal program.

This is a practical lab setup for anyone who works with older Cisco switches, home lab racks, or small network environments. Once the cable is connected, the Linux server can act as a permanent console workstation for the switch.


 

 

 

 

 

 

 

 

Lab Hardware and Software Used

For this lab, I used the following equipment:

Linux server
Linux distribution: LMDE 7 “Gigi”
Base: Debian 13 “Trixie”

Cisco switch
Model: Cisco Catalyst WS-C2960G-8TC-L

Console cable
Cable Matters USB-to-RJ45 Cisco console cable
FTDI-based USB serial chipset
Length: 6 feet

The specific cable used was sold as a Cable Matters USB-to-RJ45 Console Cable compatible with Cisco console cables / rollover cords, and purchased from Amazon: https://www.amazon.com/dp/B078PVJ5ZQ 

This kind of cable is not an Ethernet cable. The RJ45 end plugs into the console port on the Cisco switch, not into a regular Ethernet switch port.

What the Cable Does

A Cisco console connection is a serial connection. Many Cisco switches use an RJ45-style console port, but electrically it is not Ethernet.

The USB-to-RJ45 console cable includes a USB-to-serial adapter in the cable assembly. In this lab, Linux detected the USB-to-serial chipset as an FTDI device. Once detected, the system created a serial console device that could be used to connect to the Cisco switch. 

Physical Connection

The connection is straightforward:

Linux server USB port
        |
        | USB-to-RJ45 Cisco console cable
        |
Cisco Catalyst console port

The RJ45 end must go into the console port on the Cisco switch. Do not plug it into a normal Ethernet data port.

Step 1: Confirm Linux Sees the USB Serial Adapter

After plugging in the USB side of the console cable, I checked whether Linux detected the USB serial chipset:

lsusb | grep -i -E 'ftdi|serial|cable|0403'

Example output:

Bus 005 Device 002: ID 0403:6001 Future Technology Devices International, 
Ltd FT232 Serial (UART) IC

Then I checked the kernel log:

dmesg | grep -i -E 'ttyUSB|ftdi|usb serial' | tail -n 30

The important line was:

FTDI USB Serial Device converter now attached to ttyUSB0

That means Linux created a serial device at:

/dev/ttyUSB0

Linux also created a stable device path:

ls -l /dev/ttyUSB* /dev/serial/by-id/* 2>/dev/null

Example output:

/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AH6SK75M-if00-port0 -> ../../ttyUSB0
/dev/ttyUSB0

I prefer using the /dev/serial/by-id/ path because /dev/ttyUSB0 can change if additional USB serial devices are connected later.

Step 2: Install Serial Console Tools

On the Linux server, I installed screen and minicom:

sudo apt update
sudo apt install -y screen minicom

Either tool can be used. screen is quick and simple. minicom is more purpose-built for serial console work.

Step 3: Connect with screen

Most Cisco Catalyst console ports use 9600 baud.

To connect using screen:

screen /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AH6SK75M-if00-port0 9600

After the session opens, press Enter once or twice. The Cisco prompt should appear:

Switch>

To enter privileged EXEC mode:

enable

The prompt should change to:

Switch#

At that point, the Linux server is connected to the Cisco switch console.

Step 4: Disable Output Paging

Cisco IOS often pauses long output with --More--. For lab documentation and troubleshooting, I usually disable paging for the current session:

terminal length 0

This does not permanently change the switch. It only affects the current console session.

Step 5: Run Basic Discovery Commands

Useful commands for identifying and documenting the switch include:

show version
show inventory
show running-config
show startup-config
show ip interface brief
show interfaces status
show vlan brief
show logging

In this lab, the switch was identified as:

Model: Cisco Catalyst WS-C2960G-8TC-L
IOS image: c2960-lanbasek9-mz.122-55.SE5.bin
Processor: PowerPC405
Memory: 65536K bytes
Management interface: Vlan1
Management IP method: DHCP

The switch had a DHCP-assigned management IP address on VLAN 1.

Step 6: Save Configuration Changes

After changing Cisco IOS configuration, save the running configuration to startup configuration:

write memory

or:

copy running-config startup-config

If prompted for the destination filename, press Enter to accept the default.

Step 7: Disconnect Properly from screen

Do not just close the terminal window. To cleanly disconnect from screen:

Ctrl-A
K
y

That means:

  1. Press Ctrl-A.

  2. Press K.

  3. Press y to confirm.

This exits the screen session and releases the serial device.

Step 8: Connect with Minicom

Minicom is another good option for Cisco console access.

To connect:

minicom -D /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AH6SK75M-if00-port0 -b 9600

If the screen appears blank, press Enter once or twice.

To exit Minicom:

Ctrl-A
X

Then confirm that you want to leave Minicom.

Step 9: Log the Entire Cisco Console Session to a File

For documentation, I like logging the whole Cisco console session to a file. This creates a record of the commands run and the output returned by the switch.

Create a log directory:

mkdir -p /root/cisco-logs

Start screen with logging enabled:

screen -L -Logfile /root/cisco-logs/catalyst-2960-$(date +%Y%m%d-%H%M%S).log \
/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_AH6SK75M-if00-port0 9600

Inside the Cisco session, run the commands you want to capture:

terminal length 0
show version
show inventory
show running-config
show interfaces status
show vlan brief
show ip interface brief

When finished, exit screen:

Ctrl-A
K
y

Then review the log file:

ls -lt /root/cisco-logs/
less /root/cisco-logs/catalyst-2960-*.log

This is one of the easiest ways to collect clean documentation from a Cisco switch in a lab.

Step 10: Disable Old Web Management If Needed

Older Cisco Catalyst switches may have the built-in HTTP or HTTPS management server enabled. If you browse to the switch management IP and get a username/password prompt, that may be the switch’s internal web interface.

For an older lab switch, I prefer disabling web management unless I specifically need it:

configure terminal
no ip http server
no ip http secure-server
end
write memory

Verify:

show running-config | include ip http

Expected output:

no ip http server
no ip http secure-server

For a lab switch, console access is often enough. If remote management is needed later, configure SSH, a local admin user, an enable secret, and management access restrictions.

Troubleshooting

If Linux does not show the serial device, check:

lsusb
dmesg | grep -i -E 'ttyUSB|ftdi|usb serial'
ls -l /dev/ttyUSB* /dev/serial/by-id/* 2>/dev/null

If another program is using the serial port:

fuser -v /dev/ttyUSB0

If the screen is blank:

Press Enter.
Confirm the RJ45 connector is plugged into the console port.
Confirm the baud rate is 9600.
Try minicom if screen behaves oddly.

If the characters are garbled, the serial settings are probably wrong. Most Cisco Catalyst console ports use:

9600 baud
8 data bits
No parity
1 stop bit
No flow control

Final Thoughts

Connecting a Linux server to a Cisco Catalyst switch with a USB-to-RJ45 console cable is a simple and useful lab setup. It lets the Linux server act as a dedicated console workstation for the switch. It also makes it easy to capture switch configuration, check port status, save logs, and perform recovery work without dragging out another machine.

For a home lab, small rack, or learning environment, this is a practical and inexpensive way to manage older Cisco gear from the Linux command line.

82nd Anniversary of D-Day


 

 

 

 

 

 

 

 

 

 

Eighty-two years ago today, freedom stood on the edge of extinction, and Allied forces stormed into hell to help save the world. We will never forget the courage, the sacrifice, and the blood spilled on that fateful day.