Compare commits

...

10 Commits

Author SHA1 Message Date
jendis
2d9f322618
Merge 983df6f7ae into b5ab5b8906 2025-12-12 23:36:49 +03:00
Vladimir Dubrovin
b5ab5b8906 client_sni command added; do not send hostname from request as SNI in SSL client configuration
Some checks failed
C/C++ CI / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
2025-12-12 19:08:26 +03:00
Vladimir Dubrovin
ec7004cd6f Close SSL on shutdown 2025-12-12 18:25:40 +03:00
Vladimir Dubrovin
fe53378596 maxseg / TCP_MAXSEG support added
Some checks failed
C/C++ CI / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
2025-11-29 15:05:29 +03:00
Vladimir Dubrovin
5450ca4cdf Fixed: invalid config value initializers 2025-11-29 14:46:01 +03:00
Vladimir Dubrovin
fbca6d8e93 Update c-cpp.yml
Some checks failed
C/C++ CI / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
2025-11-17 16:21:53 +03:00
Vladimir Dubrovin
7353b77206
Update c-cpp.yml 2025-11-17 15:40:26 +03:00
Vladimir Dubrovin
08d3f5fa76
Update c-cpp.yml 2025-11-17 15:38:40 +03:00
Alexey Suslov
7a1ca8d341
Fix HTTPS proxy for HTTPS addresses (#1175) 2025-11-17 15:31:54 +03:00
Jan Smutny
983df6f7ae Extend SOCKS for AnyIP utilization
Introduce '-k' parameter that overwrites the -e parameter (if given) and
uses the IP for the external connection that corresponds to the current client
connection. The benefit arises when the parameter '-i0.0.0.0' or '-i::' in case
of IPv6 is set. This allows the entire range configured as local on the system
to receive connections and establish connections to the target server using the
IP address to which the client connected.
Note: This feature is not applicable for Windows.
2025-02-06 13:23:03 +01:00
8 changed files with 136 additions and 29 deletions

View File

@ -34,7 +34,7 @@ jobs:
run: copy Makefile.win Makefile
- name: dirs Windows
if: ${{ startsWith(matrix.target, 'windows') }}
run: cmd /C 'echo LIBS := -L "c:/program files/openssl/lib" $(LIBS) >>Makefile.win && echo CFLAGS := -I "c:/program files/openssl/include" $(CFLAGS) >>Makefile.win && type Makefile.win'
run: cmd /C 'echo LIBS := -L "c:/program files/openssl/lib/VC/x64/MT" $(LIBS) >>Makefile.win && echo CFLAGS := -I "c:/program files/openssl/include" $(CFLAGS) >>Makefile.win && type Makefile.win && dir "c:/program files/openssl/lib"'
- name: SSLPlugin Linux
if: ${{ startsWith(matrix.target, 'ubuntu') }}
run: "sed -i '/^PLUGIN/s/$/ SSLPlugin/' Makefile && sed -i '/^LIBS/s/$/ -lcrypto -lssl/' Makefile"

View File

@ -42,6 +42,16 @@ of IP-IP NAT (will not work for PAT)
Internal address. IP address proxy accepts connections to.
By default connection to any interface is accepted. It\'s usually unsafe.
.TP
.B -k
External address given by
.B -e
is ignored and the internal address or generally the address client conected to is used instead.
This allows to utilize AnyIP Linux feature when
.B -i0.0.0.0
or in case of IPv6
.B -i::
is set. Not available for Windows platform.
.TP
.B -p
Port. Port proxy listens for incoming connections. Default is 1080.
.TP

View File

@ -93,27 +93,31 @@ char *rotations[] = {
struct extparam conf = {
{0, 0},
{1, 5, 30, 60, 180, 1800, 15, 60, 15, 5, 0, 0},
NULL,
NULL,
NULL, NULL,
NULL,
NULL,
NULL,
0,
-1, 0, 0, 0, 0,
0, 500, 0, 0, 0, 0, 0, 0, 2,
0, 0, 0,
6, 600,
1048576,
NULL, NULL,
NONE, NONE,
NULL,
{0, 0}, /* threadinit */
{1, 5, 30, 60, 180, 1800, 15, 60, 15, 5, 0, 0}, /* timeouts */
NULL, /* struct ace * acl; */
NULL, /* char * conffile; */
NULL, NULL, /* struct bandlim * bandlimiter, *bandlimiterout; */
NULL, /* struct connlim * connlimiter; */
NULL, /* struct trafcount * trafcounter; */
NULL, /* struct srvparam *services; */
0, /* int stacksize, */
-1, 0, 0, 0, 0, /* counterd, haveerror, rotate, paused, archiverc, */
0, 500, 0, 0, 0, 0, 0, 0, 2, /* demon, maxchild, backlog, needreload, timetoexit, version, noforce, bandlimver, parentretries; */
6, 600, /* int authcachetype, authcachetime; */
1048576, /* int filtermaxsize; */
0, 0, 0, /* int gracetraf, gracenum, gracedelay */
0, /* int maxseg */
NULL, NULL, /* unsigned char *logname, **archiver; */
NONE, NONE, /* ROTATION logtype, countertype; */
NULL, /* char * counterfile; */
#ifndef NOIPV6
{AF_INET},{AF_INET6},{AF_INET},
{AF_INET},
{AF_INET6},
{AF_INET},
#else
{AF_INET},{AF_INET},
{AF_INET},
{AF_INET},
#endif
NULL,
NULL,
@ -522,16 +526,48 @@ int doconnect(struct clientparam * param){
if(!*SAPORT(&param->sinsr))*SAPORT(&param->sinsr) = *SAPORT(&param->req);
if ((param->remsock=param->srv->so._socket(param->sostate, SASOCK(&param->sinsr), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {return (11);}
if(SAISNULL(&param->sinsl)){
if (param->srv->keepip) {
#ifndef NOIPV6
struct sockaddr_in6 local_addr;
socklen_t local_addr_len = sizeof(local_addr);
getsockname(param->clisock, (struct sockaddr *)&local_addr, &local_addr_len);
if(*SAFAMILY(&local_addr) == AF_INET6) {
if (IN6_IS_ADDR_V4MAPPED(&local_addr.sin6_addr)) {
struct sockaddr_in6 local_addr2;
memset(&local_addr2, 0, sizeof(local_addr2));
local_addr2.sin6_family = AF_INET;
local_addr2.sin6_port = local_addr.sin6_port;
param->sinsl = local_addr2;
} else {
param->sinsl = local_addr;
}
} else {
param->sinsl = local_addr;
}
#else
struct sockaddr_in local_addr;
socklen_t local_addr_len = sizeof(local_addr);
getsockname(new_sock, (struct sockaddr *)&local_addr, &local_addr_len);
param->sinsl = local_addr;
#endif
} else {
#ifndef NOIPV6
if(*SAFAMILY(&param->sinsr) == AF_INET6) param->sinsl = param->srv->extsa6;
else
#endif
param->sinsl = param->srv->extsa;
}
}
*SAPORT(&param->sinsl) = 0;
setopts(param->remsock, param->srv->srvsockopts);
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
if (param->srv->keepip) {
int opt = 1;
param->srv->so._setsockopt(param->sostate, param->remsock, SOL_IP, IP_FREEBIND, (char *)&opt, sizeof(int));
}
#ifdef REUSE
{
int opt;

View File

@ -466,6 +466,11 @@ static int h_rotate(int argc, unsigned char **argv){
return 0;
}
static int h_maxseg(int argc, unsigned char **argv){
conf.maxseg = atoi((char *)argv[1]);
return 0;
}
static int h_logformat(int argc, unsigned char **argv){
unsigned char * old = conf.logformat;
conf.logformat = (unsigned char *)mystrdup((char *)argv[1]);
@ -1648,8 +1653,9 @@ struct commands commandhandlers[]={
{commandhandlers+64, "auto", h_proxy, 1, 0},
{commandhandlers+65, "backlog", h_backlog, 2, 2},
{commandhandlers+66, "tlspr", h_proxy, 1, 0},
{commandhandlers+67, "maxseg", h_maxseg, 2, 2},
#ifndef NORADIUS
{commandhandlers+67, "radius", h_radius, 3, 0},
{commandhandlers+68, "radius", h_radius, 3, 0},
#endif
{specificcommands, "", h_noop, 1, 0}
};

View File

@ -30,6 +30,8 @@ struct ssl_config {
char * server_ca_file;
char * server_ca_dir;
char * server_ca_store;
char * client_sni;
char * client_alpn;
int mitm;
int serv;
int cli;

View File

@ -58,6 +58,8 @@ char * client_ciphersuites = NULL;
char * server_ciphersuites = NULL;
char * client_cipher_list = NULL;
char * server_cipher_list = NULL;
char * client_sni = NULL;
char * client_alpn = NULL;
typedef struct _ssl_conn {
struct SSL_CTX *ctx;
@ -211,6 +213,11 @@ static ssize_t ssl_recv(void *state, SOCKET s, void *msg, size_t len, int flags)
return sso._recv(sso.state, s, msg, len, flags);
}
static int WINAPI ssl_shutdown(void *state, SOCKET s, int how){
delSSL(state, s);
return sso._shutdown(sso.state, s, how);
}
static int WINAPI ssl_closesocket(void *state, SOCKET s){
delSSL(state, s);
return sso._closesocket(sso.state, s);
@ -307,8 +314,11 @@ int docli(struct clientparam* param){
SSL_CONN ServerConn;
SSL_CERT ServerCert=NULL;
unsigned char *hostname;
hostname = param->hostname;
param->hostname = (unsigned char *)PCONF->client_sni;
ServerConn = dosrvcon(param, &ServerCert);
param->hostname = hostname;
_ssl_cert_free(ServerCert);
if(!ServerConn) return 1;
@ -437,6 +447,9 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
if(server_ca_dir)sc->server_ca_dir=server_ca_dir;
if(server_ca_store)sc->server_ca_store=server_ca_store;
if(client_sni)sc->client_sni=client_sni;
if(client_alpn)sc->client_alpn=client_alpn;
if(mitm){
if(!server_ca_file){
@ -501,6 +514,7 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
srv->so._recv = ssl_recv;
srv->so._sendto = ssl_sendto;
srv->so._recvfrom = ssl_recvfrom;
srv->so._shutdown = ssl_shutdown;
srv->so._closesocket = ssl_closesocket;
srv->so._poll = ssl_poll;
}
@ -536,7 +550,7 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
SSL_CTX_set_verify(sc->srv_ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
}
}
#ifdef WIWHSPLICE
#ifdef WITHSPLICE
srv->usesplice = 0;
#endif
return sc;
@ -629,6 +643,8 @@ static void ssl_filter_close(void *fo){
free(CONFIG->client_ca_file);
free(CONFIG->client_ca_dir);
free(CONFIG->client_ca_store);
free(CONFIG->client_sni);
free(CONFIG->client_alpn);
free(fo);
}
@ -829,6 +845,18 @@ static int h_client_ca_store(int argc, unsigned char **argv){
return 0;
}
static int h_client_sni(int argc, unsigned char **argv){
free(client_sni);
client_sni = argc > 1? strdup((char *)argv[1]) : NULL;
return 0;
}
static int h_client_alpn(int argc, unsigned char **argv){
free(client_alpn);
client_alpn = argc > 1? strdup((char *)argv[1]) : NULL;
return 0;
}
static int h_server_ca_dir(int argc, unsigned char **argv){
free(server_ca_dir);
server_ca_dir = argc > 1? strdup((char *)argv[1]) : NULL;
@ -950,6 +978,8 @@ static struct commands ssl_commandhandlers[] = {
{ssl_commandhandlers+31, "ssl_server_no_verify", h_no_server_verify, 1, 1},
{ssl_commandhandlers+32, "ssl_server_ca_dir", h_server_ca_dir, 1, 2},
{ssl_commandhandlers+33, "ssl_server_ca_store", h_server_ca_store, 1, 2},
{ssl_commandhandlers+34, "ssl_client_sni", h_client_sni, 1, 2},
{ssl_commandhandlers+35, "ssl_client_alpn", h_client_alpn, 1, 2},
{NULL, "ssl_certcache", h_certcache, 2, 2},
};

View File

@ -170,6 +170,9 @@ struct socketoptions sockopts[] = {
#endif
#ifdef TCP_FASTOPEN_CONNECT
{TCP_FASTOPEN_CONNECT, "TCP_FASTOPEN_CONNECT"},
#endif
#ifdef TCP_MAXSEG
{TCP_MAXSEG, "TCP_MAXSEG"},
#endif
{0, NULL}
};
@ -193,6 +196,12 @@ void setopts(SOCKET s, int opts){
int i, opt, set;
for(i = 0; opts >= (opt = (1<<i)); i++){
set = 1;
#ifdef TCP_MAXSEG
if(sockopts[i].opt == TCP_MAXSEG){
if(!conf.maxseg) continue;
set = conf.maxseg;
}
#endif
if(opts & opt) setsockopt(s, *sockopts[i].optname == 'T'? IPPROTO_TCP:
#ifdef SOL_IP
*sockopts[i].optname == 'I'? SOL_IP:
@ -279,6 +288,9 @@ int MODULEMAINFUNC (int argc, char** argv){
"\n"
" -iIP ip address or internal interface (clients are expected to connect)\n"
" -eIP ip address or external interface (outgoing connection will have this)\n"
#ifndef _WIN32
" -k outgoing connection will have local IP where client connected, thus ignores -e (useful in AnyIP case)\n"
#endif
" -rHOST:PORT Use IP:port for connect back proxy instead of listen port\n"
" -RHOST:PORT Use PORT to listen connect back proxy connection to pass data to\n"
" -4 Use IPv4 for outgoing connections\n"
@ -417,6 +429,13 @@ int MODULEMAINFUNC (int argc, char** argv){
#endif
}
break;
#ifndef _WIN32
case 'k':
{
srv.keepip = 1;
}
break;
#endif
case 'N':
getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&srv.extNat);
break;
@ -806,6 +825,7 @@ int MODULEMAINFUNC (int argc, char** argv){
}
else {
new_sock = srv.so._accept(srv.so.state, sock, (struct sockaddr*)&defparam.sincr, &size);
if(new_sock == INVALID_SOCKET){
#ifdef _WIN32
switch(WSAGetLastError()){
@ -981,6 +1001,7 @@ void srvinit(struct srvparam * srv, struct clientparam *param){
srv->logdumpcli = conf.logdumpcli;
srv->cbsock = INVALID_SOCKET;
srv->needuser = 1;
srv->keepip = 0;
#ifdef WITHSPLICE
srv->usesplice = 1;
#endif

View File

@ -491,6 +491,7 @@ struct srvparam {
int paused, version;
int singlepacket;
int usentlm;
int keepip;
int needuser;
int silent;
int transparent;
@ -651,6 +652,7 @@ struct extparam {
int authcachetype, authcachetime;
int filtermaxsize;
int gracetraf, gracenum, gracedelay;
int maxseg;
unsigned char *logname, **archiver;
ROTATION logtype, countertype;
char * counterfile;