RHCSA · Enterprise Linux RHEL 9 ShellCheck Verified

SMART PORT
BILLING
INFRASTRUCTURE

Production-grade RHEL 9 deployment for maritime port billing operations — secure, automated, and continuously available.

7 Hardened Scripts
8 RHCSA Skills
30 GB LVM Storage
portbill@rhel9 — system status
portadmin@rhel9:~$
portbill.service active (running) 12d 4h
nginx.service active (running) 12d 4h
firewalld.service active (running) 12d 4h
sshd.service active (running) 12d 4h
portbill-backup.timer active (waiting) → 02:00
SELinux enforcing targeted

Infrastructure Topology

End-to-end deployment stack — from the network perimeter to persistent LVM storage, every layer hardened and automated.

INTERNET Client Requests HTTPS :443 firewalld zone: portbilling Network Perimeter · Rich Rules · Rate Limiting TLS termination nginx :443 → upstream :3000 Nginx · TLS 1.3 · Reverse Proxy 127.0.0.1:3000 podman · read-only · SELinux :Z portbill Container · Node.js :3000 lv: billing-data · 10G XFS /srv/portbill/data lv: billing-logs · 5G XFS /srv/portbill/logs lv: billing-backup · 15G XFS /srv/portbill/backup sshd :2222 · key-only Admin SSH Access billing-admin SELinux enforcing httpd_sys_content_t httpd_log_t ssh_port_t :2222 http_port_t :3000 targeted policy
Data Flow
Volume Mounts
Backup / Admin
Network Perimeter
SELinux Enforcement

Infrastructure Scripts

Seven hardened Bash scripts covering every RHCSA deployment skill — strict mode, ERR traps, idempotent execution, and full structured logging.

01_user_group_setup.sh
bash — lines

RHCSA Skills Matrix

Every script maps to a core RHCSA EX200 objective — from user management and LVM to SELinux contexts and systemd service units.

User & Group Management
01_user_group_setup.sh
useraddgroupaddchagesudoers.d
Storage Management (LVM)
02_storage_lvm.sh
pvcreatevgcreatelvcreatemkfs.xfsfstab
firewalld Configuration
03_firewall_selinux.sh
zonesrich rulesrate limitservices
SELinux Configuration
03_firewall_selinux.sh
semanagefcontextrestoreconsetsebool
SSH Hardening
04_ssh_hardening.sh
sshd_configPubkeyAuthAllowGroupsciphers
Systemd Service Management
05_service_deploy.sh
unit filesExecStartRestart=timers
ACL Configuration
06_acl_backup.sh
setfaclgetfacldefault ACLinheritance
Log Monitoring
07_log_monitor.sh
journalctlrsysloglogrotatealerting

Hardening Deep-Dive

Three independent hardening layers — every directive deliberate, every context explicit.

SELinux Enforcing Mode

Every file, port, and process receives an explicit SELinux context. No policy shortcuts — targeted policy with custom fcontext rules.

Enforcing mode — permanent in /etc/selinux/config
httpd_sys_content_t on /srv/portbill/data
httpd_log_t on /srv/portbill/logs
ssh_port_t on port 2222/tcp
http_port_t on port 3000/tcp
httpd_can_network_connect=on (Nginx→Podman)
Podman volumes mounted with :Z (auto-relabel)
AVC denials logged to /var/log/portbill-avc.log
## Applied by 03_firewall_selinux.sh

# Set SELinux to enforcing (persistent)
setenforce 1
sed -i 's/SELINUX=.*/SELINUX=enforcing/' \
    /etc/selinux/config

# File contexts for billing app
semanage fcontext --add \
  --type httpd_sys_content_t \
  "/srv/portbill/data(/.*)?"

semanage fcontext --add \
  --type httpd_log_t \
  "/srv/portbill/logs(/.*)?"

# Port contexts
semanage port --add \
  --type ssh_port_t \
  --proto tcp 2222

semanage port --add \
  --type http_port_t \
  --proto tcp 3000

# Apply contexts
restorecon -Rv /srv/portbill/

# Booleans — least privilege
setsebool -P httpd_can_network_connect on
setsebool -P httpd_read_user_content  off
setsebool -P httpd_enable_homedirs    off

firewalld Zone Architecture

A dedicated portbilling zone replaces the default public zone, with rich rules restricting SSH to the admin subnet only.

Custom zone: portbilling
Public zone target=DROP
SSH port 2222 — admin subnet only (192.168.10.0/24)
HTTPS from billing LAN (10.10.0.0/16)
HTTP rate-limited to 100 connections/min
Zone target=REJECT (graceful refusal)
All rules permanent (--permanent + reload)
## Applied by 03_firewall_selinux.sh

# Create dedicated billing zone
firewall-cmd --permanent \
    --new-zone=portbilling

