commit 09ccc4c4a3b67695295ad95f24b2f102d5f2fa1a
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Jan 31 12:59:35 2014 -0500
Add support for TPROXY via new TransTPRoxy option
Based on patch from "thomo" at #10582.
---
changes/10582_tproxy | 7 +++++++
doc/tor.1.txt | 13 +++++++++++++
src/or/config.c | 26 ++++++++++++++++++++++----
src/or/connection.c | 11 +++++++++++
src/or/or.h | 2 ++
5 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/changes/10582_tproxy b/changes/10582_tproxy
new file mode 100644
index 0000000..3609d56
--- /dev/null
+++ b/changes/10582_tproxy
@@ -0,0 +1,7 @@
+ o Minor features:
+
+ - Add support for the TPROXY transparent proxying facility on Linux.
+ See documentation for the new TransTRPOXY option for more details.
+ Implementation by "thomo". Closes ticket 10582.
+
+
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index 28e7c5d..69452a0 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -1183,6 +1183,19 @@ The following options are useful only for clients (that is, if
compatibility, TransListenAddress is only allowed when TransPort is just
a port number.)
+[[TransTPROXY]] **TransTPROXY** **0**|**1**::
+ TransTPROXY may only be enabled when there is transparent proxy listener
+ enabled and only for Linux.
+ +
+ Set this 1 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.
+ (Default: 0)
+
[[NATDPort]] **NATDPort** \['address':]__port__|**auto** [_isolation flags_]::
Open this port to listen for connections from old versions of ipfw (as
included in old versions of FreeBSD, etc) using the NATD protocol.
diff --git a/src/or/config.c b/src/or/config.c
index d348f10..a2366c0 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -408,6 +408,7 @@ static config_var_t option_vars_[] = {
OBSOLETE("TrafficShaping"),
V(TransListenAddress, LINELIST, NULL),
VPORT(TransPort, LINELIST, NULL),
+ V(TransTPROXY, BOOL, "0"),
V(TunnelDirConns, BOOL, "1"),
V(UpdateBridgesFromAuthority, BOOL, "0"),
V(UseBridges, BOOL, "0"),
@@ -2530,10 +2531,27 @@ options_validate(or_options_t *old_options, or_options_t *options,
"undefined, and there aren't any hidden services configured. "
"Tor will still run, but probably won't do anything.");
-#ifndef USE_TRANSPARENT
- /* XXXX024 I think we can remove this TransListenAddress */
- if (options->TransPort_set || options->TransListenAddress)
- REJECT("TransPort and TransListenAddress are disabled in this build.");
+#ifdef USE_TRANSPARENT
+ if (options->TransTPROXY) {
+#ifndef __linux__
+ REJECT("TransTPROXY is a Linux-specific feature.")
+#endif
+ if (!options->TransPort_set) {
+ REJECT("Cannot use TransTPROXY without any valid TransPort or "
+ "TransListenAddress.");
+ }
+ /* Friendly suggestion about running as root initially. */
+ if (!options->User) {
+ log_warn(LD_CONFIG,
+ "You have enabled TransTPROXY but have not specified the "
+ "\"User\" option. TransTPROXY will not function without "
+ "root privileges.");
+ }
+ }
+#else
+ if (options->TransPort_set || options->TransTPROXY)
+ REJECT("TransPort, TransListenAddress, and TransTPROXY are disabled "
+ "in this build.");
#endif
if (options->TokenBucketRefillInterval <= 0
diff --git a/src/or/connection.c b/src/or/connection.c
index 1f6e11f..7d8feeb 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -1035,6 +1035,17 @@ connection_listener_new(const struct sockaddr *listensockaddr,
make_socket_reuseable(s);
+#if defined USE_TRANSPARENT && defined(IP_TRANSPARENT)
+ if (options->TransTPROXY && type == CONN_TYPE_AP_TRANS_LISTENER) {
+ int one = 1;
+ if (setsockopt(s, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) < 0) {
+ int e = tor_socket_errno(s);
+ log_warn(LD_NET, "Error setting IP_TRANSPARENT flag: %s",
+ tor_socket_strerror(e));
+ }
+ }
+#endif
+
#ifdef IPV6_V6ONLY
if (listensockaddr->sa_family == AF_INET6) {
#ifdef _WIN32
diff --git a/src/or/or.h b/src/or/or.h
index 7df6c37..55f2862 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -3553,6 +3553,8 @@ typedef struct {
config_line_t *SocksPort_lines;
/** Ports to listen on for transparent pf/netfilter connections. */
config_line_t *TransPort_lines;
+ int TransTPROXY; /** < Boolean: are we going to listen for all destinations
+ * on the TransPort_lines are required for TPROXY? */
config_line_t *NATDPort_lines; /**< Ports to listen on for transparent natd
* connections. */
config_line_t *ControlPort_lines; /**< Ports to listen on for control