Fix orphaned Apache vhosts and the 502 they cause (#17) - #20
Merged
Conversation
delete_account.sh found a user's domains by globbing /home/<user>/*/www. If that directory was already gone — a partial delete, a manual rm, or delete_user.sh --force removing the home dir first — the glob found nothing, remove_domain.sh never ran, and the Apache vhost survived pointing at a DocumentRoot and ErrorLog dir that no longer existed. Apache keeps serving on its already-loaded config, so nothing looks wrong until the next full restart (an apt upgrade, a reboot), at which point a missing log directory is fatal and Apache refuses to start at all — taking every site on the box down with it. Reported in #17, where an apt upgrade turned a long-dead vhost into a 502 across all three sites. Take the union of the filesystem, the panel DB, and the vhosts whose DocumentRoot lives under the user's home. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
remove_domain.sh ran `systemctl reload apache2 || systemctl restart apache2`, which is backwards: a reload that fails leaves the running (good) config serving, but a restart on a broken config takes every site on the box down. add_domain.sh reloaded with no validation at all, so a bad vhost could sit latent until something restarted Apache. Both now run apache2ctl configtest first. add_domain.sh additionally disables the vhost it just wrote if validation fails, so a bad add can never become a boot-time outage. Also stop clobbering live sites: add_domain.sh supports recreating an existing domain (see the vhost cleanup near the top), but unconditionally copied the welcome placeholder over www/index.php — data loss for anyone re-adding a domain to regenerate its vhost. Only write it into an empty web root now. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
rebuild_pools.sh regenerates missing PHP-FPM pools from the panel DB, but
there was no equivalent for Apache. A domain whose vhost went missing had
to be rebuilt by hand, and add_domain.sh was the obvious tool to reach
for — which would overwrite the site's index.php.
Two jobs, both driven by the panel database:
MISSING — a domain the panel knows about with no vhost in
sites-available, regenerated from add_domain.sh's template.
Existing vhosts are never touched.
ORPHANED — an enabled vhost whose DocumentRoot or ErrorLog directory no
longer exists. Reported by default; --disable-orphans
a2dissites them.
--check reports without modifying anything. Nothing is reloaded unless
apache2ctl configtest passes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The arg loop discarded anything that wasn't --domain, so the documented- looking `inetp dns_check example.com` failed with "Domain is required (--domain)" — confusing enough that it cost a round trip in #17 while diagnosing an outage. Positional domains now work; --domain still does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`grep "APP_VERSION" Version.php | grep -oP "'[^']+'"` matched every line
mentioning APP_VERSION — the doc comments, the User-Agent string, and the
self-update regex — so CURRENT_VER became a multi-line blob that printed
as garbage under "Panel":
Version: 1.24.4
User-Agent: iNetPanel/
available
latest
...
and, never equalling panel_latest_ver, made every run claim an update was
available. Match only the constant declaration, and compare with sort -V
so a stale panel_latest_ver can't read as newer.
Also fall back to ASCII for the box rules and status dots when the
terminal isn't UTF-8 — in the Proxmox/noVNC console these rendered as a
row of '?' characters.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The port was written straight into /etc/ssh/sshd_config, which is
ucf-managed on Debian: upgrading openssh-server prompts whether to keep
your version or take the maintainer's, and taking the maintainer's
silently reverts the port — locking you out on the next reconnect, with
no clue why. Write to /etc/ssh/sshd_config.d/99-inetpanel.conf instead
when the main config includes that directory (bookworm does by default),
falling back to the old behaviour when it doesn't.
While here:
- detect the current port from `sshd -T` rather than only grepping the
main file, so a port set in a drop-in is seen
- confirm sshd actually came back on the new port before reporting
success — reporting a change that didn't take effect is how people
get locked out
- back up and fully restore both files on the revert path
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the root cause behind #17 (all sites 502 after an
apt upgrade) plus everything else that turned up while reproducing it.The outage chain
A domain deleted at some earlier point left its vhost in
sites-enabledpointing at aDocumentRootand log directory that no longer existed. Apache kept serving on its already-loaded config, so nothing looked wrong — untilapt upgraderestarted it. A missing log directory is fatal at startup, Apache refused to come up, and cloudflared had no origin to reach. Hence 502 on every site at once rather than one.delete_account.shenumerated a user's domains by globbing/home/<user>/*/www. With the home dir already gone, the glob found nothing,remove_domain.shnever ran, and the vhost was orphaned.Changes
4742bb8delete_account.sh— enumerate domains from the filesystem, the panel DB, and vhost ownershipcc0b564remove_domain.sh/add_domain.sh—configtestbefore reload; never escalate a failed reload to a restart; stop overwriting a live site'sindex.phpon recreate7b6046binetp rebuild_vhosts— regenerate missing vhosts from the DB, report/disable orphans4b31edddns_check.sh— accept a bare domain9d18224status.sh— version parse,sort -Vupdate comparison, ASCII fallback for non-UTF-8 consolese7b09c0update_ssh_port.sh— port lives insshd_config.d/99-inetpanel.conf, verify it took effect, full revert on failureThe
reload || restartfallback deserves calling out: a reload that fails is harmless (the good config keeps serving), but the restart that followed it took the whole box down. That ordering turned a single bad vhost into a total outage.Verification
Run against a live 1.24.4 box with 35 domains:
bash -nstatus.shreproduced the exact garbage block from 502 Bad Gateway on a Cloudflare-tunneled site #17, and the fix printsVersion: 1.24.4 / Update: up to datestatus.shrenders correctly under bothLANG=C.UTF-8andLC_ALL=Cdns_check.shacceptsexample.com,--domain example.org, and--verbose example.netrebuild_vhosts --checkdry-ran clean: 35 skipped, 0 missing, 0 orphanedrebuild_vhostsgenerates reproduces an existing vhost byte for byte (port and FPM socket path both match)update_ssh_port.shis the exception — it rewrites sshd config, so I did not exercise it on a live box. It wants a test where a lockout doesn't matter.Notes
post-commithook frominstall-hooks.shwasn't installed in this clone, soVersion.phpis untouched — the release commit can own that.TiCore/*.php,src/*.phpandthemes/default/*.phpstill have CRLF committed while.gitattributesasks for LF, so they show as modified on a fresh clone. Unrelated to this work and a big diff, so I left it. Worth agit add --renormalize .on its own commit.