Changelog
Version history and release notes for iNetPanel, sourced from GitHub releases.
Release History
v1.24.2 — Installer cascade fix (#14, #15) + per-domain disk cache
Bug Fixes
- Installer fails on fresh Debian 12 (closes #15). The installer's
exec_cmdhelper ran commands in a backgrounded subshell that didn't have/usr/sbinin PATH, soa2enmodfailed. Added a global PATH export near the top ofinstall_LAMP.shand switcheda2enmod/a2ensite/a2dissite/a2disconfto absolute/usr/sbin/paths. - Unusable MariaDB / phpMyAdmin on fresh install (closes #14). Same root cause as #15: when
a2enmodexited early, the installer skipped the sudoers file, phpMyAdmin storage DB, and panel deploy. Without the sudoers rulewww-datacouldn't read the MariaDB root password — producing *"Access denied for user 'root'@'localhost' (using password: NO)"*. Fix #15 resolves the cascade. - Same disk usage shown on every domain for multi-domain users.
accountDisk()was summing/home/<user>(the whole home dir) and the user's DB total on every row. Now a newdisk_cacheSQLite table tracks per-domain file usage,disk_cache_usertracks the per-user DB total, and the Accounts page shows each domain's actual files size plus a single *Total:* badge per user (files across all their domains + MariaDB total). - /admin/accounts load time. With 30+ domains and 100 GB+ data the page hung for seconds while
du -sbran live for every user. Newscripts/system/disk_cache_scan.shpopulates the SQLite cache every 10 minutes via cron, and fires immediately after add/remove/create/delete via backgroundinetpcalls. The API now reads cached rows — O(ms) regardless of dataset size. - README install command now pre-installs
curlfor fresh Debian 12 installs (apt-get install -y curl && bash <(curl -s …/latest)). build_release.shnow also generateslatest-betaalongsidelatest— same installer, just with the download URL swapped to the main-branch zipball so beta testers pull the latest code instead of the tagged release zip.
Performance
Docs / Packaging
v1.24.1 — Dashboard speed + www ServerAlias hotfix
Performance
- Dashboard load time —
/api/accounts?action=listwas runningdu -sb+inetp db_sizefor every hosting user on every dashboard load (5+ seconds with 31 domains), even though the dashboard only displays 6 rows and doesn't use disk usage. Added?limit=Nand?skip_disk=1query params; dashboard now requestslimit=6&skip_disk=1. Accounts page unchanged — still shows disk usage. - Apache vhost missing www ServerAlias — Apex domains (
example.com) had the DNSwwwCNAME auto-created by the Cloudflare tunnel logic, but the Apache vhost only declaredServerName ${DOMAIN}, sowww.{domain}requests fell through to the default vhost.add_domain.shandrestore_account.shnow addServerAlias www.${DOMAIN}for apex domains (dot-count heuristic: exactly 1 dot, not already prefixed withwww.).
Bug Fixes
v1.24 — Backup Restore with CF Migration Support
New Features
- Backup Restore — Full account restore from backup archives with 4-step wizard: Upload (web with progress bar, FTP, SSH/SCP) → Review (username, domains, ports, databases) → Cloudflare routing check with override → Execute with progress and credential summary.
- Domain availability checker —
inetp check_domainsuses RDAP (free, no API key) for single, bulk, and auto-generated variant checks. - CF tunnel migration — Restore override adds route to new tunnel and removes from old tunnel automatically. Searches all account tunnels for domain conflicts, not just the current server's tunnel.
- Tunnel creation fails on fresh install — Removed invalid
tunnel_secretfrom API-managed tunnel creation. - Beta channel update detection — Was always showing "up to date"; now compares commit SHAs.
- Beta version string stacking — Stripped
-beta.x-beta.ychains to just base + latest hash. - Domain deletion "Connection error" — FPM reload in
remove_domain.shkilled panel worker; deferred to after response. - Restore connection reset at 95% — Same FPM reload issue in
restore_account.sh. - Restore FTP login — Fixed nologin shell, sudo permissions, password (now copies root's shadow hash).
- Restore parse on large backups — Replaced full
tar -tzfbuffering with streaming grep pipes (constant memory). - CF CNAME safety —
removeTunnelHostname()now only deletes CNAME if it points to the specific tunnel being cleaned up, preventing breakage when domains are migrated between servers. - CF domain conflict detection —
check_domainandadd_domainnow search all account tunnels, not just the current server's.
Bug Fixes
v1.23.3 — Fix tunnel creation, beta update detection, add domain checker
Bug Fixes
- Tunnel creation fails on fresh install — Removed
tunnel_secretfromcreateTunnel(). API-managed tunnels (config_src: cloudflare) reject client-side secrets; Cloudflare's Rust serde threw a JSON deserialize error. Token is already retrieved separately viagetTunnelToken(). - Beta channel update detection broken —
update_check.phpandsettings.phpcheck_updatesaction only queried GitHub releases API, never checking main branch commits. Beta channel now compares latest commit SHA against installed SHA to properly detect available updates. - Domain availability checker — Added
check_domains.sh(inetp check_domains). Uses RDAP (free, no API key). Supports single domain, bulk file (-f), and auto-generated variant checks (-g keyword).
New Features
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
Release notes are fetched from github.com/tuxxin/iNetPanel/releases and cached for 6 hours.