Allow HTTP_X_FORWARDED_FOR at server level instead of declaring it per-application
The stage 5 smoke test failure was a locked config section, but not one of the two the installer unlocks. A diagnostic collected from the server returned: HTTP 500.52 - URL Rewrite Module Error Module RewriteModule, Handler httpplatformhandler Error Code 0x80070021 Config Error: This configuration section cannot be used at this path. Config File: \\?\C:\shopdb-flask\web.config handlers and httpPlatform were both overrideMode Allow and locked false, so the unlock had worked. The section at fault was a third one, system.webServer/rewrite/allowedServerVariables, which ships overrideModeDefault="Deny". web.config declared <allowedServerVariables> locally for the X-Forwarded-For rule, and IIS rejects that declaration outright, failing the entire configuration before httpPlatformHandler ran. python was therefore never launched and C:\shopdb-flask\logs stayed empty, which reads as a dead application or a permissions fault and is neither. Unlocking the section would let every site on the machine declare arbitrary server variables. The installer now adds the single variable to the server-level allow list, checking first because a duplicate add is an error, and web.config no longer declares it. The rewrite rule is unchanged. Verified by applying the installer's own uncommenting to the template and parsing the result: one rewrite element, no allowedServerVariables, the rule still setting HTTP_X_FORWARDED_FOR from REMOTE_ADDR. shopdb-diagnose.py checked only the two sections the installer unlocks, so it could not have named this one; the IIS error page did. It now reports the lock state of the rewrite sections as well.
This commit is contained in:
@@ -1915,6 +1915,39 @@ If not, re-run matching how the application is published today: pass
|
||||
} finally { $ErrorActionPreference = $prevEap }
|
||||
}
|
||||
|
||||
# URL Rewrite: a rule may only set a server variable that is ALLOWED, and
|
||||
# system.webServer/rewrite/allowedServerVariables ships with
|
||||
# overrideModeDefault="Deny". An <allowedServerVariables> block in the app's
|
||||
# own web.config is therefore refused outright - IIS answered 500.52 with
|
||||
# 0x80070021, "this configuration section cannot be used at this path",
|
||||
# before it ever reached httpPlatformHandler. python was never launched, the
|
||||
# stdout log stayed empty, and the stage 5 smoke test reported it as a dead
|
||||
# application when the config had been rejected wholesale.
|
||||
#
|
||||
# Allow the ONE variable at server level rather than unlocking the section.
|
||||
# Unlocking would let every site on this machine declare arbitrary server
|
||||
# variables; this grants exactly HTTP_X_FORWARDED_FOR.
|
||||
if (($ClientIpSource -eq 'direct') -and (-not $WhatIfOnly)) {
|
||||
$varName = 'HTTP_X_FORWARDED_FOR'
|
||||
$section = 'system.webServer/rewrite/allowedServerVariables'
|
||||
$prevEap = $ErrorActionPreference
|
||||
$ErrorActionPreference = 'Continue'
|
||||
try {
|
||||
# Adding a duplicate entry is an error, so look before writing.
|
||||
$current = (& $appcmd list config /section:$section 2>&1 | Out-String)
|
||||
if ($current -match [regex]::Escape($varName)) {
|
||||
Write-Log "$varName is already allowed for URL Rewrite" 'OK'
|
||||
} else {
|
||||
Write-Log "allowing $varName for URL Rewrite (server level)"
|
||||
& $appcmd set config /section:$section "/+[name='$varName']" /commit:apphost 2>&1 |
|
||||
ForEach-Object { Write-Log " $_" }
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Log " could not allow $varName - IIS will return 500.52 and the app will not start" 'WARN'
|
||||
}
|
||||
}
|
||||
} finally { $ErrorActionPreference = $prevEap }
|
||||
}
|
||||
|
||||
# Stage 2 stops the pool on an upgrade so its files can be replaced. Nothing
|
||||
# else starts it again, so the smoke test would fail against a stopped site
|
||||
# and report it as a broken install.
|
||||
|
||||
@@ -257,7 +257,16 @@ def main():
|
||||
report.block('modules: httpPlatformHandler present?',
|
||||
run([appcmd, 'list', 'modules']))
|
||||
# overrideMode tells us whether the unlock actually took effect.
|
||||
for section in ('system.webServer/handlers', 'system.webServer/httpPlatform'):
|
||||
#
|
||||
# allowedServerVariables is in this list because it caused a 500.52 that
|
||||
# the first two sections could not explain: it is Deny by default, so an
|
||||
# <allowedServerVariables> block in the app's web.config is rejected
|
||||
# before httpPlatformHandler runs. Checking only the sections we unlock
|
||||
# would have missed the one we do not.
|
||||
for section in ('system.webServer/handlers',
|
||||
'system.webServer/httpPlatform',
|
||||
'system.webServer/rewrite/allowedServerVariables',
|
||||
'system.webServer/rewrite/rules'):
|
||||
report.block('lock state of %s' % section,
|
||||
run([appcmd, 'list', 'config', '/section:%s' % section,
|
||||
'/text:*']))
|
||||
|
||||
@@ -67,15 +67,28 @@
|
||||
It ships DISABLED because it needs the URL Rewrite module; enabled without
|
||||
it, IIS returns HTTP 500.19 ("configuration section not well-formed").
|
||||
|
||||
There is deliberately NO <allowedServerVariables> block below. Setting a
|
||||
server variable requires that variable to be allowed, but the section
|
||||
system.webServer/rewrite/allowedServerVariables ships with
|
||||
overrideModeDefault="Deny", so declaring it in an application's own
|
||||
web.config is refused outright: IIS answered 500.52 with error 0x80070021,
|
||||
"this configuration section cannot be used at this path", BEFORE it ever
|
||||
reached httpPlatformHandler - so python was never launched and the stdout
|
||||
log stayed empty, which looks like an application fault and is not one.
|
||||
|
||||
The installer instead allows the single variable at server level, which
|
||||
grants exactly HTTP_X_FORWARDED_FOR rather than unlocking the section and
|
||||
letting every site on the machine declare arbitrary server variables.
|
||||
|
||||
The installer handles both: -ClientIpSource direct installs URL Rewrite
|
||||
from the bundle and enables this; -ClientIpSource proxy leaves it alone.
|
||||
By hand: install URL Rewrite, then delete the two marker lines below.
|
||||
from the bundle, allows the variable, and enables this; -ClientIpSource
|
||||
proxy leaves it alone. By hand: install URL Rewrite, run
|
||||
appcmd set config /section:system.webServer/rewrite/allowedServerVariables ^
|
||||
/+"[name='HTTP_X_FORWARDED_FOR']" /commit:apphost
|
||||
then delete the two marker lines below.
|
||||
-->
|
||||
<!-- SHOPDB-CLIENTIP-BEGIN
|
||||
<rewrite>
|
||||
<allowedServerVariables>
|
||||
<add name="HTTP_X_FORWARDED_FOR" />
|
||||
</allowedServerVariables>
|
||||
<rules>
|
||||
<rule name="Set X-Forwarded-For" stopProcessing="false">
|
||||
<match url=".*" />
|
||||
|
||||
Reference in New Issue
Block a user