Skip to content

Commit 44e942d

Browse files
committed
v1.2(development beta 1, patch 10)
1. Added support of IP forwarding(#7).
1 parent 3ac8866 commit 44e942d

File tree

6 files changed

+87
-21
lines changed

6 files changed

+87
-21
lines changed

README.md

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Minecraft Versions before 12w04a are **NOT SUPPORTED**!
1010
## Features
1111
* Support reverse proxy for Minecraft servers by server address in the handshake packet which client send to.
1212
* Support rewrite server address and server port to camouflage connection which using official server address. (eg: pretend to be a normal connection to Hypixel, avoiding their server address check.)
13+
* Support IP forwarding using HAProxy's Proxy Protocol. (But refuses any incoming connection using this protocol.)
1314

1415
## Requirements
1516
* Linux
@@ -24,10 +25,10 @@ Minecraft Versions before 12w04a are **NOT SUPPORTED**!
2425
## Files
2526
* mcrelay.c: Source code of Main program.
2627
* mcrelay.conf.example: config file example of mcrelay.
27-
* mcrelay.service.forking.example: service unit file of mcrelay for systemd(using runmode: forking).
28-
* mcrelay.service.simple.example: service unit file of mcrelay for systemd(using runmode: simple).
28+
* mcrelay.service.forking.example: service unit file of mcrelay for systemd. (using runmode: forking)
29+
* mcrelay.service.simple.example: service unit file of mcrelay for systemd. (using runmode: simple)
2930
* mod: directory of essential modules.
30-
* version.json: version manifest
31+
* version.json: version manifest.
3132
* loglevel.info: definations for messages.
3233

3334
## Compile
@@ -60,6 +61,7 @@ proxy_pass proxy_type
6061
ident_name destination_object
6162
default destination_object
6263
</pre>
64+
6365
### Explanation
6466
* log: set log file.
6567
>* logfile_path: path of the file which logs saved to.
@@ -71,18 +73,19 @@ default destination_object
7173
>>* port: the port you wish to bind as an Internet Service. Valid range: 1-65535.
7274
* proxy_pass: list of relay/relay+rewrites.
7375
>* proxy_type: type of proxies, "relay" for raw relay, "rewrite" for relay with server address camouflage enabled.
74-
>* ident_name: name of destination identification. Usually a Fully Qualified Domain Name(FQDN) by CNAME to your server.
76+
>>* You can add "p" suffix (i.e. "relayp" or "rewritep") to enable IP forwarding. (Need downstream supports HAProxy's Proxy Protocol, otherwise your connection will be aborted.)
77+
>* ident_name: name of destination identification. Usually a Fully Qualified Domain Name (FQDN) by CNAME to your server.
7578
>* destination_object: (format: "address_d[:port]")
7679
>>* address_d: the address you wish to connect. Both FQDN or x.x.x.x allowed.
7780
>>* port: optional, the port you wish to connect. Valid range: 1-65535.
7881
79-
If not set, the server will detect SRV record first(defined in address_d).
82+
If not set, the server will detect SRV record first. (defined in address_d)
8083

8184
If SRV record resolve failed, it will fallback to normal address resolve, also connect to this address with port 25565.
8285

8386
**For rewrite enabled relay, it will use actual connect configuration to rewrite.**
84-
>>* path: the socket file you wish to connect.
8587
* default: optional, set a default server to connect when client don't match any valid virtual host. (Intentionally not support rewrite here.) (Security suggestion: Don't use this feature unless you know what you are doing.)
88+
8689
### Example
8790
<pre>
8891
log /var/log/mcrelay/mcrelay.log
@@ -96,7 +99,7 @@ proxy_pass relay
9699
default 192.168.1.254:25565
97100
</pre>
98101

99-
## Instruction of using a DNS-based redirection(SRV)
102+
## Instruction of using a DNS-based redirection (SRV)
100103
If you are using a SRV record to provide your service, you should follow the instructions below.
101104

102105
Otherwise, your user will see the message of using a wrong address to connect.
@@ -110,3 +113,11 @@ If you provide "srvrecord.example.com" to your user, you should set your vhostna
110113
* For Minecraft version from 21w20a to 1.17, use "srvrecord.example.com".
111114

112115
For compatibility, it's recommended to add both of them to your configuration.
116+
117+
## IP Forwarding
118+
You can provide the real client address and port through HAProxy's Proxy Protocol by this feature.
119+
120+
It's compatible with any server which support this protocol. (e.g. Bungeecord)
121+
122+
### Bungeecord
123+
To use this feature correctly, turn on the "proxy_protocol" in the "config.yml". ("false" to "true")

mod/config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ typedef struct
2727
} conf_bind;
2828
typedef struct
2929
{
30-
unsigned short enable_rewrite;
30+
unsigned short enable_rewrite,enable_pheader;
3131
char from[512],to_inet_addr[512];
3232
unsigned short to_inet_port;
3333
unsigned short to_inet_hybridmode;

mod/linux/config.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ void config_dump(conf * source)
7474
printf("Rewrite\t\tEnabled\n");
7575
break;
7676
}
77+
switch(source->relay[i].enable_pheader)
78+
{
79+
case 0:
80+
printf("PHeader\t\tDisabled\n");
81+
break;
82+
case 1:
83+
printf("PHeader\t\tEnabled\n");
84+
break;
85+
}
7786
printf("vhost\t\t%s\n",source->relay[i].from);
7887
printf("Address\t\t%s\n",source->relay[i].to_inet_addr);
7988
switch(source->relay[i].to_inet_hybridmode)
@@ -176,14 +185,26 @@ int config_load(char * filename, conf * result)
176185
}
177186
else if(strcmp(key,"proxy_pass")==0)
178187
{
179-
int enable_rewrite;
188+
int enable_rewrite,enable_pheader;
180189
if(strcmp(value,"rewrite")==0)
181190
{
182191
enable_rewrite=1;
192+
enable_pheader=0;
183193
}
184194
else if(strcmp(value,"relay")==0)
185195
{
186196
enable_rewrite=0;
197+
enable_pheader=0;
198+
}
199+
else if(strcmp(value,"rewritep")==0)
200+
{
201+
enable_rewrite=1;
202+
enable_pheader=1;
203+
}
204+
else if(strcmp(value,"relayp")==0)
205+
{
206+
enable_rewrite=0;
207+
enable_pheader=1;
187208
}
188209
else
189210
{
@@ -195,6 +216,7 @@ int config_load(char * filename, conf * result)
195216
{
196217
tmpptr++;
197218
result->relay[rec_relay].enable_rewrite=enable_rewrite;
219+
result->relay[rec_relay].enable_pheader=enable_pheader;
198220
if(strsplit_fieldcount(tmpptr,' ')!=2)
199221
{
200222
line_reccount++;
@@ -253,6 +275,7 @@ int config_load(char * filename, conf * result)
253275
return CONF_EDEFPROXYDUP;
254276
}
255277
relay_default.enable_rewrite=0;
278+
relay_default.enable_pheader=0;
256279
strcpy(relay_default.from,"*");
257280
if(strsplit_fieldcount(tmpptr,':')==1)
258281
{

mod/linux/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include <unistd.h>
2121
const char * version_str="1.2-beta1";
2222
const char * year_str="2020-2021";
23-
const short version_internal=45;
23+
const short version_internal=46;
2424
conf config;
2525
char configfile[512],cwd[512],config_logfull[BUFSIZ];
2626
unsigned short config_runmode=1;

mod/linux/misc.c

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@
1313
#include <string.h>
1414
int backbone(int socket_in, int * socket_out, char * logfile, unsigned short runmode, conf conf_in, struct sockaddr_in addrinfo_in)
1515
{
16-
unsigned char inbound[BUFSIZ],outbound[BUFSIZ],rewrited[BUFSIZ];
17-
int packlen_inbound,packlen_outbound,packlen_rewrited;
16+
unsigned char inbound[BUFSIZ],outbound[BUFSIZ],rewrited[BUFSIZ],pheader[105];
17+
int packlen_inbound,packlen_outbound,packlen_rewrited,packlen_pheader;
1818
struct sockaddr_in addr_outbound;
19-
bzero(inbound,BUFSIZ);
20-
bzero(outbound,BUFSIZ);
21-
bzero(rewrited,BUFSIZ);
19+
memset(inbound,0,BUFSIZ);
20+
memset(outbound,0,BUFSIZ);
21+
memset(rewrited,0,BUFSIZ);
22+
memset(pheader,0,105);
2223
packlen_inbound=recv(socket_in,inbound,BUFSIZ,0);
2324
if(packlen_inbound==0)
2425
{
@@ -89,12 +90,16 @@ int backbone(int socket_in, int * socket_out, char * logfile, unsigned short run
8990
mkoutbound_status=NET_ENORECORD;
9091
}
9192
*socket_out=net_socket(NETSOCK_CONN,AF_INET,connaddr,proxyinfo->to_inet_port,0);
92-
free(connaddr);
93-
connaddr=NULL;
9493
if(*socket_out==-1)
9594
{
9695
mkoutbound_status=NET_ECONNECT;
9796
}
97+
char * connaddr_strp=inet_ntoa(*((struct in_addr *)connaddr));
98+
free(connaddr);
99+
connaddr=NULL;
100+
char * connaddr_str=(char *)malloc(strlen(connaddr_strp)+1);
101+
strcpy(connaddr_str,connaddr_strp);
102+
connaddr_strp=NULL;
98103
if(mkoutbound_status!=0)
99104
{
100105
outmsg_level=1;
@@ -107,6 +112,11 @@ int backbone(int socket_in, int * socket_out, char * logfile, unsigned short run
107112
{
108113
case 0:
109114
mksysmsg(0,logfile,runmode,conf_in.loglevel,outmsg_level,"src: %s:%d, type: motd, vhost: %s, dst: %s:%d, status: accept\n",inet_ntoa(addrinfo_in.sin_addr),ntohs(addrinfo_in.sin_port),proxyinfo->from,proxyinfo->to_inet_addr,proxyinfo->to_inet_port);
115+
if(proxyinfo->enable_pheader==1)
116+
{
117+
packlen_pheader=sprintf(pheader,"PROXY TCP4 %s %s %d %d\r\n",inet_ntoa(addrinfo_in.sin_addr),connaddr_str,ntohs(addrinfo_in.sin_port),proxyinfo->to_inet_port);
118+
send(*socket_out,pheader,packlen_pheader,0);
119+
}
110120
if(proxyinfo->enable_rewrite==1)
111121
{
112122
strcpy(inbound_info.address,proxyinfo->to_inet_addr);
@@ -200,12 +210,16 @@ int backbone(int socket_in, int * socket_out, char * logfile, unsigned short run
200210
mkoutbound_status=NET_ENORECORD;
201211
}
202212
*socket_out=net_socket(NETSOCK_CONN,AF_INET,connaddr,proxyinfo->to_inet_port,0);
203-
free(connaddr);
204-
connaddr=NULL;
205213
if(*socket_out==-1)
206214
{
207215
mkoutbound_status=NET_ECONNECT;
208216
}
217+
char * connaddr_strp=inet_ntoa(*((struct in_addr *)connaddr));
218+
free(connaddr);
219+
connaddr=NULL;
220+
char * connaddr_str=(char *)malloc(strlen(connaddr_strp)+1);
221+
strcpy(connaddr_str,connaddr_strp);
222+
connaddr_strp=NULL;
209223
if(mkoutbound_status!=0)
210224
{
211225
outmsg_level=1;
@@ -218,6 +232,11 @@ int backbone(int socket_in, int * socket_out, char * logfile, unsigned short run
218232
{
219233
case 0:
220234
mksysmsg(0,logfile,runmode,conf_in.loglevel,outmsg_level,"src: %s:%d, type: game, vhost: %s, dst: %s:%d, status: accept, username: %s\n",inet_ntoa(addrinfo_in.sin_addr),ntohs(addrinfo_in.sin_port),proxyinfo->from,proxyinfo->to_inet_addr,proxyinfo->to_inet_port,inbound_info.username);
235+
if(proxyinfo->enable_pheader==1)
236+
{
237+
packlen_pheader=sprintf(pheader,"PROXY TCP4 %s %s %d %d\r\n",inet_ntoa(addrinfo_in.sin_addr),connaddr_str,ntohs(addrinfo_in.sin_port),proxyinfo->to_inet_port);
238+
send(*socket_out,pheader,packlen_pheader,0);
239+
}
221240
if(proxyinfo->enable_rewrite==1)
222241
{
223242
strcpy(inbound_info.address,proxyinfo->to_inet_addr);
@@ -318,12 +337,16 @@ int backbone(int socket_in, int * socket_out, char * logfile, unsigned short run
318337
mkoutbound_status=NET_ENORECORD;
319338
}
320339
*socket_out=net_socket(NETSOCK_CONN,AF_INET,connaddr,proxyinfo->to_inet_port,0);
321-
free(connaddr);
322-
connaddr=NULL;
323340
if(*socket_out==-1)
324341
{
325342
mkoutbound_status=NET_ECONNECT;
326343
}
344+
char * connaddr_strp=inet_ntoa(*((struct in_addr *)connaddr));
345+
free(connaddr);
346+
connaddr=NULL;
347+
char * connaddr_str=(char *)malloc(strlen(connaddr_strp)+1);
348+
strcpy(connaddr_str,connaddr_strp);
349+
connaddr_strp=NULL;
327350
if(mkoutbound_status!=0)
328351
{
329352
outmsg_level=1;
@@ -350,6 +373,11 @@ int backbone(int socket_in, int * socket_out, char * logfile, unsigned short run
350373
{
351374
mksysmsg(0,logfile,runmode,conf_in.loglevel,outmsg_level,"src: %s:%d, type: game, vhost: %s, dst: %s:%d, status: accept, username: %s\n",inet_ntoa(addrinfo_in.sin_addr),ntohs(addrinfo_in.sin_port),proxyinfo->from,proxyinfo->to_inet_addr,proxyinfo->to_inet_port,inbound_info.username);
352375
}
376+
if(proxyinfo->enable_pheader==1)
377+
{
378+
packlen_pheader=sprintf(pheader,"PROXY TCP4 %s %s %d %d\r\n",inet_ntoa(addrinfo_in.sin_addr),connaddr_str,ntohs(addrinfo_in.sin_port),proxyinfo->to_inet_port);
379+
send(*socket_out,pheader,packlen_pheader,0);
380+
}
353381
if(proxyinfo->enable_rewrite==1)
354382
{
355383
strcpy(inbound_info.address,proxyinfo->to_inet_addr);

version.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,5 +170,9 @@
170170
{
171171
"version": 45,
172172
"names": ["1.2-beta1-patch9"]
173+
{
174+
"version": 46,
175+
"names": ["1.2-beta1-patch10"]
176+
}
173177
}
174178
]

0 commit comments

Comments
 (0)