enhanced intercept handling in httpd

This commit is contained in:
hyung-hwan 2015-09-28 07:33:46 +00:00
parent 1f6fbd4f9f
commit 74ab14974b
5 changed files with 78 additions and 19 deletions

View File

@ -514,9 +514,17 @@ static int get_server_root (
{ {
root->type = QSE_HTTPD_SERVERSTD_ROOT_PROXY; root->type = QSE_HTTPD_SERVERSTD_ROOT_PROXY;
root->u.proxy.dst.nwad = qinfo->client->orgdst_addr; root->u.proxy.dst.nwad = qinfo->client->orgdst_addr;
/* if TPROXY is used, set the source to the original source. if (qse_nwadequal(&qinfo->client->orgdst_addr, &qinfo->client->local_addr))
root->u.proxy.src.nwad = qinfo->client->remote_addr; {
qse_setnwadport (&root->u.proxy.src.nwad, 0);*/ /* if the local address is the same as the original
* destination and INTERCEPTED is set, it's probably
* TPROXYed. if TPROXY is used, set the source to the
* original source. */
root->u.proxy.src.nwad = qinfo->client->remote_addr;
/* well, i don't keep the port number, though */
qse_setnwadport (&root->u.proxy.src.nwad, 0);
}
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;

View File

@ -777,6 +777,9 @@ struct qse_httpd_server_t
/* provided by a user for attaching */ /* provided by a user for attaching */
qse_httpd_server_dope_t dope; qse_httpd_server_dope_t dope;
/* actual binding address */
qse_nwad_t nwad;
/* set by server.open callback */ /* set by server.open callback */
qse_httpd_hnd_t handle; qse_httpd_hnd_t handle;

View File

@ -932,6 +932,7 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
qse_sck_hnd_t fd = QSE_INVALID_SCKHND, flag; qse_sck_hnd_t fd = QSE_INVALID_SCKHND, flag;
qse_skad_t addr; qse_skad_t addr;
int addrsize; int addrsize;
qse_sck_len_t addrlen;
addrsize = qse_nwadtoskad (&server->dope.nwad, &addr); addrsize = qse_nwadtoskad (&server->dope.nwad, &addr);
if (addrsize <= -1) if (addrsize <= -1)
@ -975,16 +976,38 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
* if transparency is achieved with TPROXY */ * if transparency is achieved with TPROXY */
/* /*
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)
iptables -t mangle -N DIVERT iptables -t mangle -N DIVERT
iptables -t mangle -A PREROUTING -p tcp -m socket --transparent -j 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 --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)
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 --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 8000
4)
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 --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 8000
1) is required.
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
and the downstream interface are obvious.
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 -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
---------------------------------------------------------------------- ----------------------------------------------------------------------
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...
@ -1038,6 +1061,19 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
} }
bind_ok: bind_ok:
server->nwad = server->dope.nwad;
addrlen = QSE_SIZEOF(addr);
if (getsockname (fd, (struct sockaddr*)&addr, &addrlen) >= 0)
{
qse_nwad_t tmpnwad;
if (qse_skadtonwad (&addr, &tmpnwad) >= 0)
{
/* this is the actual binding address */
server->nwad = tmpnwad;
}
}
if (listen (fd, 10) <= -1) if (listen (fd, 10) <= -1)
{ {
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
@ -1095,7 +1131,7 @@ static int server_accept (
if (qse_skadtonwad (&addr, &client->remote_addr) <= -1) if (qse_skadtonwad (&addr, &client->remote_addr) <= -1)
{ {
/* TODO: logging */ /* TODO: logging */
client->remote_addr = server->dope.nwad; client->remote_addr = server->nwad;
} }
addrlen = QSE_SIZEOF(addr); addrlen = QSE_SIZEOF(addr);
@ -1103,14 +1139,14 @@ static int server_accept (
qse_skadtonwad (&addr, &client->local_addr) <= -1) qse_skadtonwad (&addr, &client->local_addr) <= -1)
{ {
/* TODO: logging */ /* TODO: logging */
client->local_addr = server->dope.nwad; client->local_addr = server->nwad;
} }
#if defined(SO_ORIGINAL_DST) #if defined(SO_ORIGINAL_DST)
/* if REDIRECT is used, SO_ORIGINAL_DST returns the original /* if REDIRECT is used, SO_ORIGINAL_DST returns the original
* destination. If TPROXY is used, getsockname() above returns * destination address. When REDIRECT is not used, it returnes
* the original address. */ * the address of the local socket. In this case, it should
* be same as the result of getsockname(). */
addrlen = QSE_SIZEOF(addr); addrlen = QSE_SIZEOF(addr);
if (getsockopt (fd, SOL_IP, SO_ORIGINAL_DST, (char*)&addr, &addrlen) <= -1 || if (getsockopt (fd, SOL_IP, SO_ORIGINAL_DST, (char*)&addr, &addrlen) <= -1 ||
qse_skadtonwad (&addr, &client->orgdst_addr) <= -1) qse_skadtonwad (&addr, &client->orgdst_addr) <= -1)
@ -1121,16 +1157,27 @@ static int server_accept (
client->orgdst_addr = client->local_addr; client->orgdst_addr = client->local_addr;
#endif #endif
/* TODO: how to set intercepted when TPROXY is used? */
if (!qse_nwadequal(&client->orgdst_addr, &client->local_addr)) if (!qse_nwadequal(&client->orgdst_addr, &client->local_addr))
{
client->status |= QSE_HTTPD_CLIENT_INTERCEPTED; client->status |= QSE_HTTPD_CLIENT_INTERCEPTED;
}
else if (qse_getnwadport(&client->local_addr) !=
qse_getnwadport(&server->nwad))
{
/* When TPROXY is used, getsockname() and SO_ORIGNAL_DST return
* the same addresses. however, the port number may be different
* as a typical TPROXY rule is set to change the port number.
* However, this check is fragile if the server port number is
* set to 0. */
client->status |= QSE_HTTPD_CLIENT_INTERCEPTED;
}
#if 0 #if 0
client->initial_ifindex = resolve_ifindex (fd, client->local_addr); /* TODO: how to set intercepted when TPROXY is used? */
if (client->ifindex <= -1) else if ((client->initial_ifindex = resolve_ifindex (fd, client->local_addr)) <= -1)
{ {
/* the local_address is not one of a local address. /* the local_address is not one of a local address.
* it's probably proxied. */ * it's probably proxied. */
client->status |= QSE_HTTPD_CLIENT_INTERCEPTED;
} }
#endif #endif

View File

@ -869,7 +869,8 @@ static int accept_client (
qse_nwadtombs (&client->local_addr, tmp1, QSE_COUNTOF(tmp1), QSE_NWADTOMBS_ALL); qse_nwadtombs (&client->local_addr, tmp1, QSE_COUNTOF(tmp1), QSE_NWADTOMBS_ALL);
qse_nwadtombs (&client->orgdst_addr, tmp2, QSE_COUNTOF(tmp2), QSE_NWADTOMBS_ALL); qse_nwadtombs (&client->orgdst_addr, tmp2, QSE_COUNTOF(tmp2), QSE_NWADTOMBS_ALL);
qse_nwadtombs (&client->remote_addr, tmp3, QSE_COUNTOF(tmp3), QSE_NWADTOMBS_ALL); qse_nwadtombs (&client->remote_addr, tmp3, QSE_COUNTOF(tmp3), QSE_NWADTOMBS_ALL);
HTTPD_DBGOUT3 ("Accepted client %hs(%hs) from %hs\n", tmp1, tmp2, tmp3); HTTPD_DBGOUT5 ("Accepted client %hs(%hs) on %zd from %hs - %zd\n",
tmp1, tmp2, (qse_size_t)server->handle, tmp3, (qse_size_t)client->handle);
} }
#endif #endif
} }
@ -973,9 +974,10 @@ static int activate_servers (qse_httpd_t* httpd)
{ {
#if defined(QSE_HTTPD_DEBUG) #if defined(QSE_HTTPD_DEBUG)
{ {
qse_mchar_t tmp[128]; qse_mchar_t tmp[128], tmp2[128];
qse_nwadtombs (&server->dope.nwad, tmp, QSE_COUNTOF(tmp), QSE_NWADTOMBS_ALL); qse_nwadtombs (&server->dope.nwad, tmp, QSE_COUNTOF(tmp), QSE_NWADTOMBS_ALL);
HTTPD_DBGOUT2 ("Opened server [%hs] - %zd\n", tmp, (qse_size_t)server->handle); qse_nwadtombs (&server->nwad, tmp2, QSE_COUNTOF(tmp2), QSE_NWADTOMBS_ALL);
HTTPD_DBGOUT3 ("Opened server [%hs] actual address [%hs] - %zd\n", tmp, tmp2, (qse_size_t)server->handle);
} }
#endif #endif
} }

View File

@ -153,8 +153,7 @@ int qse_mtx_lock (qse_mtx_t* mtx)
* state is nonsignaled. * state is nonsignaled.
* WAIT_FAILED An error occurred * WAIT_FAILED An error occurred
*/ */
if (WaitForSingleObject ( if (WaitForSingleObject (mtx->hnd, INFINITE) == WAIT_FAILED)
mtx->hnd, INFINITE) == WAIT_FAILED)
{ {
qse_seterrno (qse_maperrno(GetLastError())); qse_seterrno (qse_maperrno(GetLastError()));
return -1; return -1;