tools(re): remove the port-8081 DNAT that breaks FIFA 17's roster TLS
A client-local nat rule redirecting dport 8081 to the plain-HTTP staging UTAS host captures the roster/squad-update TLS connection, which is https://winter15.gosredirector.ea.com:8081/fifa17/fut/rosterupdate.xml. The staging host completes the TCP handshake then closes on the ClientHello, so the client retries and shows "An error occurred downloading the FUT squad update." Proven by capturing on the server while probing from the client: a connection addressed to :8081 arrives as dport 8299, while an :8443 control in the same capture yields 75 packets and a clean handshake. The script deletes only nat rules whose destination port is 8299, then verifies the endpoint presents CN = winter15.gosredirector.ea.com.
This commit is contained in:
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#!/bin/sh
|
||||
# Remove the port-8081 DNAT rule that hijacks FIFA 17's roster/squad-update TLS.
|
||||
#
|
||||
# Why: the FUT squad update is https://winter15.gosredirector.ea.com:8081/fifa17/fut/rosterupdate.xml
|
||||
# (TLS on port 8081). A DNAT rule rewriting dport 8081 -> 8299 sends that TLS
|
||||
# handshake to the plain-HTTP staging UTAS host, which closes the connection.
|
||||
# Proven: a probe to 10.10.0.120:8081 from this box arrives at the server as
|
||||
# dport 8299. Result: "An error occurred downloading the FUT squad update."
|
||||
#
|
||||
# The rule also never redirected UTAS, which lives on :8443, not :8081.
|
||||
#
|
||||
# Read-only until it deletes; deletes only nat rules whose target port is 8299.
|
||||
set -u
|
||||
|
||||
echo "== nat OUTPUT rules mentioning 8081 or 8299 =="
|
||||
iptables -t nat -S OUTPUT 2>/dev/null | grep -E '8081|8299' || echo " (none)"
|
||||
|
||||
echo
|
||||
echo "== deleting DNAT rules that redirect to port 8299 =="
|
||||
removed=0
|
||||
# Delete by spec, repeatedly, until no matching rule remains.
|
||||
while :; do
|
||||
rule=$(iptables -t nat -S OUTPUT 2>/dev/null | grep -m1 -E '\-\-dport 8081 .*8299|to-destination [0-9.]+:8299')
|
||||
[ -z "$rule" ] && break
|
||||
spec=$(printf '%s' "$rule" | sed 's/^-A /-D /')
|
||||
# shellcheck disable=SC2086
|
||||
if iptables -t nat $spec 2>/dev/null; then
|
||||
echo " removed: $rule"
|
||||
removed=$((removed + 1))
|
||||
else
|
||||
echo " FAILED to remove: $rule" >&2
|
||||
break
|
||||
fi
|
||||
done
|
||||
[ "$removed" -eq 0 ] && echo " (no matching rule found)"
|
||||
|
||||
echo
|
||||
echo "== remaining nat OUTPUT rules mentioning 8081 or 8299 =="
|
||||
iptables -t nat -S OUTPUT 2>/dev/null | grep -E '8081|8299' || echo " (none)"
|
||||
|
||||
echo
|
||||
echo "== verifying the roster endpoint now presents the correct certificate =="
|
||||
python3 - <<'PY'
|
||||
import socket, ssl
|
||||
host, port, sni = "10.10.0.120", 8081, "winter15.gosredirector.ea.com"
|
||||
try:
|
||||
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
with socket.create_connection((host, port), 8) as s:
|
||||
with ctx.wrap_socket(s, server_hostname=sni) as t:
|
||||
der = t.getpeercert(True)
|
||||
cn = dict(x[0] for x in t.getpeercert().get("subject", ()))
|
||||
print(f" PASS {host}:{port} sni={sni} {t.version()} der={len(der)}B subject={cn}")
|
||||
except Exception as e:
|
||||
print(f" FAIL {host}:{port} sni={sni} -> {type(e).__name__}: {e}")
|
||||
print(" The roster path is still broken; do not relaunch yet.")
|
||||
PY
|
||||
Reference in New Issue
Block a user