diff --git a/ctrl/sbbs.ini b/ctrl/sbbs.ini
index a211078726d359ce1c57c6214f91214d5571d4be..0a717ce8c7ba306018b27ebcf7424c52b03ca0d7 100644
--- a/ctrl/sbbs.ini
+++ b/ctrl/sbbs.ini
@@ -137,6 +137,7 @@
 ;       NO_RECYCLE
 ;       GET_IDENT
 ;       MUTE
+;       HAPROXY_PROTO
 Options = XTRN_MINIMIZED | ALLOW_RLOGIN | ALLOW_SSH
 
 [Mail]	SMTP/POP3 Mail Server
diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp
index 499f6670ece3a5d1696d75e771e39c045fce78c5..b5db52142dbbfe8ebb1d017499563a3d9b6b4f59 100644
--- a/src/sbbs3/main.cpp
+++ b/src/sbbs3/main.cpp
@@ -4933,6 +4933,9 @@ static void cleanup(int code)
 
 void DLLCALL bbs_thread(void* arg)
 {
+	struct addrinfo *res;
+	unsigned char	hapstr[108];
+
 	char			host_name[256];
 	char*			identity;
 	char*			p;
@@ -4942,7 +4945,7 @@ void DLLCALL bbs_thread(void* arg)
 	union xp_sockaddr	client_addr;
 	socklen_t		client_addr_len;
 	SOCKET			client_socket=INVALID_SOCKET;
-	int				i;
+	int				i,l;
     int				file;
 	int				result;
 	time_t			t;
@@ -5449,7 +5452,132 @@ NO_SSH:
 		}
 		char host_ip[INET6_ADDRSTRLEN];
 
-		inet_addrtop(&client_addr, host_ip, sizeof(host_ip));
+		// Set host_ip from haproxy protocol, if its used
+		// http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
+		if(startup->options&BBS_OPT_HAPROXY_PROTO) {
+			lprintf(LOG_INFO,"%04d Working out client address from HAPROXY PROTO",client_socket);
+			memset(hapstr,'\0',sizeof(hapstr));
+			memset(host_ip,'\0',sizeof(host_ip));
+
+			// Read the first 5 chars to work out what we are dealing with
+			recv(client_socket,hapstr,5,0);
+			lprintf(LOG_DEBUG,"%04d * GOT (%s) [%x]",client_socket,hapstr,i);
+
+			if (strcmp((char *)hapstr,"PROXY") == 0) {
+				lprintf(LOG_DEBUG,"%04d * HAPROXY PROTO v1",client_socket);
+				recv(client_socket,hapstr,1,0);	// \x20
+
+				// Get Protocol
+				memset(hapstr,'\0',sizeof(hapstr));
+				recv(client_socket,hapstr,4,0);
+				lprintf(LOG_DEBUG,"%04d * GOT (%s) [%x]",client_socket,hapstr,i);
+
+				// IPV4
+				if (strcmp((char *)hapstr,"TCP4") == 0) {
+					lprintf(LOG_DEBUG,"%04d * Proto [%s]",client_socket,hapstr);
+					recv(client_socket,hapstr,1,0);	// \x20
+
+					// Source Address
+					recv(client_socket,hapstr,16,0);
+
+				// IPV6
+				} else if (strcmp((char *)hapstr,"TCP6") == 0) {
+					lprintf(LOG_DEBUG,"%04d * Proto %s",client_socket,hapstr);
+					i=recv(client_socket,hapstr,1,0);	// \x20
+
+					// Source Address
+					recv(client_socket,hapstr,40,0);
+
+				// Unknown?
+				} else if (strcmp((char *)hapstr,"UNKN") == 0) {
+					lprintf(LOG_DEBUG,"%04d * Unknown Protocol",client_socket);
+					close_socket(client_socket);
+					continue;
+				}
+
+				// Look for the space between the next IP
+				for(i=0;i<sizeof(hapstr);i++) {
+					if (hapstr[i] == 0x20)
+						break;
+				}
+
+				hapstr[i]='\0';
+				memcpy(host_ip,hapstr,i);
+
+			} else if (strcmp((char *)hapstr,"\x0d\x0a\x0d\x0a\x00") == 0) {
+				lprintf(LOG_DEBUG,"%04d * HAPROXY PROTO v2",client_socket);
+				recv(client_socket,hapstr,7,0);	// \x0d\x0aQUIT\x0a
+				memset(hapstr,'\0',sizeof(hapstr));
+
+				// Command and Version
+				recv(client_socket,hapstr,1,0);
+				i = hapstr[0];
+				lprintf(LOG_DEBUG,"%04d * Version [%x]",client_socket,(i>>0)&((1<<4)-1)); //Should be 2
+				lprintf(LOG_DEBUG,"%04d * Command [%x]",client_socket,(i>>4)&((1<<4)-1)); //0=Local/1=Proxy
+
+				// Protocol and Family
+				recv(client_socket,hapstr,1,0);
+				i = hapstr[0];
+				lprintf(LOG_DEBUG,"%04d * Protocol [%x]",client_socket,(i>>0)&((1<<4)-1)); //0=Unspec/1=AF_INET/2=AF_INET6/3=AF_UNIX
+				l = (i>>4)&((1<<4)-1);
+				lprintf(LOG_DEBUG,"%04d * Family [%x]",client_socket,l); //0=UNSPEC/1=STREAM/2=DGRAM
+
+				// Address Length
+				recv(client_socket,hapstr,2,0);
+				sscanf((char *)hapstr,"%x",&i);
+				lprintf(LOG_DEBUG,"%04d * Address Length [%d]",client_socket,i);
+
+				recv(client_socket,hapstr,i,0);
+
+				switch (l) {
+					// IPv4 - AF_INET
+					case 0x1:
+						sprintf(host_ip,"%d.%d.%d.%d",hapstr[0],hapstr[1],hapstr[2],hapstr[3]);
+						break;
+
+					// IPv6 - AF_INET6
+					case 0x2:
+						// IPv4 address in IPv6 ::ffff:n.n.n.n
+						// 0000:0000:0000:0000:0000:ffff:0a01:039c
+						for(i=0;i<10;i++) {
+							if (hapstr[i] != 0x00)
+								break;
+						}
+
+						if ((i==10) && (hapstr[i] == 0xff) && (hapstr[i+1] == 0xff)) {
+							sprintf(host_ip,"%d.%d.%d.%d",hapstr[12],hapstr[13],hapstr[14],hapstr[15]);
+							lprintf(LOG_DEBUG,"%04d * IPv4 address in IPv6 [%s]",client_socket,host_ip);
+
+						} else {
+							sprintf(host_ip,"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+								hapstr[0],hapstr[1],hapstr[2],hapstr[3],
+								hapstr[4],hapstr[5],hapstr[6],hapstr[7],
+								hapstr[8],hapstr[9],hapstr[10],hapstr[11],
+								hapstr[12],hapstr[13],hapstr[14],hapstr[15]
+							);
+						}
+						break;
+
+					default:
+						lprintf(LOG_DEBUG,"%04d * Unknown Family",client_socket);
+						close_socket(client_socket);
+						continue;
+				}
+
+
+			} else {
+				lprintf(LOG_ERR,"%04d Unknown HAProxy Initialisation - is HAProxy used?",client_socket);
+				close_socket(client_socket);
+				continue;
+			}
+
+			lprintf(LOG_DEBUG,"%04d * Source [%s]",client_socket,host_ip);
+			getaddrinfo(host_ip,NULL,NULL,&res);
+			client_addr.addr = *res->ai_addr;
+
+		} else {
+			inet_addrtop(&client_addr, host_ip, sizeof(host_ip));
+		}
 
 		if(trashcan(&scfg,host_ip,"ip-silent")) {
 			close_socket(client_socket);
diff --git a/src/sbbs3/services.c b/src/sbbs3/services.c
index 14aa6c479235a0cbb8b7ea81d62cd86ca4091bb4..03ac2d844c47b1a75f8ab5a989b8ef6c9eb04f4b 100644
--- a/src/sbbs3/services.c
+++ b/src/sbbs3/services.c
@@ -2129,6 +2129,12 @@ void DLLCALL services_thread(void* arg)
 					}
 					inet_addrtop(&client_addr, host_ip, sizeof(host_ip));
 
