mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
Merge branch '10267_plus_10896_rebased_twice'
This commit is contained in:
commit
973661394a
4
changes/10267_tproxy
Normal file
4
changes/10267_tproxy
Normal file
@ -0,0 +1,4 @@
|
||||
o Minor features:
|
||||
- Support the ipfw firewall interface for transparent proxy support on
|
||||
FreeBSD. To enable it, set "TransProxyType ipfw" in your torrc.
|
||||
Resolves ticket 10267; patch from "yurivict".
|
8
changes/10896
Normal file
8
changes/10896
Normal file
@ -0,0 +1,8 @@
|
||||
o Minor features:
|
||||
- Support OpenBSD's divert-to rules with the pf firewall, when
|
||||
"TransProxyType pf-divert" is specified. This allows Tor to run a
|
||||
TransPort transparent proxy port on OpenBSD 4.4 or later without
|
||||
root privileges. See the pf.conf(5) manual page for information on
|
||||
configuring pf to use divert-to rules. Closes ticket 10896; patch
|
||||
from Dana Koch.
|
||||
|
@ -1196,20 +1196,29 @@ The following options are useful only for clients (that is, if
|
||||
compatibility, TransListenAddress is only allowed when TransPort is just
|
||||
a port number.)
|
||||
|
||||
[[TransProxyType]] **TransProxyTYpe** **default**|**TPROXY**::
|
||||
[[TransProxyType]] **TransProxyTYpe** **default**|**TPROXY**|**ipfw**|**pf-divert**::
|
||||
TransProxyType may only be enabled when there is transparent proxy listener
|
||||
enabled.
|
||||
+
|
||||
Set this to TPROXY if you wish to be able to use the TPROXY Linux module to
|
||||
transparently proxy connections that are configured using the TransPort
|
||||
Set this to "TPROXY" if you wish to be able to use the TPROXY Linux module
|
||||
to transparently proxy connections that are configured using the TransPort
|
||||
option. This setting lets the listener on the TransPort accept connections
|
||||
for all addresses, even when the TransListenAddress is configured for an
|
||||
internal address. Detailed information on how to configure the TPROXY
|
||||
feature can be found in the Linux kernel source tree in the file
|
||||
Documentation/networking/tproxy.txt.
|
||||
+
|
||||
Set this option to "ipfw" to use the FreeBSD ipfw interface.
|
||||
+
|
||||
On *BSD operating systems when using pf, set this to "pf-divert" to take
|
||||
advantage of +divert-to+ rules, which do not modify the packets like
|
||||
+rdr-to+ rules do. Detailed information on how to configure pf to use
|
||||
+divert-to+ rules can be found in the pf.conf(5) manual page. On OpenBSD,
|
||||
+divert-to+ is available to use on versions greater than or equal to
|
||||
OpenBSD 4.4.
|
||||
+
|
||||
Set this to "default", or leave it unconfigured, to use regular IPTables
|
||||
on Linux, or to use pf on the *BSD operating systems.
|
||||
on Linux, or to use pf +rdr-to+ rules on *BSD systems.
|
||||
+
|
||||
(Default: "default".)
|
||||
|
||||
|
@ -1089,7 +1089,8 @@ options_act_reversible(const or_options_t *old_options, char **msg)
|
||||
|
||||
#if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
|
||||
/* Open /dev/pf before dropping privileges. */
|
||||
if (options->TransPort_set) {
|
||||
if (options->TransPort_set &&
|
||||
options->TransProxyType_parsed == TPT_DEFAULT) {
|
||||
if (get_pf_socket() < 0) {
|
||||
*msg = tor_strdup("Unable to open /dev/pf for transparent proxy.");
|
||||
goto rollback;
|
||||
@ -2553,11 +2554,23 @@ options_validate(or_options_t *old_options, or_options_t *options,
|
||||
if (options->TransProxyType) {
|
||||
if (!strcasecmp(options->TransProxyType, "default")) {
|
||||
options->TransProxyType_parsed = TPT_DEFAULT;
|
||||
} else if (!strcasecmp(options->TransProxyType, "pf-divert")) {
|
||||
#ifndef __OpenBSD__
|
||||
REJECT("pf-divert is a OpenBSD-specific feature.");
|
||||
#else
|
||||
options->TransProxyType_parsed = TPT_PF_DIVERT;
|
||||
#endif
|
||||
} else if (!strcasecmp(options->TransProxyType, "tproxy")) {
|
||||
#ifndef __linux__
|
||||
REJECT("TPROXY is a Linux-specific feature.");
|
||||
#else
|
||||
options->TransProxyType_parsed = TPT_TPROXY;
|
||||
#endif
|
||||
} else if (!strcasecmp(options->TransProxyType, "ipfw")) {
|
||||
#ifndef __FreeBSD__
|
||||
REJECT("ipfw is a FreeBSD-specific feature.");
|
||||
#else
|
||||
options->TransProxyType_parsed = TPT_IPFW;
|
||||
#endif
|
||||
} else {
|
||||
REJECT("Unrecognized value for TransProxyType");
|
||||
|
@ -1391,35 +1391,48 @@ get_pf_socket(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Fetch the original destination address and port from a
|
||||
* system-specific interface and put them into a
|
||||
* socks_request_t as if they came from a socks request.
|
||||
*
|
||||
* Return -1 if an error prevents fetching the destination,
|
||||
* else return 0.
|
||||
*/
|
||||
#if defined(TRANS_NETFILTER) || defined(TRANS_PF)
|
||||
/** Try fill in the address of <b>req</b> from the socket configured
|
||||
* with <b>conn</b>. */
|
||||
static int
|
||||
connection_ap_get_original_destination(entry_connection_t *conn,
|
||||
socks_request_t *req)
|
||||
destination_from_socket(entry_connection_t *conn, socks_request_t *req)
|
||||
{
|
||||
#ifdef TRANS_NETFILTER
|
||||
/* Linux 2.4+ */
|
||||
struct sockaddr_storage orig_dst;
|
||||
socklen_t orig_dst_len = sizeof(orig_dst);
|
||||
tor_addr_t addr;
|
||||
|
||||
#ifdef TRANS_NETFILTER
|
||||
if (getsockopt(ENTRY_TO_CONN(conn)->s, SOL_IP, SO_ORIGINAL_DST,
|
||||
(struct sockaddr*)&orig_dst, &orig_dst_len) < 0) {
|
||||
int e = tor_socket_errno(ENTRY_TO_CONN(conn)->s);
|
||||
log_warn(LD_NET, "getsockopt() failed: %s", tor_socket_strerror(e));
|
||||
return -1;
|
||||
}
|
||||
#elif defined(TRANS_PF)
|
||||
if (getsockname(ENTRY_TO_CONN(conn)->s, (struct sockaddr*)&orig_dst,
|
||||
&orig_dst_len) < 0) {
|
||||
int e = tor_socket_errno(ENTRY_TO_CONN(conn)->s);
|
||||
log_warn(LD_NET, "getsockname() failed: %s", tor_socket_strerror(e));
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
(void)conn;
|
||||
(void)req;
|
||||
log_warn(LD_BUG, "Unable to determine destination from socket.");
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
tor_addr_from_sockaddr(&addr, (struct sockaddr*)&orig_dst, &req->port);
|
||||
tor_addr_to_str(req->address, &addr, sizeof(req->address), 1);
|
||||
|
||||
return 0;
|
||||
#elif defined(TRANS_PF)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TRANS_PF
|
||||
static int
|
||||
destination_from_pf(entry_connection_t *conn, socks_request_t *req)
|
||||
{
|
||||
struct sockaddr_storage proxy_addr;
|
||||
socklen_t proxy_addr_len = sizeof(proxy_addr);
|
||||
struct sockaddr *proxy_sa = (struct sockaddr*) &proxy_addr;
|
||||
@ -1435,6 +1448,21 @@ connection_ap_get_original_destination(entry_connection_t *conn,
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if (get_options()->TransProxyType_parsed == TPT_IPFW) {
|
||||
/* ipfw(8) is used and in this case getsockname returned the original
|
||||
destination */
|
||||
if (tor_addr_from_sockaddr(&addr, proxy_sa, &req->port) < 0) {
|
||||
tor_fragile_assert();
|
||||
return -1;
|
||||
}
|
||||
|
||||
tor_addr_to_str(req->address, &addr, sizeof(req->address), 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(&pnl, 0, sizeof(pnl));
|
||||
pnl.proto = IPPROTO_TCP;
|
||||
pnl.direction = PF_OUT;
|
||||
@ -1481,6 +1509,36 @@ connection_ap_get_original_destination(entry_connection_t *conn,
|
||||
req->port = ntohs(pnl.rdport);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Fetch the original destination address and port from a
|
||||
* system-specific interface and put them into a
|
||||
* socks_request_t as if they came from a socks request.
|
||||
*
|
||||
* Return -1 if an error prevents fetching the destination,
|
||||
* else return 0.
|
||||
*/
|
||||
static int
|
||||
connection_ap_get_original_destination(entry_connection_t *conn,
|
||||
socks_request_t *req)
|
||||
{
|
||||
#ifdef TRANS_NETFILTER
|
||||
return destination_from_socket(conn, req);
|
||||
#elif defined(TRANS_PF)
|
||||
const or_options_t *options = get_options();
|
||||
|
||||
if (options->TransProxyType_parsed == TPT_PF_DIVERT)
|
||||
return destination_from_socket(conn, req);
|
||||
|
||||
if (options->TransProxyType_parsed == TPT_DEFAULT)
|
||||
return destination_from_pf(conn, req);
|
||||
|
||||
(void)conn;
|
||||
(void)req;
|
||||
log_warn(LD_BUG, "Proxy destination determination mechanism %s unknown.",
|
||||
options->TransProxyType);
|
||||
return -1;
|
||||
#else
|
||||
(void)conn;
|
||||
(void)req;
|
||||
|
@ -3473,7 +3473,12 @@ typedef struct {
|
||||
const char *TransProxyType; /**< What kind of transparent proxy
|
||||
* implementation are we using? */
|
||||
/** Parsed value of TransProxyType. */
|
||||
enum { TPT_DEFAULT, TPT_TPROXY } TransProxyType_parsed;
|
||||
enum {
|
||||
TPT_DEFAULT,
|
||||
TPT_PF_DIVERT,
|
||||
TPT_IPFW,
|
||||
TPT_TPROXY,
|
||||
} TransProxyType_parsed;
|
||||
config_line_t *NATDPort_lines; /**< Ports to listen on for transparent natd
|
||||
* connections. */
|
||||
config_line_t *ControlPort_lines; /**< Ports to listen on for control
|
||||
|
Loading…
Reference in New Issue
Block a user