feat(installer): bundle URL Rewrite, ask where client IPs come from, verify installs
IIS does not set X-Forwarded-For on its own and HttpPlatformHandler connects from loopback, so without a rewrite rule every client reads as 127.0.0.1. The GE-Enforce IP allowlist, the dashboard visitor-location lookup and per-host login rate limiting all stop working, silently. The rule needed URL Rewrite, which the installer told operators to download - from an air-gapped server. URL Rewrite now ships in the bundle, and the wizard asks which case applies, because the two answers are mutually exclusive. Directly exposed: install it and set X-Forwarded-For from REMOTE_ADDR, which is what stops a client spoofing its own. Behind a proxy: leave the rule off, since REMOTE_ADDR is the proxy and applying it would discard the real client IP. The rule is enabled by deleting two explicit marker lines rather than by a regex over the surrounding comment, so editing that prose cannot silently disable it. An existing web.config is no longer overwritten. It is the one file on a server that legitimately carries hand-edits, and replacing it reverted them without a word - on a server where the X-Forwarded-For rule had been enabled by hand, that alone would have turned the GE-Enforce IP allowlist off. The installer reports what it found instead. pip now runs with --require-hashes and --only-binary=:all:. Hash-checking is requested explicitly rather than inferred from the lockfile, so shipping an unhashed requirements.txt fails loudly instead of quietly dropping the check. shopdb-admin.ps1 gains a verify command: which bundle this server was installed from, and whether the installed packages still match what shipped. The .iss states its compiler floor. WizardStyle uses the built-in windows11 custom style, which needs Inno Setup 6.6.0; older compilers now fail with that sentence rather than 'WizardStyle is invalid'.
This commit is contained in:
@@ -9,6 +9,14 @@
|
||||
; that nobody tests. This file only collects operator input, runs the stages in
|
||||
; order, and reports which one failed.
|
||||
|
||||
; Inno Setup 6.6.0 is the floor: WizardStyle below uses the built-in 'windows11'
|
||||
; custom style, which 6.5 and earlier reject. Stated here so a build box on an
|
||||
; older compiler fails with this sentence rather than with a bare
|
||||
; "Value of [Setup] section directive WizardStyle is invalid".
|
||||
#if VER < EncodeVer(6,6,0)
|
||||
#error This script needs Inno Setup 6.6.0 or newer (WizardStyle=... windows11). Download it from https://jrsoftware.org/isdl.php
|
||||
#endif
|
||||
|
||||
#define AppName "ShopDB-Flask"
|
||||
; Pre-release. This has not shipped, so it is 0.x by definition. It becomes
|
||||
; 1.0.0 when a real site installs from it successfully - not before.
|
||||
@@ -173,6 +181,7 @@ var
|
||||
DbPageReady: Boolean;
|
||||
DeployPage: TInputOptionWizardPage;
|
||||
DeployPageReady: Boolean;
|
||||
ClientIpPage: TInputOptionWizardPage;
|
||||
// Set from the streamed stage output so a failure can name its cause. Without
|
||||
// this the wizard could only report "exit 1", which points at nothing.
|
||||
FailCause: String;
|
||||
@@ -388,6 +397,35 @@ begin
|
||||
else
|
||||
SitePage.Values[0] := GetComputerNameString;
|
||||
SitePage.Values[1] := '8090';
|
||||
|
||||
// Where the real client IP comes from. Not cosmetic: IIS sends no
|
||||
// X-Forwarded-For of its own, so with neither option applied every request
|
||||
// reads as 127.0.0.1 and the GE-Enforce IP allowlist, the dashboard's
|
||||
// visitor-location lookup and per-host login rate limiting all fail silently.
|
||||
//
|
||||
// The two answers are mutually exclusive, and picking the wrong one is worse
|
||||
// than picking neither: the rule OVERWRITES the header with REMOTE_ADDR, which
|
||||
// is exactly right when IIS faces clients (it defeats spoofing) and exactly
|
||||
// wrong behind a proxy (REMOTE_ADDR is the proxy, so the real client IP is
|
||||
// discarded). Hence a question rather than a default.
|
||||
ClientIpPage := CreateInputOptionPage(SitePage.ID,
|
||||
'Client addresses', 'How does this server see who is connecting?',
|
||||
'ShopDB records the address of every request, and some features decide what '
|
||||
+ 'to show based on it. Choose whichever describes this server.',
|
||||
True, False);
|
||||
ClientIpPage.Add('Clients connect to this server directly (installs URL Rewrite)');
|
||||
ClientIpPage.Add('A proxy or load balancer sits in front of this server');
|
||||
ClientIpPage.SelectedValueIndex := 0;
|
||||
end;
|
||||
|
||||
// 'direct' installs URL Rewrite from the bundle and enables the X-Forwarded-For
|
||||
// rule; 'proxy' leaves both alone because the proxy already sets the header.
|
||||
function ClientIpSourceArg: String;
|
||||
begin
|
||||
if ClientIpPage.SelectedValueIndex = 1 then
|
||||
Result := 'proxy'
|
||||
else
|
||||
Result := 'direct';
|
||||
end;
|
||||
|
||||
// Full path to the 64-bit PowerShell.
|
||||
@@ -900,6 +938,7 @@ begin
|
||||
' -SiteHost "' + SitePage.Values[0] + '"' +
|
||||
' -SitePort ' + SitePage.Values[1] +
|
||||
' -OnFailure never' +
|
||||
' -ClientIpSource ' + ClientIpSourceArg +
|
||||
' -SitePlugins "' + SelectedPlugins + '"';
|
||||
|
||||
// Subpath deployment: an IIS Application under the existing site instead of a
|
||||
|
||||
Reference in New Issue
Block a user