Changelog
Version history and release notes for iNetPanel, sourced from GitHub releases.
Release History
Hotfix
- Installer fails to download panel source —
install_LAMP.shwas pointing atinetpanel.tuxxin.com/inetpanel-latest.zip(404). The zip is a GitHub release asset, not hosted on the website. Fixed URL togithub.com/tuxxin/iNetPanel/releases/latest/download/inetpanel-latest.zip.
Install / Update
bash <(curl -s https://inetpanel.tuxxin.com/latest)
Hotfix
- Multi-PHP install fails silently on fresh installs — The
/var/www/inetpanel/storage/directory wasn't created during deployment, causing status files and logs to never be written. The API now creates the directory if missing and returns a clear error if it can't.
Install / Update
bash <(curl -s https://inetpanel.tuxxin.com/latest)
Existing installs: run inetp panel_update from the admin panel or CLI.
New: Release Channels (Stable vs Beta)
- Installer now uses release tarballs instead of
git clone— the repo (mainbranch) is now beta code, while GitHub Releases are stable.
- - Settings → Updates → Release Channel — toggle between stable and beta without reinstalling. Stable pulls from tagged releases, beta pulls the latest commit from
main. - Multi-PHP install broken on all environments —
systemd-run --scopefails silently in LXC/Proxmox containers with no fallback, leaving the status file stuck at "running" forever. Added direct background execution fallback when systemd-run fails. Simplified the API exec() call and set a 3-minute timeout.
inetpanel.tuxxin.com/latest — stable installer (downloads release zip)
- inetpanel.tuxxin.com/latest-beta — beta installer (clones main branch)
Fixes
Install / Update
bash <(curl -s https://inetpanel.tuxxin.com/latest)
Existing installs: run inetp panel_update from the admin panel or CLI.
Fixes
- Dashboard disk stats inflated —
disk_free_space()excludes ext4 reserved blocks (~5%), making "used" appear ~10 GB higher than reality. Now usesdfoutput for accurate numbers matching what the OS reports. - PHP 5.6 install timeout — Polling timeout increased from 120s to 360s. Older PHP versions take longer to install via apt.
- SSH port fix for LXC containers — Previous fix only checked
is-activeonssh.socket, which misses cases where the socket is enabled but not yet active (common in LXC). Now checkslist-unit-filesandmasks the socket unit to prevent reactivation.
Install / Update
curl -o latest https://inetpanel.tuxxin.com/latest && bash latest
Existing installs: run inetp panel_update from the admin panel or CLI.
Fixes
- SSH port ignored on Debian 12 — Installer now disables
ssh.socket(systemd socket activation hardcodes port 22, overridingsshd_config Port 1022) - SSL cert reissue blocked after self-signed fallback — Cleans up non-LE certs from
/etc/letsencrypt/live/before certbot retry - CertBot DNS propagation timeout — Added
--dns-cloudflare-propagation-seconds 30(default 10s was too short) - Dashboard graph empty on fresh install —
inetpanel_statswas missing frommanage_cron.shallowed list, so the stats collector cron was never created inetp optimize_server— Auto-tunes Apache2mpm_eventand MariaDB InnoDB/buffers based on detected RAM, CPU cores, disk type (SSD/HDD), and hosted domain count. Dry-run by default,--applyto write changes with automatic config backups.
New
Install / Update
curl -o latest https://inetpanel.tuxxin.com/latest && bash latest
Existing installs: run inetp panel_update from the admin panel or CLI.
Logo rebrand & dark mode fixes (v1.22.1)
New branding
- New logo — redesigned iNetPanel logo (PNG with transparency), replaces old
.webp - Favicon — new
Logo-Icon.webpfavicon added to admin and account portals - Logo automatically inverts to white in dark mode via CSS filter
- Account portal logo resized to 28px for cleaner navigation fit
- Table headers —
.table-light<thead>elements now display light text (previously black on dark background) - Nav tabs — dark mode styling for tabbed interfaces (multi-php, firewall pages)
- Bootstrap 5.3 subtle utilities —
bg-success-subtle,bg-primary-subtle,bg-warning-subtle,bg-danger-subtlewith proper dark variants - Close button — filter inversion for visibility on dark backgrounds
- Warning badges — retain dark text for contrast on yellow background
- Table borders — consistent border color in dark mode
Dark mode — root-level fix
The core issue with dark mode was that Bootstrap 5.3 uses internal CSS variables (--bs-body-color, --bs-table-color, --bs-border-color, etc.) that our custom [data-theme="dark"] wasn't overriding. This caused all Bootstrap components to inherit dark text colors regardless of theme.
Fix: Override all Bootstrap 5.3 internal CSS variables at the [data-theme="dark"] root level. This makes every Bootstrap component — tables, cards, headings, links, borders — automatically inherit correct dark mode colors without needing per-component overrides.
Specific fixes
Pages fixed
Accounts, DNS, Email, SSL, Firewall, Multi-PHP, Services, and all other pages that use Bootstrap tables, cards, or badges.Closes #10
Dark mode audit & fixes (v1.22)
Addresses #10 — dark mode inconsistencies and unreadable text.
CSS additions (58 new dark mode rules)
- Badges —
bg-light,text-dark,bg-secondarynow theme-aware - Alerts — info, success, warning, danger with proper dark backgrounds and contrast
- Pre/code blocks — proper dark background and text colors
- Buttons —
outline-dark,outline-secondary,btn-lightvariants - Components — breadcrumbs, nav pills, pagination, input groups, progress bars, accordion, offcanvas, toast
- Logo — brightness inversion filter for dark sidebar backgrounds
- Dashboard chart grid/tick colors now adapt to theme
- QR code colors invert in dark mode (light modules on dark background)
- Removed hardcoded
#e8f4f8alert background in settings - WireGuard code block uses theme-aware
bg-lightinstead ofbg-white
Hardcoded color fixes
Fix PHP package extension install/remove (v1.21.9)
Same root cause as v1.21.8 — dpkg triggers restart php-fpm during apt-get install/remove of individual extensions (e.g. php8.5-uploadprogress), killing the PHP worker mid-request.
Changes
- Extension install/remove now runs inside
systemd-run --scopeto escape the FPM cgroup - Frontend uses async status polling with progress modal (matches multi-php pattern)
- Modal only shown after API confirms operation started (prevents stuck modal on errors)
- Added
pkg_statusAPI endpoint for polling extension install/remove progress
Fix Multi-PHP install/remove (v1.21.8)
Root cause: dpkg triggers restart php-fpm during package install/remove, which kills all processes in the FPM cgroup — including the background apt script launched from PHP exec(). nohup/setsid don't help because systemd kills by cgroup, not process group.
Changes
- Script re-launches itself via
systemd-run --scopeto escape the FPM cgroup before running apt - Fixed status file path mismatch between API and backend script
- Fixed concurrent operation guard falling through to
exec()instead of breaking the switch - Modal now only shown after API confirms success (prevents stuck modal on errors)
- Status file removed immediately after verification, before slow post-cleanup steps
- Moved apt logic from inline PHP to dedicated
multiphp_manage.shbash script
v1.21.7 — Fix Multi-PHP: detached apt execution
Bug Fix
Multi-PHP install/remove silently fails
apt-get ran inside the PHP-FPM worker process. dpkg post-install hooks restart php-fpm, which kills the worker mid-execution — apt never completes, status file stuck at 'running', modal spins forever.
Fix: All apt operations now run in a detached bash script (sudo bash script.sh &) that survives FPM restarts. The script handles the full lifecycle: dpkg configure, apt install/purge, FPM enable/start, upload limits, module reinstall, and cleanup. Status tracking via temp file allows the polling UI to detect success (file removed) or failure (file contains 'error').
Files Changed
api/multiphp.php— Detached bash wrapper for apt operationssrc/multiphp.php— Improved polling with seenRunning state trackingTiCore/Version.php— Version bump
v1.21.6 — Fix Multi-PHP status tracking
Bug Fix
Multi-PHP status file stuck at 'running'
The v1.21.5 status file mechanism never transitioned from 'running' to 'done' because dpkg post-install hooks triggered an FPM restart that killed the PHP worker before it could update the file. The polling modal would spin until timeout.Fix: Status file is deleted immediately after apt succeeds, before any FPM operations. On apt failure, error is written and execution stops immediately.
Files Changed
api/multiphp.php— Reorder status file cleanup before FPM operationsTiCore/Version.php— Version bump
v1.21.5 — Fix Multi-PHP background failure detection
Bug Fix
Multi-PHP install/remove modal spins forever on failure
Whenapt-get failed silently in the background (e.g. package not available, dpkg lock), the polling modal would spin indefinitely since the version state never changed.
Fix: Background apt operations now write status to a temp file. The polling list action reports this status, allowing the UI to detect errors and show them immediately instead of spinning for 3 minutes.
Files Changed
api/multiphp.php— Status file tracking for background apt operationssrc/multiphp.php— Poll checks for background error statusTiCore/Version.php— Version bump
v1.21.4 — Fix Multi-PHP removal & FPM pool cleanup
Bug Fixes
Multi-PHP removal causes 500 error
Removing a PHP version via the admin UI triggered an Internal Server Error becauseapt-get purge restarted the panel's own PHP-FPM process mid-request.
Fix: apt-get now runs after fastcgi_finish_request() so the browser receives a success response before the package removal begins. The UI polls until the version is fully removed before closing the progress modal.
Multi-PHP removal leaves packages behind
The purge command only removed specific packages (fpm, cli, common, etc.) but missed sub-packages like bz2, gd, intl — leaving the binary installed.Fix: Uses wildcard php{ver}-* purge + apt-get autoremove to fully remove all packages for that version.
FPM pools not cleaned up on domain/account removal
Removing a domain or account from the admin UI deleted the pool config file but never reloaded PHP-FPM, leaving orphaned worker processes running.Fix: Both the shell script and API now reload FPM after pool removal.
Database creation SQL syntax error
Creating a database from the client portal failed with "Unknown command" due to escaped backticks in the SQL statement.New Features
inetp rebuild_pools
New CLI command to regenerate all missing PHP-FPM pool configs from the panel database. Useful for recovery after pool files are accidentally deleted.
Dashboard "Accounts & Domains"
The dashboard card now shows both account count and domain count (e.g. "3 / 5").Files Changed (9 files)
TiCore/Version.php, api/account.php, api/accounts.php, api/multiphp.php, scripts/system/inetp, scripts/system/rebuild_pools.sh, scripts/system/remove_domain.sh, src/dashboard.php, src/multiphp.php
v1.21.3 — Fix backup toggle and retention
Bug Fixes
Backup toggle not disabling backups
Toggling backups off in admin settings had no effect — the cron was always written with the backup command, and the script never checked thebackup_enabled setting. Fresh installs saw system config backups appearing even with backups toggled off.
Fix:
api/settings.php: Checksbackup_enabledbefore writing backup cron; writes a disabled comment when offbackup_accounts.sh: Exits early ifbackup_enabled = 0(safety net);--singlemode still works for domain removalapi/settings.php— Backup toggle cron logicscripts/system/backup_accounts.sh— Early exit guard + retention fixTiCore/Version.php— Version bump
Backup retention not cleaning old files
The retention cleanup never removed old backups becauseMTIME_DAYS was calculated inside the loop body but used in the find command's process substitution (which runs before the loop).
Fix: Moved MTIME_DAYS calculation before the find command.
Files Changed
v1.21.2 — Fix database creation, updated README
Bug Fix
Database creation from client portal
CREATE DATABASE used escapeshellarg() which wraps the name in single quotes — MySQL requires backticks for identifiers. All database creation attempts from /user/dashboard#database failed with ERROR 1064. Now uses backtick-wrapped identifiers with regex sanitization.
Updated
- README rewritten — streamlined with home hosting focus, technical stack details, directory layout, and links to [inetpanel.tuxxin.com](https://inetpanel.tuxxin.com) for full documentation
api/account.php— Fix CREATE DATABASE SQL syntaxREADME.md— RewriteTiCore/Version.php— Version bump
Files Changed
v1.21.1 — Fix: Missing cron jobs on fresh install
Bug Fix
Fresh installs missing stats collector and backup cron jobs
New installations were not setting up thestats_collector.sh cron (runs every minute) or the backup_accounts.sh cron (runs daily). These were only created by panel_update.php during subsequent updates, not during initial setup.
Symptoms: Dashboard graph shows no data, automated backups never run.
Fix: install.php now creates both cron jobs during initial setup:
/etc/cron.d/inetpanel_stats— stats collector every minute/etc/cron.d/lamp_backup— daily backup at configured timepublic/install.php— Add stats and backup cron setupTiCore/Version.php— Version bump to 1.21.1
Note: Existing installations already have these crons (created by panel_update.php). This fix only affects new installations.
Files Changed
v1.21 — Public Release
Public Release
iNetPanel is now open source. This release removes all private repository requirements and prepares the codebase for public access.
Changes
Repository Access
- Removed GitHub Personal Access Token (PAT) from admin settings, update system, and installer
install_LAMP.shno longer prompts for authentication — clones directly from the public repo- Update system (
panel_update.php) works without authentication tokens - Creating a server hostname DNS record with a private IP (192.168.x, 10.x, 172.16-31.x) now sets
proxied: false— Cloudflare cannot proxy traffic to private addresses - Applies to both the installer (Step 5) and admin Settings > General
- Existing installations with a
github_tokensetting: the token is harmlessly ignored and can be removed from the database - No breaking changes — all existing functionality works as before
Bug Fix: Private IP + Cloudflare DNS
Upgrade Notes
Installation
bash <(curl -s https://inetpanel.tuxxin.com/latest)
Links
v1.20.4 — Critical: FPM Pool Recovery
Critical Fix
Auto-regenerate missing PHP-FPM pools on update
After an update,panel_update.php now checks all domains in the database and regenerates any missing FPM pool configs in /etc/php/{ver}/fpm/pool.d/. This prevents 503 Service Unavailable errors when PHP-FPM reloads and finds an empty pool directory.
If you're seeing 503 errors on all Apache-hosted sites, run the panel update from Settings > Updates — it will automatically detect and recreate missing pool configs, then reload FPM and Apache.
Firewall port range display
Fixed the firewall UI not showing port ranges like40000-50000/tcp (used by FTP passive mode).
Files Changed
scripts/panel_update.php— FPM pool safety check + regeneration after every updateapi/firewall.php— Port range regex fixTiCore/Version.php— Version bump
v1.20.3 — Hardened update script
Fix
- Hardened rsync ownership handling — Added
--chown=www-data:www-datadirectly to the rsync command so files are synced with correct ownership in a single operation. The post-rsyncchownis kept as a safety net. This eliminates the 403 error that occurred in v1.20.1 where the executing (old) update script lacked the ownership fix.
v1.20.2 — Critical: Fix 403 after update
Critical Fix
- 403 Forbidden after panel update — The rsync in
panel_update.phpruns as root and overwrites file ownership toroot:root. Lighttpd/PHP-FPM runs aswww-dataand cannot read the files, causing a 403 error on all pages. Fixed by restoringwww-data:www-dataownership immediately after rsync.
chown -R www-data:www-data /var/www/inetpanel/
Then update again from the admin panel to get this permanent fix.
v1.20.1 — Patch: Migration Fix & Live Clock
Fixes
- Database migrations not running on update — rsync excluded the entire
db/directory includingdb/migrations/. Now only excludesdb/inetpanel.db,db/.installed, anddb/.admin_pass. Users updating from v1.20 will now get thestats_historytable created automatically, enabling the dashboard resource graph. - PMA config patching regex warnings — "Unknown modifier" and "Undefined variable $i" warnings during panel update. Switched regex delimiter from
/to#. - Admin header live clock — Clock now ticks live every second, matching the client portal.
v1.20 — CLI Tools, Portal Redesign & Installer Hardening
New Features
11 New CLI Commands
inetp status— Server health summary (uptime, load, disk, RAM, services, SSL, backups)inetp benchmark— Quick disk I/O, network speed, PHP opcache, MySQL query benchmarksinetp reset_password --username USER— Reset FTP/SSH/MySQL passwordinetp disk_report— Disk usage breakdown per user with top files/directoriesinetp audit— Security audit (permissions, PHP versions, open ports, weak passwords, fail2ban)inetp malware_scan --username USER— Scan for PHP backdoors/webshellsinetp cleanup— Clear temp files, old logs, orphaned FPM pools, stale sessionsinetp rotate_logs— Force logrotate on all user/system logsinetp db_repair— Check and repair all MariaDB tablesinetp dns_check --domain DOMAIN— DNS propagation, SSL chain, HTTP response, CF tunnel checkinetp speedtest— Server bandwidth test (curl-based, no dependencies)- Historical CPU, memory, and network usage with 1h/24h/7d views
- Background stats collector cron (every minute) populates
stats_historytable - Smooth Chart.js graphs with time-based x-axis labels
- Overview: All domains listed in compact table with PHP version, web root, port, disk, status
- Database: List existing databases, create new with
username_prefix, delete modal with PMA link - Multi-PHP: Change PHP version per domain with dropdown
- Optimize: Image optimization with directory selection and dry-run preview
- Backups: View and download account backups
- File Manager: .htaccess editor with directory tree + password protection
- FTP/SSH and SSH Keys moved to bottom of Overview tab
- Domain dropdown only in File Manager and Optimize tabs
- Live clock in header, user icon
- Verify button checks Cloudflare DNS for hostname existence
- Auto-create A record if hostname is available
- Server IP detection with private/public IP notice
- Configured passive port range (40000–50000) in
vsftpd.conf - Opened passive ports in firewalld
- Fixes FTP upload failures on large batch transfers (GitHub issue #8)
latestfile included in repo for web hosting atinetpanel.tuxxin.com/latest- Support widget in sidebar footer (admin) and portal footer
- Firewall rule ordering — WG rules now added before restrictive DROP rules
- Peer IP allocation — sequential /32 addresses from WG subnet
- Config validation — prevents duplicate peers and invalid IPs
- Peer cleanup on user deletion
- Uninstall script fixes ListenAddress and port fallback
- Lock file now blocks ALL requests (GET and POST) after installation
stats_historytable added to install schema (schema_version bumped to 2)- MariaDB timezone tables loaded (
mysql_tzinfo_to_sql) before setting timezone - Timezone config only persisted if runtime SET succeeds
event.target→ button parameter fix for Cloudflare test button- Server IP fallback for DNS record creation
- Null coalescing for POST values
- Settings hostname verify uses public CloudflareAPI methods (was calling private
request()) - Multi-PHP version change uses
fastcgi_finish_request()before FPM reload (prevents 500 error) - Database listing uses
sudo /bin/catfor MySQL root password (www-data can't read directly) - Admin PMA sidebar link routes through auto-login
Dashboard Resource Graph
Client Portal Redesign
Settings Hostname Verification
VSFTPD Passive Mode Fix
Installer Distribution
Buy Me a Coffee
Bug Fixes
WireGuard
Installer Hardening
Other Fixes
Files Changed (37 files, +4334 / −290)
v1.19 — Client Portal Overhaul & phpMyAdmin Auto-Login
New Features
Client Portal Overhaul
- Complete redesign with tabbed dashboard: Overview, Database, FTP / SSH, File Manager, Backups, DNS, and Email
- SSH Key Management — generate, import, and delete SSH keys directly from the portal
- .htaccess File Manager — browse directories, edit
.htaccessfiles, and password-protect directories with.htpasswd(supports multiple users) - Backups tab — view and download your account backups
- Database info — explains
username_*prefix convention for creating additional databases - Token-based signon authentication — one-click login from both admin panel (as root) and client portal (as hosting user)
- Deploys
signon.phpand patches PMA config automatically on panel update - Fallback login form prevents redirect loops when accessing PMA directly
- Toggle Under Attack Mode and Development Mode per zone from admin DNS page and client portal DNS tab
- Immediate Cloudflare API calls with status feedback
- Automated backups now include system configuration files: Apache, PHP, MariaDB, lighttpd, fail2ban, WireGuard, SSH, cron, vsftpd, and the panel SQLite database
- Same retention policy as user backups
- Changing timezone in Settings or during installation now updates MariaDB global timezone and persists to
/etc/mysql/mariadb.conf.d/99-timezone.cnf - URL hash navigation:
/admin/settings#general,#cloudflare,#updates, etc. - Hash updates in address bar on tab switch for bookmarking/sharing
- Banned username list (50+ system names) prevents creating hosting accounts with names like
root,admin,www-data,mysql, etc. - Auto-generated usernames from domains are prefixed if they collide with reserved names
- Admin PMA sidebar link now routes through
/admin/phpmyadminfor auto-login instead of linking directly to port 8443 - Portal PMA no longer falls back to root for regular user sessions
conf.d/pma_secure.phpoverride patched during panel update
phpMyAdmin Auto-Login
Cloudflare DDoS & Development Mode
System Config Backups
MySQL Timezone Sync
Settings Deep Links
Reserved Usernames
Bug Fixes
Files Changed (16 files, +1520 / -293)
README.md, TiCore/AccountAuth.php, TiCore/CloudflareAPI.php, TiCore/Version.php, api/account.php, api/accounts.php, api/dns.php, api/settings.php, public/index.php, public/install.php, scripts/panel_update.php, scripts/system/backup_accounts.sh, src/account/portal.php, src/dns.php, src/settings.php, themes/default/sidebar.php
v1.18 — SSH Key Fix, UI Improvements
Bug Fixes
SSH Keys — chown invalid group (Fixes #3)
Hosting users are created withwww-data as their primary group, but manage_ssh_keys.sh and fix_permissions.sh used chown user:user which fails because no personal group exists. Changed to chown user:www-data.
SSH Key Delete Button
The delete button in the SSH Keys modal did nothing when clicked. Theonclick attribute used double quotes inside a double-quoted HTML attribute, silently breaking the click handler.
Form Autofill on Add Account
Chrome aggressively autofilled the username, domain, and password fields on/admin/add-account with saved login credentials. Fixed with readonly-on-focus trick for text fields and autocomplete="new-password" for password fields.
Files Changed
scripts/system/manage_ssh_keys.sh— chown fixscripts/system/fix_permissions.sh— chown fix + corrected commentsrc/accounts.php— SSH key delete button quote fixsrc/add_account.php— anti-autofill attributesTiCore/Version.php— version bump to 1.18
v1.17 — Hook Scripts Fixes
Bug Fixes
Hook Scripts — 3 bugs fixed
1. PHP comment broke entire page JS — A // comment containing ?> prematurely closed the PHP block (a known PHP gotcha where ?> exits PHP mode even inside single-line comments). The nowdoc template assignment never executed, causing a fatal Undefined constant "SITE_TITLE" error that silently killed the <script> block. No buttons, toggles, or API calls worked.
2. Windows CRLF line endings broke bash validation — Windows browsers send \r\n in form data. Bash heredoc closing markers like HOMEEOF\r weren't recognized, causing "unexpected end of file" errors on Save/Validate. Fixed by stripping \r in the save, validate, and hook execution paths.
3. Hook scripts failed silently due to sudo permission — www-data didn't have passwordless sudo for /bin/bash, so hooks logged "a terminal is required to read the password" and failed without any user-visible error. Added a scoped sudoers rule restricted to /bin/bash /tmp/inetp_hook_*.
Files Changed
src/hook_scripts.php— Fixed PHP commentapi/hook_scripts.php— Strip\rin save and validate actionsapi/accounts.php— Strip\rinexecuteHook()scripts/panel_update.php— Added sudoers rule for hook executionTiCore/Version.php— Version bump to 1.17
v1.16 — Update Notifications & Hook Scripts Fix
Changes
Update Notification Improvements
- Removed duplicate "Update available" banner from sidebar footer — notification now only shows in the header bar
- Added automatic version check on login so the header notification is immediately current
- Header notification auto-clears after a manual panel update (no stale cache)
- Fixed Hook Scripts page: All buttons (Save, Validate, TiCore Template) and toggle switches were non-functional. The TiCore template contained
<?= ?>PHP tags inside a JavaScript template literal — PHP processed them as code, causing a fatal error that silently broke the entire<script>block. Fixed by using a PHP nowdoc +json_encodeto safely embed the template.
Bug Fix
v1.15 — Hook Scripts
Hook Scripts
New admin page for running custom bash code automatically after domain creation or deletion.
Features
- Post Add Domain and Post Delete Domain hook editors with syntax highlighting
- Toggle on/off per hook — saves immediately via AJAX without losing code
- Bash syntax validation (
bash -n) before saving — prevents broken scripts - Available Variables reference tables for each hook type (DOMAIN, USERNAME, PORT, DOC_ROOT, etc.)
- TiCore Template — one-click auto-populate with a full TiCore PHP Framework deployment script
- Hook execution runs after
fastcgi_finish_request()— never blocks the API response - Hook failures are logged but never break domain operations
api/hook_scripts.php— New API endpoint (get/save/toggle/validate)src/hook_scripts.php— New admin UI pageapi/accounts.php—executeHook()function + 4 hook call pointspublic/index.php— Page route + API routethemes/default/sidebar.php— Nav link under System sectionTiCore/Version.php— Version bump to 1.15
Hook Variables
Add Domain: DOMAIN, USERNAME, PORT, DOC_ROOT, WEB_ROOT, LOG_DIR, SERVER_IP, PHP_VER, DB_NAME, DB_USER, DB_PASS Delete Domain: DOMAIN, USERNAME, PORT, DOC_ROOT, SERVER_IPFiles Changed
v1.14 — Beta Bug Fixes
What's New
- Accounts filter: Fixed browser autocomplete filling the filter input with saved login credentials
- Services & SSL refresh buttons: Fixed Refresh button not responding to clicks
- Service monitor toggle: Now surfaces errors if the cron job fails to install/remove
- Accounts disk size: Total now includes MariaDB database sizes (not just
/homefilesystem usage) - Settings > Updates: "Check Now" dynamically shows/hides the Update button without a page reload; page reloads automatically after an update completes
v1.13 — Installer Fix, PHP API Hardening & Bug Fixes
What's New in v1.13
Critical Installer Fix
- Fixed installer crash on minimal Debian 12: Added \
sudo\to base dependencies and \mkdir -p /etc/sudoers.d\before writing the sudoers file — the installer was failing at the sudo rules step on fresh minimal installs, skipping panel deploy, crons, and firewall setup - Fixed 404 on sidebar restart button: "Yes, Restart Now" in the sidebar modal was linking to \
/dashboard/restart\(no route) — now correctly POSTs to the API - Fixed firewall page crash (PHP 8.x TypeError): \
Shell::exec()\returns an array; all callers in \api/firewall.php\were passing it to \trim()\as a string, crashing the entire firewall status page on PHP 8.x - install.php POST bypass fixed: POST to \
action=install\was not blocked by the lock file check — re-installation was possible after setup - Server-side input validation added to installer: Username and password were only validated in the browser; backend now enforces format and minimum length
- Backup path traversal protection: \
backup_destination\setting now validated before save (must be absolute path, no \..)\ - DNS/Email read actions restricted to admin: \
zones\, \list\, \list_rules\, \list_addresses\were accessible to sub-admins who could see all Cloudflare zones/records - Backup list/settings now require admin role: Sub-admins could previously enumerate all backup files
- Installer DB transaction: All schema creation and settings inserts are now wrapped in a transaction — partial DB state is rolled back and cleaned up on failure so the install can be retried
- Lock file written after commit: Previously written before system config steps; now written only after the DB is fully committed
- Exec error logging: \
timedatectl\, \hostnamectl\, \cloudflared_setup\, and \panel_ssl\exit codes are now captured and logged - Cron write error checking: \
popen()\/\pclose()\calls for cron management now check return values and log failures - phpBin sanitized in settings API: \
ddns_test\action now uses \escapeshellarg()\and validates the PHP version string before executing - Dynamic PHP version detection: Replaced hardcoded version arrays with \
glob('/usr/sbin/php-fpm*')\detection in both the installer and panel bootstrap - Confirm password field added to installer: Previously a single password field with no confirmation
- Simplified installer progress display: Replaced fake staged progress bar (with hardcoded delays) with a simple spinner that shows the real result immediately
Bug Fixes
Security Hardening
Resilience
UX
v1.12 — Debian 12 Resilience Hardening
Debian 12 Resilience Hardening
Hardens all 15 system scripts for reliable operation across diverse Debian 12 server configurations.
MySQL / MariaDB
- Socket auth fallback — all 6 database scripts now work with both password-file and socket authentication (
create_user,add_domain,delete_user,remove_domain,change_password,backup_accounts) - Password escaping —
change_password.shnow properly escapes single quotes and backslashes in SQL - Removed
grep -P(Perl regex) — replaced with portablegrep -oEand bash[[ =~ ]]acrosscreate_user,remove_domain, andsuspend_account - Auto-detect PHP-FPM version —
panel_ssl.shno longer hardcodes PHP 8.5; detects installed version at runtime - Dynamic network interface detection —
wireguard_setup.shfinds first non-loopback interface instead of assumingeth0 - SSH lockout prevention —
update_ssh_port.shvalidates sshd config (sshd -t) before restart; reverts on failure - certbot/openssl checks —
ssl_manage.shverifies tools exist before attempting certificate operations - mysqldump failure detection —
backup_accounts.shnow reports and removes empty SQL dumps instead of archiving them silently - cloudflared validation —
cloudflared_setup.shvalidates binary path before writing systemd service file - WireGuard install verification —
wireguard_setup.shconfirmswgcommand exists afterapt-get install - Graceful process termination —
delete_user.shsends SIGTERM, waits, then SIGKILL (was immediate SIGKILL) - service_monitor.sh — fixed false positives where non-existent services were never skipped (systemctl always returns 0)
- panel_ssl.sh — prevent duplicate
mod_openssl/mod_redirectinsertion on re-run - wireguard_setup.sh — prevent duplicate
net.ipv4.ip_forwardentries in sysctl.conf - wireguard_uninstall.sh — reads WireGuard port from config before cleanup (was undefined)
- wg_peer.sh — removed
localkeyword used outside functions (undefined behavior) - suspend_account.sh — removed dead
PHP_VER="8.4"variable
Portability Fixes
Safety & Error Handling
Bug Fixes
Files Changed
16 files, 123 insertions, 40 deletionsRelease notes are fetched from github.com/tuxxin/iNetPanel/releases and cached for 6 hours.