feat(velocity): let 1.8.x players through the modern-forwarding proxy
Felis pins player-info-forwarding-mode = "modern", and Velocity's HandshakeSessionHandler#handleLogin refuses anything below 1.13 outright: it reads handshake.getProtocolVersion() and disconnects with velocity.error.modern-forwarding-needs-new-client before the backend is ever contacted. A player pinned to 1.8.9 never reaches the login gate, never sees the onboarding link, and gets an error string that tells them to upgrade their client. install_via_plugins now stages ViaVersion, ViaBackwards and ViaRewind into /opt/felis/velocity/plugins alongside felis-velocity.jar. Nothing else moves: same forwarding mode, same secret, no backend patched and no backend downgraded. The 1.13 floor turns out to be a property of the unassisted proxy pipeline rather than of the forwarding protocol, so lifting it costs three jars and no source change. This was measured, not assumed. Felis-Legacy's FL-007 probe stands a protocol-47 client in front of a stock Paper 1.21.11 backend behind a modern-forwarding proxy and watches it join. The proof is the join itself rather than the log line: that backend runs velocity.enabled with a shared secret, and Paper in that state rejects any login not carrying forwarding data signed with a matching HMAC. The control cell without Via is rejected before the backend is contacted, so Via is the only difference. A second cell re-runs the same join with force-key-authentication = true, the way Felis sets it, because a result that only holds under a config Felis does not run is not a result about Felis; the 1.19+ signed chat key a protocol-47 client cannot produce is never demanded, and it cannot be, since the pre-1.19 wire format has no player-key field to decode. The jars are pinned by sha256 and not by a moving tag. They sit in front of every packet on the proxy and they are the exact bytes FL-007 measured; "latest" would quietly make this an unmeasured configuration. The digests come from the GitHub releases FL-006 locked, which is deliberate — Hangar's VELOCITY/download endpoint serves different bytes for the same version numbers, so an installer that only checked for HTTP 200 would ship artifacts nothing has tested. A version bump means a digest bump here. Two limits are worth writing down. Only protocol 47 was measured; the rest of Via's documented 1.7-1.12 range is inference from that one point. And the probe runs online-mode = false because it has no Mojang account, so Felis's online-mode = true is untested — the untested part is the Mojang auth handshake specifically, which puts the residual in Via's own login handling rather than in forwarding or in the hasJoined multiplexer, whose request is protocol-independent. Checks: a fresh install lands all three jars at the pinned digests and sizes with no temp files left behind; a re-run downloads nothing; a tampered jar is restored to the pinned bytes; and a deliberately wrong digest aborts without installing anything. Existing installs pick this up by re-running bootstrap, which re-enters install_velocity because bootstrap.done is written but never read as an early exit.
This commit is contained in:
1 file changed
+54
@@ -1313,6 +1313,59 @@ build_velocity_plugin() {
|
|||||||
atomic_install_file "${jars[0]}" "${VELOCITY_DIR}/plugins/felis-velocity.jar" 0644 root root
|
atomic_install_file "${jars[0]}" "${VELOCITY_DIR}/plugins/felis-velocity.jar" 0644 root root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# install_via_plugins stages ViaVersion + ViaBackwards + ViaRewind so players on clients
|
||||||
|
# older than the proxy can still join.
|
||||||
|
#
|
||||||
|
# Modern forwarding nominally refuses anything below 1.13: HandshakeSessionHandler#handleLogin
|
||||||
|
# reads the handshake protocol version and disconnects with
|
||||||
|
# velocity.error.modern-forwarding-needs-new-client. That gate stops firing once Via is
|
||||||
|
# present — it logs "Replacing channel initializers" during startup, so the version reaching
|
||||||
|
# the check is plausibly already the rewritten one. The 1.13 floor is a property of the
|
||||||
|
# UNASSISTED proxy pipeline, not of the forwarding protocol, so nothing here changes
|
||||||
|
# player-info-forwarding-mode and no backend is patched or downgraded.
|
||||||
|
#
|
||||||
|
# Measured end to end rather than assumed (Felis-Legacy FL-007, cell modern-via121): a
|
||||||
|
# protocol-47 client joined a stock Paper 1.21.11 backend through a modern-forwarding proxy.
|
||||||
|
# The proof is the join itself, not the log line — that backend ran velocity.enabled=true with
|
||||||
|
# a shared secret, and Paper in that state rejects any login not carrying forwarding data
|
||||||
|
# signed with a matching HMAC. Only protocol 47 was measured; the rest of Via's 1.7-1.12 range
|
||||||
|
# is its own documented support.
|
||||||
|
#
|
||||||
|
# Pinned by hash and not by "latest" on purpose. These three jars sit in front of every packet
|
||||||
|
# on the proxy, and they are the exact bytes FL-007 measured — a moving tag would quietly make
|
||||||
|
# this an unmeasured configuration. Bumping a version means bumping its checksum here.
|
||||||
|
install_via_plugins() {
|
||||||
|
prepare_velocity_layout
|
||||||
|
local name version want target url tmp have
|
||||||
|
while read -r name version want; do
|
||||||
|
[ -n "$name" ] || continue
|
||||||
|
target="${VELOCITY_DIR}/plugins/${name}.jar"
|
||||||
|
# Hash stdin, never the path: sha256sum escapes its output line when the filename
|
||||||
|
# carries a backslash or a newline, and a leading "\" on the digest silently fails
|
||||||
|
# every comparison below.
|
||||||
|
have=""
|
||||||
|
[ -f "$target" ] && have="$(sha256sum <"$target" | cut -d' ' -f1)"
|
||||||
|
if [ "$have" = "$want" ]; then
|
||||||
|
ok "${name} ${version} already staged"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
url="https://github.com/ViaVersion/${name}/releases/download/${version}/${name}-${version}.jar"
|
||||||
|
log "downloading ${name} ${version}"
|
||||||
|
tmp="$(mktemp "${VELOCITY_DIR}/.${name}.jar.XXXXXX")"
|
||||||
|
remember_temp "$tmp"
|
||||||
|
curl -fsSL "$url" -o "$tmp" || die "failed to download ${name} ${version}: ${url}"
|
||||||
|
have="$(sha256sum <"$tmp" | cut -d' ' -f1)"
|
||||||
|
[ "$have" = "$want" ] \
|
||||||
|
|| die "${name} ${version} checksum mismatch: got ${have}, expected ${want}"
|
||||||
|
atomic_install_file "$tmp" "$target" 0644 root root
|
||||||
|
done <<'EOF'
|
||||||
|
ViaVersion 5.11.0 18d19e90fc9467d68128c076630ae8700449c901402a3ef421837ce006bc8cae
|
||||||
|
ViaBackwards 5.11.0 b21983d561e3f92df257683f0133ab6c68ec68175e8acfd82c6231723bf83587
|
||||||
|
ViaRewind 4.1.2 88f413eb1a5c302cf0fdd32bf11051bbb65485cbf6012921dbcfedab3772f341
|
||||||
|
EOF
|
||||||
|
ok "Via staged; clients from 1.8 up can join under modern forwarding"
|
||||||
|
}
|
||||||
|
|
||||||
install_jre() {
|
install_jre() {
|
||||||
local arch url
|
local arch url
|
||||||
if [ -x "${JRE_DIR}/bin/java" ]; then
|
if [ -x "${JRE_DIR}/bin/java" ]; then
|
||||||
@@ -1352,6 +1405,7 @@ install_velocity() {
|
|||||||
curl -fsSL "$url" -o "$tmp" || die "failed to download Velocity: ${url}"
|
curl -fsSL "$url" -o "$tmp" || die "failed to download Velocity: ${url}"
|
||||||
atomic_install_file "$tmp" "${VELOCITY_DIR}/velocity.jar" 0644 root root
|
atomic_install_file "$tmp" "${VELOCITY_DIR}/velocity.jar" 0644 root root
|
||||||
|
|
||||||
|
install_via_plugins
|
||||||
write_velocity_config
|
write_velocity_config
|
||||||
install_velocity_service
|
install_velocity_service
|
||||||
configure_velocity_firewall
|
configure_velocity_firewall
|
||||||
|
|||||||
Reference in new issue
Block a user