+					// Set host_ip from haproxy protocol, if its used
+					if(startup->options&BBS_OPT_HAPROXY_PROTO) {
+						lprintf(LOG_INFO,"** Working out address from HAPROXY PROTO");
+					}
+					lprintf(LOG_INFO,"** Startup options %d (%d)",startup->options,BBS_OPT_HAPROXY_PROTO);
+
 					if(trashcan(&scfg,host_ip,"ip-silent")) {
 						FREE_AND_NULL(udp_buf);
 						close_socket(client_socket);
diff --git a/src/sbbs3/startup.h b/src/sbbs3/startup.h
index 6d3a205a05d4ee37f51634c98e6674d377bfb167..877f8f811c600d7f4937ace7e8c2b3bb3b32dc99 100644
--- a/src/sbbs3/startup.h
+++ b/src/sbbs3/startup.h
@@ -190,6 +190,7 @@ static struct init_field {
 #define BBS_OPT_ALLOW_SSH			(1<<12)	/* Allow logins via BSD SSH			*/
 #define BBS_OPT_NO_DOS				(1<<13) /* Don't attempt to run 16-bit DOS programs */
 #define BBS_OPT_NO_NEWDAY_EVENTS	(1<<14)	/* Don't check for a new day in event thread */
+#define BBS_OPT_HAPROXY_PROTO   	(1<<26)	/* Incoming requests are via HAproxy */
 #define BBS_OPT_NO_RECYCLE			(1<<27)	/* Disable recycling of server		*/
 #define BBS_OPT_GET_IDENT			(1<<28)	/* Get Identity (RFC 1413)			*/
 #define BBS_OPT_NO_JAVASCRIPT		(1<<29)	/* JavaScript disabled				*/
@@ -197,7 +198,7 @@ static struct init_field {
 
 /* bbs_startup_t.options bits that require re-init/recycle when changed */
 #define BBS_INIT_OPTS	(BBS_OPT_ALLOW_RLOGIN|BBS_OPT_ALLOW_SSH|BBS_OPT_NO_EVENTS|BBS_OPT_NO_SPY_SOCKETS \
-						|BBS_OPT_NO_JAVASCRIPT)
+						|BBS_OPT_NO_JAVASCRIPT|BBS_OPT_HAPROXY_PROTO)
 
 #if defined(STARTUP_INI_BITDESC_TABLES)
 static ini_bitdesc_t bbs_options[] = {
@@ -218,6 +219,7 @@ static ini_bitdesc_t bbs_options[] = {
 	{ BBS_OPT_NO_RECYCLE			,"NO_RECYCLE"			},
 	{ BBS_OPT_GET_IDENT				,"GET_IDENT"			},
 	{ BBS_OPT_NO_JAVASCRIPT			,"NO_JAVASCRIPT"		},
+	{ BBS_OPT_HAPROXY_PROTO			,"HAPROXY_PROTO"		},
 	{ BBS_OPT_MUTE					,"MUTE"					},
 	/* terminator */										
 	{ 0								,NULL					}