Browse Source

Exit policies now reject connections that are addressed to a
relay's public (external) IP address too, unless
ExitPolicyRejectPrivate is turned off. We do this because too
many relays are running nearby to services that trust them based
on network address.


svn:r12459

Roger Dingledine 17 years ago
parent
commit
42b8fb5a15
6 changed files with 28 additions and 13 deletions
  1. 6 0
      ChangeLog
  2. 7 4
      doc/tor.1.in
  3. 2 3
      src/or/or.h
  4. 9 3
      src/or/policies.c
  5. 2 1
      src/or/router.c
  6. 2 2
      src/or/test.c

+ 6 - 0
ChangeLog

@@ -1,4 +1,10 @@
 Changes in version 0.2.0.11-alpha - 2007-11-??
 Changes in version 0.2.0.11-alpha - 2007-11-??
+  o Security fixes:
+    - Exit policies now reject connections that are addressed to a
+      relay's public (external) IP address too, unless
+      ExitPolicyRejectPrivate is turned off. We do this because too
+      many relays are running nearby to services that trust them based
+      on network address.
 
 
 
 
 Changes in version 0.2.0.10-alpha - 2007-11-10
 Changes in version 0.2.0.10-alpha - 2007-11-10

+ 7 - 4
doc/tor.1.in

@@ -739,11 +739,13 @@ To specify all internal and link-local networks (including 0.0.0.0/8,
 169.254.0.0/16, 127.0.0.0/8, 192.168.0.0/16, 10.0.0.0/8, and
 169.254.0.0/16, 127.0.0.0/8, 192.168.0.0/16, 10.0.0.0/8, and
 172.16.0.0/12), you can use the "private" alias instead of an address.
 172.16.0.0/12), you can use the "private" alias instead of an address.
 These addresses are rejected by default (at the beginning of your
 These addresses are rejected by default (at the beginning of your
-exit policy) unless you set the ExitPolicyRejectPrivate config option
+exit policy), along with your public IP address, unless you set the
+ExitPolicyRejectPrivate config option
 to 0. For example, once you've done that, you could allow HTTP to
 to 0. For example, once you've done that, you could allow HTTP to
 127.0.0.1 and block all other connections to internal networks with
 127.0.0.1 and block all other connections to internal networks with
-"accept
+"accept 127.0.0.1:80,reject private:*", though that may also allow
-127.0.0.1:80,reject private:*".  See RFC 1918 and RFC 3330 for more
+connections to your own computer that are addressed to its public
+(external) IP address. See RFC 1918 and RFC 3330 for more
 details about internal and reserved IP address space.
 details about internal and reserved IP address space.
 
 
 This directive can be specified multiple times so you don't have to put
 This directive can be specified multiple times so you don't have to put
@@ -773,7 +775,8 @@ either a reject *:* or an accept *:*. Otherwise, you're _augmenting_
 .LP
 .LP
 .TP
 .TP
 \fBExitPolicyRejectPrivate \fR\fB0\fR|\fB1\fR\fP
 \fBExitPolicyRejectPrivate \fR\fB0\fR|\fB1\fR\fP
-Reject all private (local) networks at the beginning of your exit
+Reject all private (local) networks, along with your own public IP
+address, at the beginning of your exit
 policy. See above entry on ExitPolicy. (Default: 1)
 policy. See above entry on ExitPolicy. (Default: 1)
 .LP
 .LP
 .TP
 .TP

+ 2 - 3
src/or/or.h

@@ -3356,9 +3356,8 @@ void policies_parse_from_options(or_options_t *options);
 int cmp_addr_policies(addr_policy_t *a, addr_policy_t *b);
 int cmp_addr_policies(addr_policy_t *a, addr_policy_t *b);
 addr_policy_result_t compare_addr_to_addr_policy(uint32_t addr,
 addr_policy_result_t compare_addr_to_addr_policy(uint32_t addr,
                               uint16_t port, addr_policy_t *policy);
                               uint16_t port, addr_policy_t *policy);
