ExitPolicy accept6/reject6 produces IPv6 wildcard addresses only

In previous versions of Tor, ExitPolicy accept6/reject6 * produced
policy entries for IPv4 and IPv6 wildcard addresses.

To reduce operator confusion, change accept6/reject6 * to only produce
an IPv6 wildcard address.

Resolves bug #16069.

Patch on 2eb7eafc9d and a96c0affcb (25 Oct 2012),
released in 0.2.4.7-alpha.
This commit is contained in:
teor (Tim Wilson-Brown) 2015-09-14 11:46:58 +10:00
parent 36ad8d8fdc
commit d3358a0a05
8 changed files with 126 additions and 30 deletions

View File

@ -1,4 +1,6 @@
o Minor bug fixes (torrc exit policies):
- accept6/reject6 * lines only produce IPv6 wildcard addresses,
previously they would produce both IPv4 and IPv6 wildcard addresses.
- When parsing torrc ExitPolicies, we now warn if:
* an IPv4 address is used on an accept6 or reject6 line. The line is
ignored, but the rest of the policy items in the list are used.
@ -13,6 +15,6 @@
* when expanding an accept/reject * line to include both IPv4 and IPv6
wildcard addresses.
- In each instance, usage advice is provided to avoid the message.
Partial fix for ticket 16069. Patch by "teor".
Resolves ticket 16069. Patch by "teor".
Patch on 2eb7eafc9d78 and a96c0affcb4c (25 Oct 2012),
released in 0.2.4.7-alpha.

View File

@ -1537,12 +1537,26 @@ is non-zero):
"\*". +
+
For example, "accept 18.7.22.69:\*,reject 18.0.0.0/8:\*,accept \*:\*" would
reject any traffic destined for MIT except for web.mit.edu, and accept
anything else. +
reject any IPv4 traffic destined for MIT except for web.mit.edu, and accept
any other IPv4 or IPv6 traffic. +
+
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
172.16.0.0/12), you can use the "private" alias instead of an address.
Tor also allows IPv6 exit policy entries. For instance, "reject6 [FC00::]/7:*"
rejects all destinations that share 7 most significant bit prefix with
address FC00::. Respectively, "accept6 [C000::]/3:*" accepts all destinations
that share 3 most significant bit prefix with address C000::. +
+
accept6 and reject6 only produce IPv6 exit policy entries. Using an IPv4
address with accept6 or reject6 is ignored and generates a warning.
accept/reject allows either IPv4 or IPv6 addresses. Use *4 as an IPv4
wildcard address, and *6 as an IPv6 wildcard address. accept/reject *
expands to matching IPv4 and IPv6 wildcard address rules. +
+
To specify all IPv4 and IPv6 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,
172.16.0.0/12, [::]/8, [FC00::]/7, [FE80::]/10, [FEC0::]/10, [FF00::]/8,
and [::]/127), you can use the "private" alias instead of an address.
("private" always produces rules for IPv4 and IPv6 addresses, even when
used with accept6/reject6.)
These addresses are rejected by default (at the beginning of your exit
policy), along with your public IP address, unless you set the
ExitPolicyRejectPrivate config option to 0. For example, once you've done
@ -1551,11 +1565,6 @@ is non-zero):
may also allow 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. +
+
Tor also allow IPv6 exit policy entries. For instance, "reject6 [FC00::]/7:*"
rejects all destinations that share 7 most significant bit prefix with
address FC00::. Respectively, "accept6 [C000::]/3:*" accepts all destinations
that share 3 most significant bit prefix with address C000::. +
+
This directive can be specified multiple times so you don't have to put it
all on one line. +
@ -1577,6 +1586,9 @@ is non-zero):
reject *:6881-6999
accept *:*
Since the default exit policy uses accept/reject *, it applies to both
IPv4 and IPv6 addresses.
[[ExitPolicyRejectPrivate]] **ExitPolicyRejectPrivate** **0**|**1**::
Reject all private (local) networks, along with your own public IP address,
at the beginning of your exit policy. See above entry on ExitPolicy.

View File

