Add support for PROXY protocol
This commit is contained in:
parent
a5ffeae757
commit
daac8d85e2
@ -3,15 +3,15 @@ package net.md_5.bungee.api.config;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import lombok.AccessLevel;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing the configuration of a server listener. Used for allowing
|
* Class representing the configuration of a server listener. Used for allowing
|
||||||
* multiple listeners on different ports.
|
* multiple listeners on different ports.
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
public class ListenerInfo
|
public class ListenerInfo
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -67,6 +67,16 @@ public class ListenerInfo
|
|||||||
* Whether to enable udp query.
|
* Whether to enable udp query.
|
||||||
*/
|
*/
|
||||||
private final boolean queryEnabled;
|
private final boolean queryEnabled;
|
||||||
|
/**
|
||||||
|
* Whether to support HAProxy PROXY protocol.
|
||||||
|
*/
|
||||||
|
private final boolean proxyProtocol;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public ListenerInfo(InetSocketAddress host, String motd, int maxPlayers, int tabListSize, List<String> serverPriority, boolean forceDefault, Map<String, String> forcedHosts, String tabListType, boolean setLocalAddress, boolean pingPassthrough, int queryPort, boolean queryEnabled)
|
||||||
|
{
|
||||||
|
this( host, motd, maxPlayers, tabListSize, serverPriority, forceDefault, forcedHosts, tabListType, setLocalAddress, pingPassthrough, queryPort, queryEnabled, false );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the highest priority server to join.
|
* Gets the highest priority server to join.
|
||||||
|
@ -29,6 +29,12 @@
|
|||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-codec-haproxy</artifactId>
|
||||||
|
<version>${netty.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.netty</groupId>
|
<groupId>io.netty</groupId>
|
||||||
<artifactId>netty-codec-http</artifactId>
|
<artifactId>netty-codec-http</artifactId>
|
||||||
|
@ -296,6 +296,11 @@ public class BungeeCord extends ProxyServer
|
|||||||
{
|
{
|
||||||
for ( final ListenerInfo info : config.getListeners() )
|
for ( final ListenerInfo info : config.getListeners() )
|
||||||
{
|
{
|
||||||
|
if ( info.isProxyProtocol() )
|
||||||
|
{
|
||||||
|
getLogger().log( Level.WARNING, "Using PROXY protocol for listener {0}, please ensure this listener is adequately firewalled.", info.getHost() );
|
||||||
|
}
|
||||||
|
|
||||||
ChannelFutureListener listener = new ChannelFutureListener()
|
ChannelFutureListener listener = new ChannelFutureListener()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
|
@ -452,7 +452,7 @@ public final class UserConnection implements ProxiedPlayer
|
|||||||
@Override
|
@Override
|
||||||
public InetSocketAddress getAddress()
|
public InetSocketAddress getAddress()
|
||||||
{
|
{
|
||||||
return (InetSocketAddress) ch.getHandle().remoteAddress();
|
return ch.getRemoteAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -247,6 +247,7 @@ public class YamlConfig implements ConfigurationAdapter
|
|||||||
boolean query = get( "query_enabled", false, val );
|
boolean query = get( "query_enabled", false, val );
|
||||||
int queryPort = get( "query_port", 25577, val );
|
int queryPort = get( "query_port", 25577, val );
|
||||||
|
|
||||||
|
boolean proxyProtocol = get( "proxy_protocol", false, val );
|
||||||
List<String> serverPriority = new ArrayList<>( get( "priorities", Collections.EMPTY_LIST, val ) );
|
List<String> serverPriority = new ArrayList<>( get( "priorities", Collections.EMPTY_LIST, val ) );
|
||||||
|
|
||||||
// Default server list migration
|
// Default server list migration
|
||||||
@ -271,7 +272,7 @@ public class YamlConfig implements ConfigurationAdapter
|
|||||||
}
|
}
|
||||||
set( "priorities", serverPriority, val );
|
set( "priorities", serverPriority, val );
|
||||||
|
|
||||||
ListenerInfo info = new ListenerInfo( address, motd, maxPlayers, tabListSize, serverPriority, forceDefault, forced, value.toString(), setLocalAddress, pingPassthrough, queryPort, query );
|
ListenerInfo info = new ListenerInfo( address, motd, maxPlayers, tabListSize, serverPriority, forceDefault, forced, value.toString(), setLocalAddress, pingPassthrough, queryPort, query, proxyProtocol );
|
||||||
ret.add( info );
|
ret.add( info );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,7 +574,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
|
|||||||
@Override
|
@Override
|
||||||
public InetSocketAddress getAddress()
|
public InetSocketAddress getAddress()
|
||||||
{
|
{
|
||||||
return (InetSocketAddress) ch.getHandle().remoteAddress();
|
return ch.getRemoteAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -5,8 +5,10 @@ import io.netty.channel.Channel;
|
|||||||
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelHandler;
|
import io.netty.channel.ChannelHandler;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import net.md_5.bungee.compress.PacketCompressor;
|
import net.md_5.bungee.compress.PacketCompressor;
|
||||||
import net.md_5.bungee.compress.PacketDecompressor;
|
import net.md_5.bungee.compress.PacketDecompressor;
|
||||||
import net.md_5.bungee.protocol.MinecraftDecoder;
|
import net.md_5.bungee.protocol.MinecraftDecoder;
|
||||||
@ -20,6 +22,9 @@ public class ChannelWrapper
|
|||||||
|
|
||||||
private final Channel ch;
|
private final Channel ch;
|
||||||
@Getter
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private InetSocketAddress remoteAddress;
|
||||||
|
@Getter
|
||||||
private volatile boolean closed;
|
private volatile boolean closed;
|
||||||
@Getter
|
@Getter
|
||||||
private volatile boolean closing;
|
private volatile boolean closing;
|
||||||
@ -27,6 +32,7 @@ public class ChannelWrapper
|
|||||||
public ChannelWrapper(ChannelHandlerContext ctx)
|
public ChannelWrapper(ChannelHandlerContext ctx)
|
||||||
{
|
{
|
||||||
this.ch = ctx.channel();
|
this.ch = ctx.channel();
|
||||||
|
this.remoteAddress = (InetSocketAddress) this.ch.remoteAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProtocol(Protocol protocol)
|
public void setProtocol(Protocol protocol)
|
||||||
|
@ -4,8 +4,10 @@ import com.google.common.base.Preconditions;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
import io.netty.handler.codec.DecoderException;
|
import io.netty.handler.codec.DecoderException;
|
||||||
|
import io.netty.handler.codec.haproxy.HAProxyMessage;
|
||||||
import io.netty.handler.timeout.ReadTimeoutException;
|
import io.netty.handler.timeout.ReadTimeoutException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
import net.md_5.bungee.connection.CancelSendSignal;
|
import net.md_5.bungee.connection.CancelSendSignal;
|
||||||
@ -65,6 +67,20 @@ public class HandlerBoss extends ChannelInboundHandlerAdapter
|
|||||||
@Override
|
@Override
|
||||||
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
|
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
|
||||||
{
|
{
|
||||||
|
if ( msg instanceof HAProxyMessage )
|
||||||
|
{
|
||||||
|
HAProxyMessage proxy = (HAProxyMessage) msg;
|
||||||
|
InetSocketAddress newAddress = new InetSocketAddress( proxy.sourceAddress(), proxy.sourcePort() );
|
||||||
|
|
||||||
|
ProxyServer.getInstance().getLogger().log( Level.FINE, "Set remote address via PROXY {0} -> {1}", new Object[]
|
||||||
|
{
|
||||||
|
channel.getRemoteAddress(), newAddress
|
||||||
|
} );
|
||||||
|
|
||||||
|
channel.setRemoteAddress( newAddress );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( handler != null )
|
if ( handler != null )
|
||||||
{
|
{
|
||||||
PacketWrapper packet = (PacketWrapper) msg;
|
PacketWrapper packet = (PacketWrapper) msg;
|
||||||
|
@ -16,6 +16,7 @@ import io.netty.channel.nio.NioEventLoopGroup;
|
|||||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
|
import io.netty.handler.codec.haproxy.HAProxyMessageDecoder;
|
||||||
import io.netty.handler.timeout.ReadTimeoutHandler;
|
import io.netty.handler.timeout.ReadTimeoutHandler;
|
||||||
import io.netty.util.AttributeKey;
|
import io.netty.util.AttributeKey;
|
||||||
import io.netty.util.internal.PlatformDependent;
|
import io.netty.util.internal.PlatformDependent;
|
||||||
@ -48,12 +49,19 @@ public class PipelineUtils
|
|||||||
@Override
|
@Override
|
||||||
protected void initChannel(Channel ch) throws Exception
|
protected void initChannel(Channel ch) throws Exception
|
||||||
{
|
{
|
||||||
|
ListenerInfo listener = ch.attr( LISTENER ).get();
|
||||||
|
|
||||||
BASE.initChannel( ch );
|
BASE.initChannel( ch );
|
||||||
ch.pipeline().addBefore( FRAME_DECODER, LEGACY_DECODER, new LegacyDecoder() );
|
ch.pipeline().addBefore( FRAME_DECODER, LEGACY_DECODER, new LegacyDecoder() );
|
||||||
ch.pipeline().addAfter( FRAME_DECODER, PACKET_DECODER, new MinecraftDecoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) );
|
ch.pipeline().addAfter( FRAME_DECODER, PACKET_DECODER, new MinecraftDecoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) );
|
||||||
ch.pipeline().addAfter( FRAME_PREPENDER, PACKET_ENCODER, new MinecraftEncoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) );
|
ch.pipeline().addAfter( FRAME_PREPENDER, PACKET_ENCODER, new MinecraftEncoder( Protocol.HANDSHAKE, true, ProxyServer.getInstance().getProtocolVersion() ) );
|
||||||
ch.pipeline().addBefore( FRAME_PREPENDER, LEGACY_KICKER, new KickStringWriter() );
|
ch.pipeline().addBefore( FRAME_PREPENDER, LEGACY_KICKER, new KickStringWriter() );
|
||||||
ch.pipeline().get( HandlerBoss.class ).setHandler( new InitialHandler( BungeeCord.getInstance(), ch.attr( LISTENER ).get() ) );
|
ch.pipeline().get( HandlerBoss.class ).setHandler( new InitialHandler( BungeeCord.getInstance(), listener ) );
|
||||||
|
|
||||||
|
if ( listener.isProxyProtocol() )
|
||||||
|
{
|
||||||
|
ch.pipeline().addFirst( new HAProxyMessageDecoder() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
public static final Base BASE = new Base();
|
public static final Base BASE = new Base();
|
||||||
|
Loading…
Reference in New Issue
Block a user