-int policies_parse_exit_policy(config_line_t *cfg,
+int policies_parse_exit_policy(config_line_t *cfg, addr_policy_t **dest,
-                               addr_policy_t **dest,
+                               int rejectprivate, const char *local_address);
-                               int rejectprivate);
 int exit_policy_is_general_exit(addr_policy_t *policy);
 int exit_policy_is_general_exit(addr_policy_t *policy);
 int policy_is_reject_star(addr_policy_t *policy);
 int policy_is_reject_star(addr_policy_t *policy);
 int getinfo_helper_policies(control_connection_t *conn,
 int getinfo_helper_policies(control_connection_t *conn,

+ 9 - 3
src/or/policies.c

@@ -228,7 +228,7 @@ validate_addr_policies(or_options_t *options, char **msg)
   *msg = NULL;
   *msg = NULL;
 
 
   if (policies_parse_exit_policy(options->ExitPolicy, &addr_policy,
   if (policies_parse_exit_policy(options->ExitPolicy, &addr_policy,
-                                 options->ExitPolicyRejectPrivate))
+                                 options->ExitPolicyRejectPrivate, NULL))
     REJECT("Error in ExitPolicy entry.");
     REJECT("Error in ExitPolicy entry.");
 
 
   /* The rest of these calls *append* to addr_policy. So don't actually
   /* The rest of these calls *append* to addr_policy. So don't actually
@@ -556,10 +556,16 @@ exit_policy_remove_redundancies(addr_policy_t **dest)
  */
  */
 int
 int
 policies_parse_exit_policy(config_line_t *cfg, addr_policy_t **dest,
 policies_parse_exit_policy(config_line_t *cfg, addr_policy_t **dest,
-                           int rejectprivate)
+                           int rejectprivate, const char *local_address)
 {
 {
-  if (rejectprivate)
+  if (rejectprivate) {
     append_exit_policy_string(dest, "reject private:*");
     append_exit_policy_string(dest, "reject private:*");
+    if (local_address) {
+      char buf[POLICY_BUF_LEN];
+      tor_snprintf(buf, sizeof(buf), "reject %s:*", local_address);
+      append_exit_policy_string(dest, buf);
+    }
+  }
   if (parse_addr_policy(cfg, dest, -1))
   if (parse_addr_policy(cfg, dest, -1))
     return -1;
     return -1;
   append_exit_policy_string(dest, DEFAULT_EXIT_POLICY);
   append_exit_policy_string(dest, DEFAULT_EXIT_POLICY);

+ 2 - 1
src/or/router.c

@@ -1215,7 +1215,8 @@ router_rebuild_descriptor(int force)
   ri->bandwidthcapacity = hibernating ? 0 : rep_hist_bandwidth_assess();
   ri->bandwidthcapacity = hibernating ? 0 : rep_hist_bandwidth_assess();
 
 
   policies_parse_exit_policy(options->ExitPolicy, &ri->exit_policy,
   policies_parse_exit_policy(options->ExitPolicy, &ri->exit_policy,
-                             options->ExitPolicyRejectPrivate);
+                             options->ExitPolicyRejectPrivate,
+                             ri->address);
 
 
   if (desc_routerinfo) { /* inherit values */
   if (desc_routerinfo) { /* inherit values */
     ri->is_valid = desc_routerinfo->is_valid;
     ri->is_valid = desc_routerinfo->is_valid;

+ 2 - 2
src/or/test.c

@@ -2935,7 +2935,7 @@ test_policies(void)
           compare_addr_to_addr_policy(0xc0a80102, 2, policy));
           compare_addr_to_addr_policy(0xc0a80102, 2, policy));
 
 
   policy2 = NULL;
   policy2 = NULL;
-  test_assert(0 == policies_parse_exit_policy(NULL, &policy2, 1));
+  test_assert(0 == policies_parse_exit_policy(NULL, &policy2, 1, NULL));
   test_assert(policy2);
   test_assert(policy2);
 
 
   test_assert(!exit_policy_is_general_exit(policy));
   test_assert(!exit_policy_is_general_exit(policy));
@@ -2955,7 +2955,7 @@ test_policies(void)
   line.key = (char*)"foo";
   line.key = (char*)"foo";
   line.value = (char*)"accept *:80,reject private:*,reject *:*";
   line.value = (char*)"accept *:80,reject private:*,reject *:*";
   line.next = NULL;
   line.next = NULL;
-  test_assert(0 == policies_parse_exit_policy(&line, &policy, 0));
+  test_assert(0 == policies_parse_exit_policy(&line, &policy, 0, NULL));
   test_assert(policy);
   test_assert(policy);
   test_streq(policy->string, "accept *:80");
   test_streq(policy->string, "accept *:80");
   test_streq(policy->next->string, "reject *:*");
   test_streq(policy->next->string, "reject *:*");