Pārlūkot izejas kodu

Merge branch 'feature_10582'

Nick Mathewson 10 gadi atpakaļ
vecāks
revīzija
cac5949697
6 mainītis faili ar 60 papildinājumiem un 4 dzēšanām
  1. 7 0
      changes/10582_tproxy
  2. 13 0
      doc/tor.1.txt
  3. 8 0
      src/common/sandbox.c
  4. 15 4
      src/or/config.c
  5. 15 0
      src/or/connection.c
  6. 2 0
      src/or/or.h

+ 7 - 0
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.
+
+

+ 13 - 0
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.

+ 8 - 0
src/common/sandbox.c

@@ -475,6 +475,14 @@ sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter)
   if (rc)
     return rc;
 
+#ifdef IP_TRANSPARENT
+  rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 2,
+      SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP),
+      SCMP_CMP(2, SCMP_CMP_EQ, IP_TRANSPARENT));
+  if (rc)
+    return rc;
+#endif
+
   return 0;
 }
 

+ 15 - 4
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,20 @@ 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.");
+    }
+  }
+#else
+  if (options->TransPort_set || options->TransTPROXY)
+    REJECT("TransPort, TransListenAddress, and TransTPROXY are disabled "
+           "in this build.");
 #endif
 
   if (options->TokenBucketRefillInterval <= 0

+ 15 - 0
src/or/connection.c

@@ -1035,6 +1035,21 @@ 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) {
+        const char *extra = "";
+        int e = tor_socket_errno(s);
+        if (e == EPERM)
+          extra = "TransTPROXY requires root privileges or similar"
+            " capabilities.";
+        log_warn(LD_NET, "Error setting IP_TRANSPARENT flag: %s.%s",
+                 tor_socket_strerror(e), extra);
+      }
+    }
+#endif
+
 #ifdef IPV6_V6ONLY
     if (listensockaddr->sa_family == AF_INET6) {
 #ifdef _WIN32

+ 2 - 0
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