Skip to content

Instantly share code, notes, and snippets.

@codingtony
Last active April 10, 2017 13:36
Show Gist options
  • Save codingtony/a8684c9ffa08ad56899f94d3b6c2a040 to your computer and use it in GitHub Desktop.
Save codingtony/a8684c9ffa08ad56899f94d3b6c2a040 to your computer and use it in GitHub Desktop.
ServerProxyAcceptor implementation for Mina SSHD. Tested with sshd-core 1.3.0 & 1.4.0 - https://issues.apache.org/jira/browse/SSHD-656
/**
*
* A working prototype to support PROXY protocol as described
* @see <a href="http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt">HAProxy Documentation</a>
*
* Feel free to improve and integrate to the core library, just include my name as contributor :
* Tony Bussieres - [email protected]
*
*/
public class ProxyProtocolAcceptor implements ServerProxyAcceptor {
private static final byte[] PROXY_HEADER = new byte[] { 0x50, 0x52, 0x4F, 0x58, 0x59, 0x20 };
private Logger logger = LoggerFactory.getLogger(getClass());
@Override
public boolean acceptServerProxyMetadata(ServerSession session, Buffer buffer) throws Exception {
int mark = buffer.rpos();
if (buffer.available() >= 6) {
byte[] proxyHeader = new byte[6];
buffer.getRawBytes(proxyHeader);
buffer.rpos(mark); // Rewind the buffer
if (Arrays.equals(PROXY_HEADER, proxyHeader)) {
logger.debug("PROXY protocol detected");
// 108 bytes is the largest buffer needed for the PROXY protocol
StringBuilder proxyPayload = new StringBuilder(108);
byte n = 0x0;
// read until we get 0x0d.
while ((n = buffer.getByte()) != 0x0d) {
proxyPayload.append((char) n);
}
buffer.getByte(); // 0x0a
logger.debug(proxyPayload.toString());
String[] proxyFields = proxyPayload.toString().split(" ", -1);
String proxyProtocolHeader = proxyFields[0];
String protocol = proxyFields[1];
if ("TCP4".equals(protocol) || "TCP6".equals(protocol)) {
String layer3SrcAddress = proxyFields[2];
String layer3DstAddress = proxyFields[3];
String layer3SrcPort = proxyFields[4];
String layer3DstPort = proxyFields[5];
logger.debug("Header: {}, protocol: {}, src: {}, dst: {}, srcPort: {}, dstPort: {}", proxyProtocolHeader, protocol,
layer3SrcAddress, layer3DstAddress, layer3SrcPort, layer3DstPort);
if (session instanceof AbstractServerSession) {
// Set the client address in the session from the proxy payload
((AbstractServerSession) session)
.setClientAddress(new InetSocketAddress(layer3SrcAddress, Integer.valueOf(layer3SrcPort)));
}
} else {
logger.warn("Proxy Protocol not supported : {}, But still continuing to the login", protocol);
}
}
return true;
} else {
logger.error("Problem with setting up proxy protocol acceptor");
return false;
}
}
}
@codingtony
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment