diff options
| author | Michael Peter Christen <mc@yacy.net> | 2026-07-12 17:16:24 +0200 |
|---|---|---|
| committer | Michael Peter Christen <mc@yacy.net> | 2026-07-12 17:16:24 +0200 |
| commit | ece7985d9435843989c36395c6dd2db2f0b9e933 (patch) | |
| tree | b54c2eb1f273a4c716470b5aa90ab67b83b35a4b /source/net | |
| parent | 92e0b111a0ce98964e4de3600d1a81643313ed7e (diff) | |
proper IP recognition using header X-Real-IP when YaCy is behind a
reverse proxy
Diffstat (limited to 'source/net')
| -rw-r--r-- | source/net/yacy/http/Jetty12HttpServer.java | 26 | ||||
| -rw-r--r-- | source/net/yacy/search/SwitchboardConstants.java | 4 |
2 files changed, 27 insertions, 3 deletions
diff --git a/source/net/yacy/http/Jetty12HttpServer.java b/source/net/yacy/http/Jetty12HttpServer.java index f38a1a8d0..cc72eab49 100644 --- a/source/net/yacy/http/Jetty12HttpServer.java +++ b/source/net/yacy/http/Jetty12HttpServer.java @@ -65,6 +65,8 @@ import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.security.Credential; import org.eclipse.jetty.util.ssl.SslContextFactory; +import com.google.common.net.InetAddresses; + import net.yacy.cora.protocol.ConnectionInfo; import net.yacy.cora.protocol.RequestHeader; import net.yacy.cora.util.ConcurrentLog; @@ -490,8 +492,11 @@ public class Jetty12HttpServer implements YaCyHttpServer { protected RoleInfo prepareConstraintInfo(final String pathInContext, final org.eclipse.jetty.ee8.nested.Request request) { final Switchboard switchboard = Switchboard.getSwitchboard(); - final String remoteIp = request.getRemoteAddr(); - serverAccessTracker.track(remoteIp, pathInContext); + final String socketRemoteIp = request.getRemoteAddr(); + final String trackingRemoteIp = resolveTrackingClientIp(request, + switchboard.getConfig(SwitchboardConstants.SERVER_REVERSE_PROXY_TRUSTED, + SwitchboardConstants.SERVER_REVERSE_PROXY_TRUSTED_DEFAULT)); + serverAccessTracker.track(trackingRemoteIp, pathInContext); final AdminSecurity.AccessPolicy policy = new AdminSecurity.AccessPolicy( switchboard.getConfigBool(SwitchboardConstants.ADMIN_ACCOUNT_All_PAGES, false), switchboard.isRobinsonMode() && !switchboard.isPublicRobinson(), @@ -499,7 +504,7 @@ public class Jetty12HttpServer implements YaCyHttpServer { switchboard.getConfigBool(SwitchboardConstants.ADMIN_ACCOUNT_FOR_LOCALHOST, false), switchboard.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_USER_NAME, "admin"), switchboard.getConfig(SwitchboardConstants.ADMIN_ACCOUNT_B64MD5, "")); - final AdminSecurity.AccessPolicy.Decision decision = policy.decide(pathInContext, remoteIp, + final AdminSecurity.AccessPolicy.Decision decision = policy.decide(pathInContext, socketRemoteIp, request.getHeader(RequestHeader.REFERER), request.getHeader(RequestHeader.AUTHORIZATION)); if (decision == AdminSecurity.AccessPolicy.Decision.PUBLIC) { @@ -513,6 +518,21 @@ public class Jetty12HttpServer implements YaCyHttpServer { roleInfo.addRole(SwitchboardConstants.ADMIN_ACCOUNT_ROLE); return roleInfo; } + + /** Resolve the client address for display and tracking, never for access control. */ + static String resolveTrackingClientIp(final HttpServletRequest request, + final String trustedProxyPatterns) { + final String socketRemoteIp = request.getRemoteAddr(); + if (!ProxyAccessPolicy.isClientAllowed(trustedProxyPatterns, socketRemoteIp)) { + return socketRemoteIp; + } + final String forwardedRemoteIp = request.getHeader(RequestHeader.X_Real_IP); + if (forwardedRemoteIp == null) { + return socketRemoteIp; + } + final String candidate = forwardedRemoteIp.trim(); + return InetAddresses.isInetAddress(candidate) ? candidate : socketRemoteIp; + } } /** Jetty 12 login-service adapter for YaCy's single built-in administrator. */ diff --git a/source/net/yacy/search/SwitchboardConstants.java b/source/net/yacy/search/SwitchboardConstants.java index 8692c2759..405fbcab8 100644 --- a/source/net/yacy/search/SwitchboardConstants.java +++ b/source/net/yacy/search/SwitchboardConstants.java @@ -66,6 +66,10 @@ public final class SwitchboardConstants { public static final String SERVER_SHUTDOWNPORT = "port.shutdown"; // local port to listen for a shutdown signal (0 <= disabled) public static final String SERVER_STATICIP = "staticIP"; // static IP of http server public static final String SERVER_PUBLICPORT = "publicPort"; + /** Socket peers whose X-Real-IP header may be used for request tracking. */ + public static final String SERVER_REVERSE_PROXY_TRUSTED = "server.reverseProxy.trusted"; + public static final String SERVER_REVERSE_PROXY_TRUSTED_DEFAULT = + "127[.]0[.]0[.]1,0:0:0:0:0:0:0:1,::1"; public static final String PUBLIC_SEARCHPAGE = "publicSearchpage"; |