@ -620,13 +620,20 @@ tor_addr_to_PTR_name(char *out, size_t outlen,
* yield an IPv4 wildcard.
*
* If 'flags & TAPMP_EXTENDED_STAR' is true, then the wildcard address '*'
* yields an AF_UNSPEC wildcard address, and the following change is made
* yields an AF_UNSPEC wildcard address, which expands to corresponding
* wildcard IPv4 and IPv6 rules, and the following change is made
* in the grammar above:
* Address ::= IPv4Address / "[" IPv6Address "]" / "*" / "*4" / "*6"
* with the new "*4" and "*6" productions creating a wildcard to match
* IPv4 or IPv6 addresses.
*
*/
* If 'flags & TAPMP_EXTENDED_STAR' and 'flags & TAPMP_STAR_IPV4_ONLY' are
* both true, then the wildcard address '*' yields an IPv4 wildcard.
*
* If 'flags & TAPMP_EXTENDED_STAR' and 'flags & TAPMP_STAR_IPV6_ONLY' are
* both true, then the wildcard address '*' yields an IPv6 wildcard.
*
* TAPMP_STAR_IPV4_ONLY and TAPMP_STAR_IPV6_ONLY are mutually exclusive. */
int
tor_addr_parse_mask_ports(const char *s,
unsigned flags,
@ -643,6 +650,10 @@ tor_addr_parse_mask_ports(const char *s,
tor_assert(s);
tor_assert(addr_out);
/* We can either only want an IPv4 address or only want an IPv6 address,
* but we can't only want IPv4 & IPv6 at the same time. */
tor_assert(!((flags & TAPMP_STAR_IPV4_ONLY)
&& (flags & TAPMP_STAR_IPV6_ONLY)));
/** Longest possible length for an address, mask, and port-range combination.
* Includes IP, [], /mask, :, ports */
@ -688,12 +699,21 @@ tor_addr_parse_mask_ports(const char *s,
if (!strcmp(address, "*")) {
if (flags & TAPMP_EXTENDED_STAR) {
if (flags & TAPMP_STAR_IPV4_ONLY) {
family = AF_INET;
tor_addr_from_ipv4h(addr_out, 0);
} else if (flags & TAPMP_STAR_IPV6_ONLY) {
static char nil_bytes[16] = { [0]=0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 };
family = AF_INET6;
tor_addr_from_ipv6_bytes(addr_out, nil_bytes);
} else {
family = AF_UNSPEC;
tor_addr_make_unspec(addr_out);
log_info(LD_GENERAL,
"'%s' expands into rules which apply to all IPv4 and IPv6 "
"addresses. (Use accept/reject *4:* for IPv4 or "
"accept[6]/reject[6] *6:* for IPv6.)", s);
}
} else {
family = AF_INET;
tor_addr_from_ipv4h(addr_out, 0);

View File

@ -227,10 +227,19 @@ int tor_addr_parse_PTR_name(tor_addr_t *result, const char *address,
int tor_addr_port_lookup(const char *s, tor_addr_t *addr_out,
uint16_t *port_out);
/* Does the address * yield an AF_UNSPEC wildcard address (1) and do we
/* Does the address * yield an AF_UNSPEC wildcard address (1),
* which expands to corresponding wildcard IPv4 and IPv6 rules, and do we
* allow *4 and *6 for IPv4 and IPv6 wildcards, respectively;
* or does the address * yield IPv4 wildcard address (0). */
#define TAPMP_EXTENDED_STAR 1
/* Does the address * yield an IPv4 wildcard address rule (1);
* or does it yield wildcard IPv4 and IPv6 rules (0) */
#define TAPMP_STAR_IPV4_ONLY (1 << 1)
/* Does the address * yield an IPv6 wildcard address rule (1);
* or does it yield wildcard IPv4 and IPv6 rules (0) */
#define TAPMP_STAR_IPV6_ONLY (1 << 2)
/* TAPMP_STAR_IPV4_ONLY and TAPMP_STAR_IPV6_ONLY are mutually exclusive. */
int tor_addr_parse_mask_ports(const char *s, unsigned flags,
tor_addr_t *addr_out, maskbits_t *mask_out,
uint16_t *port_min_out, uint16_t *port_max_out);

View File

@ -1,5 +1,5 @@
## Configuration file for a typical Tor user
## Last updated 2 September 2014 for Tor 0.2.6.1-alpha.
## Last updated 11 September 2015 for Tor 0.2.7.3-alpha.
## (may or may not work for much older or much newer versions of Tor.)
##
## Lines that begin with "## " try to explain what's going on. Lines
@ -24,6 +24,7 @@
## can access your SocksPort may be able to learn about the connections
## you make.
#SocksPolicy accept 192.168.0.0/16
#SocksPolicy accept6 FC00::/7
#SocksPolicy reject *
## Logs go to stdout at level "notice" unless redirected by something
@ -174,8 +175,10 @@
## networks, including to your public IP address. See the man page entry
## for ExitPolicyRejectPrivate if you want to allow "exit enclaving".
##
#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports but no more
#ExitPolicy accept *:119 # accept nntp as well as default exit policy
#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports on IPv4 and IPv6 but no more
#ExitPolicy accept *:119 # accept nntp ports on IPv4 and IPv6 as well as default exit policy
#ExitPolicy accept *4:119 # accept nntp ports on IPv4 only as well as default exit policy
#ExitPolicy accept6 *6:119 # accept nntp ports on IPv6 only as well as default exit policy
#ExitPolicy reject *:* # no exits allowed
## Bridge relays (or "bridges") are Tor relays that aren't listed in the

View File

@ -1,5 +1,5 @@
## Configuration file for a typical Tor user
## Last updated 2 September 2014 for Tor 0.2.6.1-alpha.
## Last updated 11 September 2015 for Tor 0.2.7.3-alpha.
## (may or may not work for much older or much newer versions of Tor.)
##
## Lines that begin with "## " try to explain what's going on. Lines
@ -24,6 +24,7 @@
## can access your SocksPort may be able to learn about the connections
## you make.
#SocksPolicy accept 192.168.0.0/16
#SocksPolicy accept6 FC00::/7
#SocksPolicy reject *
## Logs go to stdout at level "notice" unless redirected by something
@ -174,8 +175,10 @@
## networks, including to your public IP address. See the man page entry
## for ExitPolicyRejectPrivate if you want to allow "exit enclaving".
##
#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports but no more
#ExitPolicy accept *:119 # accept nntp as well as default exit policy
#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports on IPv4 and IPv6 but no more
#ExitPolicy accept *:119 # accept nntp ports on IPv4 and IPv6 as well as default exit policy
#ExitPolicy accept *4:119 # accept nntp ports on IPv4 only as well as default exit policy
#ExitPolicy accept6 *6:119 # accept nntp ports on IPv6 only as well as default exit policy
#ExitPolicy reject *:* # no exits allowed
## Bridge relays (or "bridges") are Tor relays that aren't listed in the

View File

@ -3820,6 +3820,12 @@ router_parse_addr_policy(directory_token_t *tok, unsigned fmt_flags)
else
newe.policy_type = ADDR_POLICY_ACCEPT;
/* accept6/reject6 * produces an IPv6 wildcard address only.
* (accept/reject * produces rules for IPv4 and IPv6 wildcard addresses.) */
if (tok->tp == K_ACCEPT6 || tok->tp == K_REJECT6) {
fmt_flags |= TAPMP_STAR_IPV6_ONLY;
}
if (tor_addr_parse_mask_ports(arg, fmt_flags, &newe.addr, &newe.maskbits,
&newe.prt_min, &newe.prt_max) < 0) {
log_warn(LD_DIR,"Couldn't parse line %s. Dropping", escaped(arg));
@ -3829,9 +3835,12 @@ router_parse_addr_policy(directory_token_t *tok, unsigned fmt_flags)
return addr_policy_get_canonical_entry(&newe);
}
/** Parse an exit policy line of the format "accept/reject private:...".
/** Parse an exit policy line of the format "accept[6]/reject[6] private:...".
* This didn't exist until Tor 0.1.1.15, so nobody should generate it in
* router descriptors until earlier versions are obsolete.
*
* accept/reject and accept6/reject6 private all produce rules for both
* IPv4 and IPv6 addresses.
*/
static addr_policy_t *
router_parse_addr_policy_private(directory_token_t *tok)

View File

@ -77,7 +77,8 @@ test_policies_general(void *arg)
int i;
smartlist_t *policy = NULL, *policy2 = NULL, *policy3 = NULL,
*policy4 = NULL, *policy5 = NULL, *policy6 = NULL,
*policy7 = NULL;
*policy7 = NULL, *policy8 = NULL, *policy9 = NULL,
*policy10 = NULL, *policy11 = NULL;
addr_policy_t *p;
tor_addr_t tar;
config_line_t line;
@ -192,6 +193,30 @@ test_policies_general(void *arg)
tt_assert(p != NULL);
smartlist_add(policy7, p);
tt_int_op(0, OP_EQ, policies_parse_exit_policy(NULL, &policy8,
EXIT_POLICY_IPV6_ENABLED |
EXIT_POLICY_REJECT_PRIVATE |
EXIT_POLICY_ADD_DEFAULT, 0));
tt_assert(policy8);
tt_int_op(0, OP_EQ, policies_parse_exit_policy(NULL, &policy9,
EXIT_POLICY_REJECT_PRIVATE |
EXIT_POLICY_ADD_DEFAULT, 0));
tt_assert(policy9);
/* accept6 * and reject6 * produce IPv6 wildcards only */
policy10 = smartlist_new();
p = router_parse_addr_policy_item_from_string("accept6 *:*",-1);
tt_assert(p != NULL);
smartlist_add(policy10, p);
policy11 = smartlist_new();
p = router_parse_addr_policy_item_from_string("reject6 *:*",-1);
tt_assert(p != NULL);
smartlist_add(policy11, p);
tt_assert(!exit_policy_is_general_exit(policy));
tt_assert(exit_policy_is_general_exit(policy2));
tt_assert(!exit_policy_is_general_exit(NULL));
@ -200,6 +225,10 @@ test_policies_general(void *arg)
tt_assert(!exit_policy_is_general_exit(policy5));
tt_assert(!exit_policy_is_general_exit(policy6));
tt_assert(!exit_policy_is_general_exit(policy7));
tt_assert(exit_policy_is_general_exit(policy8));
tt_assert(exit_policy_is_general_exit(policy9));
tt_assert(!exit_policy_is_general_exit(policy10));
tt_assert(!exit_policy_is_general_exit(policy11));
tt_assert(cmp_addr_policies(policy, policy2));
tt_assert(cmp_addr_policies(policy, NULL));
@ -208,7 +237,12 @@ test_policies_general(void *arg)
tt_assert(!policy_is_reject_star(policy2, AF_INET));
tt_assert(policy_is_reject_star(policy, AF_INET));
tt_assert(policy_is_reject_star(policy10, AF_INET));
tt_assert(!policy_is_reject_star(policy10, AF_INET6));
tt_assert(policy_is_reject_star(policy11, AF_INET));
tt_assert(policy_is_reject_star(policy11, AF_INET6));
tt_assert(policy_is_reject_star(NULL, AF_INET));
tt_assert(policy_is_reject_star(NULL, AF_INET6));
addr_policy_list_free(policy);
policy = NULL;
@ -219,13 +253,13 @@ test_policies_general(void *arg)
line.value = (char*)"accept *:80,reject private:*,reject *:*";
line.next = NULL;
tt_int_op(0, OP_EQ, policies_parse_exit_policy(&line,&policy,
EXIT_POLICY_IPV6_ENABLED |
~EXIT_POLICY_IPV6_ENABLED |
EXIT_POLICY_ADD_DEFAULT,0));
tt_assert(policy);
//test_streq(policy->string, "accept *:80");
//test_streq(policy->next->string, "reject *:*");
tt_int_op(smartlist_len(policy),OP_EQ, 4);
tt_int_op(smartlist_len(policy),OP_EQ, 9);
/* test policy summaries */
/* check if we properly ignore private IP addresses */
@ -427,6 +461,10 @@ test_policies_general(void *arg)
addr_policy_list_free(policy5);
addr_policy_list_free(policy6);
addr_policy_list_free(policy7);
addr_policy_list_free(policy8);
addr_policy_list_free(policy9);
addr_policy_list_free(policy10);
addr_policy_list_free(policy11);
tor_free(policy_str);
if (sm) {
SMARTLIST_FOREACH(sm, char *, s, tor_free(s));