added QSE_HTTPD_SERVER_TRANSPARENT to allow optional support for TPROXY.
changed to set the target to SECURE when the intercepted connection is known to be SECURE
This commit is contained in:
parent
c7bd05b419
commit
028646bb54
@ -527,9 +527,17 @@ static int get_server_root (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mth == QSE_HTTP_CONNECT)
|
if (mth == QSE_HTTP_CONNECT)
|
||||||
|
{
|
||||||
root->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_RAW;
|
root->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_RAW;
|
||||||
else if (loccfg->proxy.pseudonym[0])
|
}
|
||||||
root->u.proxy.pseudonym = loccfg->proxy.pseudonym;
|
else
|
||||||
|
{
|
||||||
|
if (loccfg->proxy.pseudonym[0])
|
||||||
|
root->u.proxy.pseudonym = loccfg->proxy.pseudonym;
|
||||||
|
|
||||||
|
if (server->dope.flags & QSE_HTTPD_SERVER_SECURE)
|
||||||
|
root->u.proxy.flags |= QSE_HTTPD_RSRC_PROXY_DST_SECURE;
|
||||||
|
}
|
||||||
|
|
||||||
goto proxy_ok;
|
goto proxy_ok;
|
||||||
}
|
}
|
||||||
@ -2047,6 +2055,7 @@ static qse_httpd_server_t* attach_server (qse_httpd_t* httpd, int num, qse_xli_l
|
|||||||
if (pair && pair->val->type == QSE_XLI_STR &&
|
if (pair && pair->val->type == QSE_XLI_STR &&
|
||||||
qse_strxcmp (((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len, QSE_T("yes")) == 0) dope.flags |= QSE_HTTPD_SERVER_SECURE;
|
qse_strxcmp (((qse_xli_str_t*)pair->val)->ptr, ((qse_xli_str_t*)pair->val)->len, QSE_T("yes")) == 0) dope.flags |= QSE_HTTPD_SERVER_SECURE;
|
||||||
|
|
||||||
|
dope.flags |= QSE_HTTPD_SERVER_TRANSPARENT; /* need this to support TPROXY when proxy.allow_intercept is enabled */
|
||||||
dope.detach = free_server_config;
|
dope.detach = free_server_config;
|
||||||
xserver = qse_httpd_attachserverstd (httpd, &dope, QSE_SIZEOF(server_xtn_t));
|
xserver = qse_httpd_attachserverstd (httpd, &dope, QSE_SIZEOF(server_xtn_t));
|
||||||
if (xserver == QSE_NULL)
|
if (xserver == QSE_NULL)
|
||||||
|
@ -211,6 +211,9 @@ struct qse_httpd_peer_t
|
|||||||
|
|
||||||
/* == PRIVATE == */
|
/* == PRIVATE == */
|
||||||
|
|
||||||
|
/* set by httpd to the client this peer has been created for */
|
||||||
|
qse_httpd_client_t* client;
|
||||||
|
|
||||||
/* peer links for the proxy peer cache list in client.
|
/* peer links for the proxy peer cache list in client.
|
||||||
* internal use only. don't mess with these */
|
* internal use only. don't mess with these */
|
||||||
qse_httpd_peer_t* next;
|
qse_httpd_peer_t* next;
|
||||||
@ -749,9 +752,10 @@ struct qse_httpd_client_t
|
|||||||
|
|
||||||
enum qse_httpd_server_flag_t
|
enum qse_httpd_server_flag_t
|
||||||
{
|
{
|
||||||
QSE_HTTPD_SERVER_ACTIVE = (1 << 0),
|
QSE_HTTPD_SERVER_ACTIVE = (1 << 0),
|
||||||
QSE_HTTPD_SERVER_SECURE = (1 << 1),
|
QSE_HTTPD_SERVER_SECURE = (1 << 1),
|
||||||
QSE_HTTPD_SERVER_BINDTONWIF = (1 << 2)
|
QSE_HTTPD_SERVER_BINDTONWIF = (1 << 2),
|
||||||
|
QSE_HTTPD_SERVER_TRANSPARENT = (1 << 3)
|
||||||
};
|
};
|
||||||
typedef enum qse_httpd_server_flag_t qse_httpd_server_flag_t;
|
typedef enum qse_httpd_server_flag_t qse_httpd_server_flag_t;
|
||||||
|
|
||||||
|
@ -2270,8 +2270,7 @@ static void on_url_rewritten (qse_httpd_t* httpd, const qse_mchar_t* url, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int task_main_proxy (
|
static int task_main_proxy (qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task)
|
|
||||||
{
|
{
|
||||||
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
task_proxy_t* proxy = (task_proxy_t*)task->ctx;
|
||||||
proxy_peer_htrd_xtn_t* xtn;
|
proxy_peer_htrd_xtn_t* xtn;
|
||||||
@ -2383,8 +2382,7 @@ static int task_main_proxy (
|
|||||||
if (!(proxy->flags & PROXY_RAW))
|
if (!(proxy->flags & PROXY_RAW))
|
||||||
{
|
{
|
||||||
/* set up a http reader to read a response from the peer */
|
/* set up a http reader to read a response from the peer */
|
||||||
proxy->peer_htrd = qse_htrd_open (
|
proxy->peer_htrd = qse_htrd_open (httpd->mmgr, QSE_SIZEOF(proxy_peer_htrd_xtn_t));
|
||||||
httpd->mmgr, QSE_SIZEOF(proxy_peer_htrd_xtn_t));
|
|
||||||
if (proxy->peer_htrd == QSE_NULL) goto oops;
|
if (proxy->peer_htrd == QSE_NULL) goto oops;
|
||||||
xtn = (proxy_peer_htrd_xtn_t*) qse_htrd_getxtn (proxy->peer_htrd);
|
xtn = (proxy_peer_htrd_xtn_t*) qse_htrd_getxtn (proxy->peer_htrd);
|
||||||
xtn->proxy = proxy;
|
xtn->proxy = proxy;
|
||||||
@ -2400,7 +2398,9 @@ static int task_main_proxy (
|
|||||||
proxy->res_pending = 0;
|
proxy->res_pending = 0;
|
||||||
|
|
||||||
/* get a cached peer connection */
|
/* get a cached peer connection */
|
||||||
peer_from_cache = qse_httpd_decacheproxypeer (httpd, client, &proxy->peer->nwad, &proxy->peer->local, (proxy->peer->flags & QSE_HTTPD_PEER_SECURE));
|
peer_from_cache = qse_httpd_decacheproxypeer (
|
||||||
|
httpd, client, &proxy->peer->nwad,
|
||||||
|
&proxy->peer->local, (proxy->peer->flags & QSE_HTTPD_PEER_SECURE));
|
||||||
if (peer_from_cache)
|
if (peer_from_cache)
|
||||||
{
|
{
|
||||||
qse_mchar_t tmpch;
|
qse_mchar_t tmpch;
|
||||||
@ -2424,13 +2424,13 @@ static int task_main_proxy (
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* the cached connection seems to be stale or invalid */
|
/* the cached connection seems to be stale or invalid */
|
||||||
#if defined(QSE_HTTPD_DEBUG)
|
#if defined(QSE_HTTPD_DEBUG)
|
||||||
{
|
{
|
||||||
qse_mchar_t tmp[128];
|
qse_mchar_t tmp[128];
|
||||||
qse_nwadtombs (&peer_from_cache->nwad, tmp, QSE_COUNTOF(tmp), QSE_NWADTOMBS_ALL);
|
qse_nwadtombs (&peer_from_cache->nwad, tmp, QSE_COUNTOF(tmp), QSE_NWADTOMBS_ALL);
|
||||||
HTTPD_DBGOUT2 ("Decached and closed stale peer [%hs] - %zd\n", tmp, (qse_size_t)peer_from_cache->handle);
|
HTTPD_DBGOUT2 ("Decached and closed stale peer [%hs] - %zd\n", tmp, (qse_size_t)peer_from_cache->handle);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
httpd->opt.scb.peer.close (httpd, peer_from_cache);
|
httpd->opt.scb.peer.close (httpd, peer_from_cache);
|
||||||
qse_httpd_freemem (httpd, peer_from_cache);
|
qse_httpd_freemem (httpd, peer_from_cache);
|
||||||
|
|
||||||
@ -2445,6 +2445,8 @@ static int task_main_proxy (
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
proxy->peer->client = client;
|
||||||
|
|
||||||
httpd->errnum = QSE_HTTPD_ENOERR;
|
httpd->errnum = QSE_HTTPD_ENOERR;
|
||||||
n = httpd->opt.scb.peer.open (httpd, proxy->peer);
|
n = httpd->opt.scb.peer.open (httpd, proxy->peer);
|
||||||
if (n <= -1)
|
if (n <= -1)
|
||||||
@ -2452,7 +2454,7 @@ static int task_main_proxy (
|
|||||||
/* TODO: translate more error codes to http error codes... */
|
/* TODO: translate more error codes to http error codes... */
|
||||||
if (httpd->errnum == QSE_HTTPD_ENOENT) http_errnum = 404;
|
if (httpd->errnum == QSE_HTTPD_ENOENT) http_errnum = 404;
|
||||||
else if (httpd->errnum == QSE_HTTPD_EACCES ||
|
else if (httpd->errnum == QSE_HTTPD_EACCES ||
|
||||||
httpd->errnum == QSE_HTTPD_ECONN) http_errnum = 403;
|
httpd->errnum == QSE_HTTPD_ECONN) http_errnum = 403;
|
||||||
|
|
||||||
#if defined(QSE_HTTPD_DEBUG)
|
#if defined(QSE_HTTPD_DEBUG)
|
||||||
{
|
{
|
||||||
|
@ -964,66 +964,73 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
|
|||||||
{
|
{
|
||||||
/* TODO: logging. warning only */
|
/* TODO: logging. warning only */
|
||||||
/* this is not a hard failure */
|
/* this is not a hard failure */
|
||||||
HTTPD_DBGOUT1 ("Failed to enable SO_REUSERPORT on %zd\n", (qse_size_t)fd);
|
HTTPD_DBGOUT1 ("Failed to set SO_REUSERPORT on %zd\n", (qse_size_t)fd);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* TODO: linux. use capset() to set required capabilities just in case */
|
/* TODO: linux. use capset() to set required capabilities just in case */
|
||||||
|
if (server->dope.flags & QSE_HTTPD_SERVER_TRANSPARENT)
|
||||||
|
{
|
||||||
#if defined(IP_TRANSPARENT)
|
#if defined(IP_TRANSPARENT)
|
||||||
/* remove the ip routing restriction that a packet can only
|
/* remove the ip routing restriction that a packet can only
|
||||||
* be sent using a local ip address. this option is useful
|
* be sent using a local ip address. this option is useful
|
||||||
* if transparency is achieved with TPROXY */
|
* if transparency is achieved with TPROXY */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
1)
|
1)
|
||||||
ip rule add fwmark 0x1/0x1 lookup 100
|
ip rule add fwmark 0x1/0x1 lookup 100
|
||||||
ip route add local 0.0.0.0/0 dev lo table 100
|
ip route add local 0.0.0.0/0 dev lo table 100
|
||||||
|
|
||||||
2)
|
2)
|
||||||
iptables -t mangle -N DIVERT
|
iptables -t mangle -N DIVERT
|
||||||
iptables -t mangle -A DIVERT -j MARK --set-mark 0x1/0x1
|
iptables -t mangle -A DIVERT -j MARK --set-mark 0x1/0x1
|
||||||
iptables -t mangle -A DIVERT -j ACCEPT
|
iptables -t mangle -A DIVERT -j ACCEPT
|
||||||
iptables -t mangle -A PREROUTING -p tcp -m socket --transparent -j DIVERT
|
iptables -t mangle -A PREROUTING -p tcp -m socket --transparent -j DIVERT
|
||||||
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 8000
|
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 8000
|
||||||
|
|
||||||
3)
|
3)
|
||||||
iptables -t mangle -A PREROUTING -p tcp -m socket --transparent -j MARK --set-mark 0x1/0x1
|
iptables -t mangle -A PREROUTING -p tcp -m socket --transparent -j MARK --set-mark 0x1/0x1
|
||||||
iptables -t mangle -A PREROUTING -p tcp -m mark 0x1/0x1 -j RETURN
|
iptables -t mangle -A PREROUTING -p tcp -m mark 0x1/0x1 -j RETURN
|
||||||
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 8000
|
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 8000
|
||||||
|
|
||||||
4)
|
4)
|
||||||
iptables -t mangle -A PREROUTING -p tcp --sport 80 -j MARK --set-mark 0x1/0x1
|
iptables -t mangle -A PREROUTING -p tcp --sport 80 -j MARK --set-mark 0x1/0x1
|
||||||
iptables -t mangle -A PREROUTING -p tcp -m mark 0x1/0x1 -j RETURN
|
iptables -t mangle -A PREROUTING -p tcp -m mark 0x1/0x1 -j RETURN
|
||||||
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 8000
|
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 8000
|
||||||
|
|
||||||
|
|
||||||
1) is required.
|
1) is required.
|
||||||
one of 2), 3), 4), and a variant is needed.
|
one of 2), 3), 4), and a variant is needed.
|
||||||
Specifying -i and -o can narrow down the amount of packets when the upstream interface
|
Specifying -i and -o can narrow down the amount of packets when the upstream interface
|
||||||
and the downstream interface are obvious.
|
and the downstream interface are obvious.
|
||||||
|
|
||||||
If eth2 is an upstream and the eth1 is a downstream interface,
|
If eth2 is an upstream and the eth1 is a downstream interface,
|
||||||
iptables -t mangle -A PREROUTING -i eth2 -p tcp --sport 80 -j MARK --set-mark 0x1/0x1
|
iptables -t mangle -A PREROUTING -i eth2 -p tcp --sport 80 -j MARK --set-mark 0x1/0x1
|
||||||
iptables -t mangle -A PREROUTING -p tcp -m mark 0x1/0x1 -j RETURN
|
iptables -t mangle -A PREROUTING -p tcp -m mark 0x1/0x1 -j RETURN
|
||||||
iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 8000
|
iptables -t mangle -A PREROUTING -i eth1 -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 8000
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
if the socket is bound to 99.99.99.99:8000, you may do...
|
if the socket is bound to 99.99.99.99:8000, you may do...
|
||||||
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-ip 99.99.99.99 --on-port 8000
|
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-ip 99.99.99.99 --on-port 8000
|
||||||
|
|
||||||
iptables -t mangle -A PREROUTING -p tcp ! -s 127.0.0.0/255.0.0.0 --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-ip 0.0.0.0 --on-port 8000
|
iptables -t mangle -A PREROUTING -p tcp ! -s 127.0.0.0/255.0.0.0 --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-ip 0.0.0.0 --on-port 8000
|
||||||
|
|
||||||
IP_TRANSPRENT is needed for:
|
IP_TRANSPRENT is needed for:
|
||||||
- accepting TPROXYed connections
|
- accepting TPROXYed connections
|
||||||
- binding to a non-local IP address (IP address the local system doesn't have)
|
- binding to a non-local IP address (IP address the local system doesn't have)
|
||||||
- using a non-local IP address as a source
|
- using a non-local IP address as a source
|
||||||
-
|
*/
|
||||||
*/
|
flag = 1;
|
||||||
flag = 1;
|
if (setsockopt (fd, SOL_IP, IP_TRANSPARENT, &flag, QSE_SIZEOF(flag)) <= -1)
|
||||||
setsockopt (fd, SOL_IP, IP_TRANSPARENT, &flag, QSE_SIZEOF(flag));
|
{
|
||||||
|
/* TODO: logging. warning only */
|
||||||
|
/* this is not a hard failure */
|
||||||
|
HTTPD_DBGOUT1 ("Failed to set IP_TRANSPARENT on %zd\n", (qse_size_t)fd);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (server->dope.flags & QSE_HTTPD_SERVER_BINDTONWIF)
|
if (server->dope.flags & QSE_HTTPD_SERVER_BINDTONWIF)
|
||||||
{
|
{
|
||||||
@ -1032,11 +1039,10 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
|
|||||||
qse_size_t len;
|
qse_size_t len;
|
||||||
|
|
||||||
len = qse_nwifindextombs (server->dope.nwif, tmp, QSE_COUNTOF(tmp));
|
len = qse_nwifindextombs (server->dope.nwif, tmp, QSE_COUNTOF(tmp));
|
||||||
|
|
||||||
if (len <= 0 || setsockopt (fd, SOL_SOCKET, SO_BINDTODEVICE, tmp, len) <= -1)
|
if (len <= 0 || setsockopt (fd, SOL_SOCKET, SO_BINDTODEVICE, tmp, len) <= -1)
|
||||||
{
|
{
|
||||||
/* TODO: logging ... */
|
|
||||||
qse_httpd_seterrnum (httpd, ((len <= 0)? QSE_HTTPD_EINVAL: SKERR_TO_ERRNUM()));
|
qse_httpd_seterrnum (httpd, ((len <= 0)? QSE_HTTPD_EINVAL: SKERR_TO_ERRNUM()));
|
||||||
|
HTTPD_DBGOUT2 ("Failed to set SO_BINDTODEVICE to %hs on %zd\n", tmp, (qse_size_t)fd);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1294,7 +1300,6 @@ static int client_accepted (qse_httpd_t* httpd, qse_httpd_client_t* client)
|
|||||||
|
|
||||||
server_xtn = (server_xtn_t*)qse_httpd_getserverxtn (httpd, client->server);
|
server_xtn = (server_xtn_t*)qse_httpd_getserverxtn (httpd, client->server);
|
||||||
|
|
||||||
|
|
||||||
if (!server_xtn->ssl_ctx)
|
if (!server_xtn->ssl_ctx)
|
||||||
{
|
{
|
||||||
/* performed the delayed ssl initialization */
|
/* performed the delayed ssl initialization */
|
||||||
@ -1422,11 +1427,18 @@ static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: set transparent and bind only if the server is transparent */
|
if (peer->client && peer->client->server &&
|
||||||
|
(peer->client->server->dope.flags & QSE_HTTPD_SERVER_TRANSPARENT))
|
||||||
|
{
|
||||||
#if defined(IP_TRANSPARENT)
|
#if defined(IP_TRANSPARENT)
|
||||||
flag = 1;
|
flag = 1;
|
||||||
setsockopt (fd, SOL_IP, IP_TRANSPARENT, &flag, QSE_SIZEOF(flag));
|
if (setsockopt (fd, SOL_IP, IP_TRANSPARENT, &flag, QSE_SIZEOF(flag)) <= -1)
|
||||||
|
{
|
||||||
|
/* this is not a hard failure */
|
||||||
|
HTTPD_DBGOUT1 ("Failed to set IP_TRANSPARENT on peer socket %zd\n", (qse_size_t)fd);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* don't use invalid binding address */
|
/* don't use invalid binding address */
|
||||||
if (bindaddrsize >= 0 &&
|
if (bindaddrsize >= 0 &&
|
||||||
@ -3457,7 +3469,7 @@ static int query_server (
|
|||||||
{
|
{
|
||||||
case QSE_HTTPD_SERVERSTD_SSL:
|
case QSE_HTTPD_SERVERSTD_SSL:
|
||||||
/* you must specify the certificate and the key file to be able
|
/* you must specify the certificate and the key file to be able
|
||||||
* to use SSL */
|
* to use SSL. not supported by this sample implmentation. */
|
||||||
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOENT);
|
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOENT);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -822,7 +822,9 @@ static int accept_client (
|
|||||||
|
|
||||||
/* TODO: check maximum number of client. if exceed call client.close */
|
/* TODO: check maximum number of client. if exceed call client.close */
|
||||||
|
|
||||||
if (server->dope.flags & QSE_HTTPD_SERVER_SECURE) clibuf.status |= QSE_HTTPD_CLIENT_SECURE;
|
if (server->dope.flags & QSE_HTTPD_SERVER_SECURE)
|
||||||
|
clibuf.status |= QSE_HTTPD_CLIENT_SECURE;
|
||||||
|
|
||||||
clibuf.server = server;
|
clibuf.server = server;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user