# Admin-only SSH (port 2222)
firewall-cmd --permanent \
    --zone=portbilling \
    --add-rich-rule="rule family='ipv4' \
      source address='192.168.10.0/24' \
      port port='2222' protocol='tcp' accept"

# Billing LAN → HTTPS
firewall-cmd --permanent \
    --zone=portbilling \
    --add-rich-rule="rule family='ipv4' \
      source address='10.10.0.0/16' \
      service name='https' accept"

# Rate limit public HTTP
firewall-cmd --permanent \
    --zone=portbilling \
    --add-rich-rule="rule family='ipv4' \
      service name='http' \
      limit value='100/m' accept"

# Graceful rejection of everything else
firewall-cmd --permanent \
    --zone=portbilling --set-target=REJECT

firewall-cmd --reload

SSH Hardening (CIS + NIST)

Key-only authentication on port 2222, restricted to billing-admin group. Crypto limited to FIPS-compatible algorithms.

Custom port 2222 (SELinux-labelled)
PermitRootLogin no
PasswordAuthentication no
AllowGroups billing-admin
MaxAuthTries 3 · LoginGraceTime 30s
X11/Agent/TCP forwarding disabled
Ed25519 + RSA-SHA2 host keys only
ChaCha20 + AES256-GCM ciphers only
## config/sshd_config.hardened

Port                    2222
PermitRootLogin         no
PasswordAuthentication  no
PubkeyAuthentication    yes
AllowGroups             billing-admin

LoginGraceTime          30
MaxAuthTries            3
MaxSessions             5
ClientAliveInterval     300
ClientAliveCountMax     2

X11Forwarding           no
AllowAgentForwarding    no
AllowTcpForwarding      no

LogLevel                VERBOSE
Banner                  /etc/ssh/billing-banner

# FIPS-compatible crypto
KexAlgorithms \
  curve25519-sha256,\
  diffie-hellman-group14-sha256

Ciphers \
  chacha20-poly1305@openssh.com,\
  aes256-gcm@openssh.com

MACs \
  hmac-sha2-512-etm@openssh.com,\
  hmac-sha2-256-etm@openssh.com

Deployment Pipeline

Run scripts in order — each builds on the last. Idempotent design means re-runs are safe at any stage.

01
User & Group Provisioning
./scripts/01_user_group_setup.sh
Creates 4 department groups, 5 users, password policy, sudo rules, and 0750 home directories.
billing-adminbilling-opsport-ops
02
LVM Storage Provisioning
./scripts/02_storage_lvm.sh [device]
Partitions disk, creates PV/VG/3 LVs, formats XFS, writes fstab with UUID, mounts, applies SELinux contexts.
30G totalXFS + noatimeUUID fstab
03
Firewall & SELinux Hardening
./scripts/03_firewall_selinux.sh
Creates portbilling zone, rich rules with CIDR restrictions, rate limiting, SELinux contexts and booleans.
enforcingtargetedREJECT
04
SSH Hardening
./scripts/04_ssh_hardening.sh
Backs up sshd_config, applies hardened config, validates syntax before reload, creates authorized_keys skeleton.
port 2222key-onlyVERBOSE log
05
Application Deployment
./scripts/05_service_deploy.sh
Pulls Podman image, writes systemd unit with hardening directives, generates TLS cert, configures Nginx, health-checks the container.
PodmanTLS 1.3health check
06
ACLs & Automated Backup
./scripts/06_acl_backup.sh
Sets granular POSIX ACLs with inheritance, creates backup script with SHA-256 integrity, enables systemd timer for daily 02:00 backup.
setfacl -dsha256sum30-day retention
07
Log Monitoring & Alerting
./scripts/07_log_monitor.sh
Configures rsyslog routing, logrotate with 90-day retention, creates real-time monitor service with email alerts, daily summary timer.
rsysloglogrotatejournalctl

Technologies Used

RHEL 9
Red Hat Enterprise Linux 9 — primary deployment OS
Nginx
TLS reverse proxy with security headers and upstream health
Podman
Rootless OCI containers with systemd integration on RHEL 9
Bash
Strict-mode scripts with ERR trap, structured logging, color output
SELinux
Enforcing mode — targeted policy with custom fcontext rules
LVM + XFS
Logical volume management with XFS filesystem and UUID fstab
Firebase
Cloud Firestore backend for billing transaction persistence
Vercel
Global CDN deployment for this portfolio showcase site

Interactive Deployment Runner

Configure and simulate running all 7 infrastructure scripts — real RHEL 9 output, live system state, fully in-browser.

Ready — configure inputs and click Run 0 / 7
01 02 03 04 05 06 07
SCRIPTS
portadmin@rhel9:~
Configure parameters above, select a script and click Run,
or click ▶ Run Full Deployment to simulate the complete RHEL 9 infrastructure setup.
SYSTEM STATE