mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 13:13:44 +01:00
Merge remote-tracking branch 'teor/bug18456'
This commit is contained in:
commit
78196c8822
6
changes/bug18456
Normal file
6
changes/bug18456
Normal file
@ -0,0 +1,6 @@
|
||||
o Major bugfixes (exit policies):
|
||||
- Avoid disclosing exit outbound bind addresses, configured port bind
|
||||
addresses, and local interface addresses in relay descriptors by
|
||||
default under ExitPolicyRejectPrivate. Instead, only reject these
|
||||
(otherwise unlisted) addresses if ExitPolicyRejectLocalInterfaces is set.
|
||||
Fixes bug 18456; bugfix on 0.2.7.2-alpha. Patch by teor.
|
@ -1701,15 +1701,16 @@ is non-zero):
|
||||
used with accept6/reject6.) +
|
||||
+
|
||||
Private addresses are rejected by default (at the beginning of your exit
|
||||
policy), along with any configured primary public IPv4 and IPv6 addresses,
|
||||
and any public IPv4 and IPv6 addresses on any interface on the relay.
|
||||
policy), along with any configured primary public IPv4 and IPv6 addresses.
|
||||
These private addresses are rejected unless you set the
|
||||
ExitPolicyRejectPrivate config option 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 "accept 127.0.0.1:80,reject private:\*", though that
|
||||
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. +
|
||||
about internal and reserved IP address space. See
|
||||
ExitPolicyRejectLocalInterfaces if you want to block every address on the
|
||||
relay, even those that aren't advertised in the descriptor. +
|
||||
+
|
||||
This directive can be specified multiple times so you don't have to put it
|
||||
all on one line. +
|
||||
@ -1739,16 +1740,23 @@ is non-zero):
|
||||
IPv4 and IPv6 addresses.
|
||||
|
||||
[[ExitPolicyRejectPrivate]] **ExitPolicyRejectPrivate** **0**|**1**::
|
||||
Reject all private (local) networks, along with any configured public
|
||||
IPv4 and IPv6 addresses, at the beginning of your exit policy. (This
|
||||
includes the IPv4 and IPv6 addresses advertised by the relay, any
|
||||
OutboundBindAddress, and the bind addresses of any port options, such as
|
||||
ORPort and DirPort.) This also rejects any public IPv4 and IPv6 addresses
|
||||
on any interface on the relay. (If IPv6Exit is not set, all IPv6 addresses
|
||||
will be rejected anyway.)
|
||||
Reject all private (local) networks, along with the relay's advertised
|
||||
public IPv4 and IPv6 addresses, at the beginning of your exit policy.
|
||||
See above entry on ExitPolicy.
|
||||
(Default: 1)
|
||||
|
||||
[[ExitPolicyRejectLocalInterfaces]] **ExitPolicyRejectLocalInterfaces** **0**|**1**::
|
||||
Reject all IPv4 and IPv6 addresses that the relay knows about, at the
|
||||
beginning of your exit policy. This includes any OutboundBindAddress, the
|
||||
bind addresses of any port options, such as ControlPort or DNSPort, and any
|
||||
public IPv4 and IPv6 addresses on any interface on the relay. (If IPv6Exit
|
||||
is not set, all IPv6 addresses will be rejected anyway.)
|
||||
See above entry on ExitPolicy.
|
||||
This option is off by default, because it lists all public relay IP
|
||||
addresses in the ExitPolicy, even those relay operators might prefer not
|
||||
to disclose.
|
||||
(Default: 0)
|
||||
|
||||
[[IPv6Exit]] **IPv6Exit** **0**|**1**::
|
||||
If set, and we are an exit node, allow clients to use us for IPv6
|
||||
traffic. (Default: 0)
|
||||
|
@ -244,6 +244,7 @@ static config_var_t option_vars_[] = {
|
||||
V(ExitNodes, ROUTERSET, NULL),
|
||||
V(ExitPolicy, LINELIST, NULL),
|
||||
V(ExitPolicyRejectPrivate, BOOL, "1"),
|
||||
V(ExitPolicyRejectLocalInterfaces, BOOL, "0"),
|
||||
V(ExitPortStatistics, BOOL, "0"),
|
||||
V(ExtendAllowPrivateAddresses, BOOL, "0"),
|
||||
V(ExitRelay, AUTOBOOL, "auto"),
|
||||
@ -4316,6 +4317,8 @@ options_transition_affects_descriptor(const or_options_t *old_options,
|
||||
old_options->ExitRelay != new_options->ExitRelay ||
|
||||
old_options->ExitPolicyRejectPrivate !=
|
||||
new_options->ExitPolicyRejectPrivate ||
|
||||
old_options->ExitPolicyRejectLocalInterfaces !=
|
||||
new_options->ExitPolicyRejectLocalInterfaces ||
|
||||
old_options->IPv6Exit != new_options->IPv6Exit ||
|
||||
!config_lines_eq(old_options->ORPort_lines,
|
||||
new_options->ORPort_lines) ||
|
||||
|
@ -3025,7 +3025,7 @@ static const getinfo_item_t getinfo_items[] = {
|
||||
" ExitPolicyRejectPrivate."),
|
||||
ITEM("exit-policy/reject-private/relay", policies,
|
||||
"The relay-specific rules appended to the configured exit policy by"
|
||||
" ExitPolicyRejectPrivate."),
|
||||
" ExitPolicyRejectPrivate and/or ExitPolicyRejectLocalInterfaces."),
|
||||
ITEM("exit-policy/full", policies, "The entire exit policy of onion router"),
|
||||
ITEM("exit-policy/ipv4", policies, "IPv4 parts of exit policy"),
|
||||
ITEM("exit-policy/ipv6", policies, "IPv6 parts of exit policy"),
|
||||
|
@ -2221,8 +2221,8 @@ ip_address_changed(int at_interface)
|
||||
{
|
||||
const or_options_t *options = get_options();
|
||||
int server = server_mode(options);
|
||||
int exit_reject_private = (server && options->ExitRelay
|
||||
&& options->ExitPolicyRejectPrivate);
|
||||
int exit_reject_interfaces = (server && options->ExitRelay
|
||||
&& options->ExitPolicyRejectLocalInterfaces);
|
||||
|
||||
if (at_interface) {
|
||||
if (! server) {
|
||||
@ -2240,8 +2240,8 @@ ip_address_changed(int at_interface)
|
||||
}
|
||||
|
||||
/* Exit relays incorporate interface addresses in their exit policies when
|
||||
* ExitPolicyRejectPrivate is set */
|
||||
if (exit_reject_private || (server && !at_interface)) {
|
||||
* ExitPolicyRejectLocalInterfaces is set */
|
||||
if (exit_reject_interfaces || (server && !at_interface)) {
|
||||
mark_my_descriptor_dirty("IP address changed");
|
||||
}
|
||||
|
||||
|
@ -3588,7 +3588,13 @@ typedef struct {
|
||||
/** Bitmask; derived from AllowInvalidNodes. */
|
||||
invalid_router_usage_t AllowInvalid_;
|
||||
config_line_t *ExitPolicy; /**< Lists of exit policy components. */
|
||||
int ExitPolicyRejectPrivate; /**< Should we not exit to local addresses? */
|
||||
int ExitPolicyRejectPrivate; /**< Should we not exit to reserved private
|
||||
* addresses, and our own published addresses?
|
||||
*/
|
||||
int ExitPolicyRejectLocalInterfaces; /**< Should we not exit to local
|
||||
* interface addresses?
|
||||
* Includes OutboundBindAddresses and
|
||||
* configured ports. */
|
||||
config_line_t *SocksPolicy; /**< Lists of socks policy components */
|
||||
config_line_t *DirPolicy; /**< Lists of dir policy components */
|
||||
/** Addresses to bind for listening for SOCKS connections. */
|
||||
|
@ -1843,10 +1843,18 @@ policies_log_first_redundant_entry(const smartlist_t *policy)
|
||||
*
|
||||
* If <b>ipv6_exit</b> is false, prepend "reject *6:*" to the policy.
|
||||
*
|
||||
* If <b>configured_addresses</b> contains addresses:
|
||||
* - prepend entries that reject the addresses in this list. These may be the
|
||||
* advertised relay addresses and/or the outbound bind addresses,
|
||||
* depending on the ExitPolicyRejectPrivate and
|
||||
* ExitPolicyRejectLocalInterfaces settings.
|
||||
* If <b>rejectprivate</b> is true:
|
||||
* - prepend "reject private:*" to the policy.
|
||||
* - prepend entries that reject publicly routable addresses on this exit
|
||||
* relay by calling policies_parse_exit_policy_reject_private
|
||||
* If <b>reject_interface_addresses</b> is true:
|
||||
* - prepend entries that reject publicly routable interface addresses on
|
||||
* this exit relay by calling policies_parse_exit_policy_reject_private
|
||||
* If <b>reject_configured_port_addresses</b> is true:
|
||||
* - prepend entries that reject all configured port addresses
|
||||
*
|
||||
* If cfg doesn't end in an absolute accept or reject and if
|
||||
* <b>add_default_policy</b> is true, add the default exit
|
||||
@ -1874,13 +1882,16 @@ policies_parse_exit_policy_internal(config_line_t *cfg,
|
||||
if (rejectprivate) {
|
||||
/* Reject IPv4 and IPv6 reserved private netblocks */
|
||||
append_exit_policy_string(dest, "reject private:*");
|
||||
/* Reject IPv4 and IPv6 publicly routable addresses on this exit relay */
|
||||
policies_parse_exit_policy_reject_private(
|
||||
dest, ipv6_exit,
|
||||
}
|
||||
|
||||
/* Consider rejecting IPv4 and IPv6 advertised relay addresses, outbound bind
|
||||
* addresses, publicly routable addresses, and configured port addresses
|
||||
* on this exit relay */
|
||||
policies_parse_exit_policy_reject_private(dest, ipv6_exit,
|
||||
configured_addresses,
|
||||
reject_interface_addresses,
|
||||
reject_configured_port_addresses);
|
||||
}
|
||||
|
||||
if (parse_addr_policy(cfg, dest, -1))
|
||||
return -1;
|
||||
|
||||
@ -1908,8 +1919,14 @@ policies_parse_exit_policy_internal(config_line_t *cfg,
|
||||
* If <b>EXIT_POLICY_REJECT_PRIVATE</b> bit is set in <b>options</b>:
|
||||
* - prepend an entry that rejects all destinations in all netblocks
|
||||
* reserved for private use.
|
||||
* - prepend entries that reject the advertised relay addresses in
|
||||
* configured_addresses
|
||||
* If <b>EXIT_POLICY_REJECT_LOCAL_INTERFACES</b> bit is set in <b>options</b>:
|
||||
* - prepend entries that reject publicly routable addresses on this exit
|
||||
* relay by calling policies_parse_exit_policy_internal
|
||||
* - prepend entries that reject the outbound bind addresses in
|
||||
* configured_addresses
|
||||
* - prepend entries that reject all configured port addresses
|
||||
*
|
||||
* If <b>EXIT_POLICY_ADD_DEFAULT</b> bit is set in <b>options</b>, append
|
||||
* default exit policy entries to <b>result</b> smartlist.
|
||||
@ -1922,12 +1939,14 @@ policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
|
||||
int ipv6_enabled = (options & EXIT_POLICY_IPV6_ENABLED) ? 1 : 0;
|
||||
int reject_private = (options & EXIT_POLICY_REJECT_PRIVATE) ? 1 : 0;
|
||||
int add_default = (options & EXIT_POLICY_ADD_DEFAULT) ? 1 : 0;
|
||||
int reject_local_interfaces = (options &
|
||||
EXIT_POLICY_REJECT_LOCAL_INTERFACES) ? 1 : 0;
|
||||
|
||||
return policies_parse_exit_policy_internal(cfg,dest,ipv6_enabled,
|
||||
reject_private,
|
||||
configured_addresses,
|
||||
reject_private,
|
||||
reject_private,
|
||||
reject_local_interfaces,
|
||||
reject_local_interfaces,
|
||||
add_default);
|
||||
}
|
||||
|
||||
@ -1993,6 +2012,7 @@ policies_copy_outbound_addresses_to_smartlist(smartlist_t *addr_list,
|
||||
* add it to the list of configured addresses.
|
||||
* - if ipv6_local_address is non-NULL, and not the null tor_addr_t, add it
|
||||
* to the list of configured addresses.
|
||||
* If <b>or_options->ExitPolicyRejectLocalInterfaces</b> is true:
|
||||
* - if or_options->OutboundBindAddressIPv4_ is not the null tor_addr_t, add
|
||||
* it to the list of configured addresses.
|
||||
* - if or_options->OutboundBindAddressIPv6_ is not the null tor_addr_t, add
|
||||
@ -2036,11 +2056,20 @@ policies_parse_exit_policy_from_options(const or_options_t *or_options,
|
||||
parser_cfg |= EXIT_POLICY_ADD_DEFAULT;
|
||||
}
|
||||
|
||||
if (or_options->ExitPolicyRejectLocalInterfaces) {
|
||||
parser_cfg |= EXIT_POLICY_REJECT_LOCAL_INTERFACES;
|
||||
}
|
||||
|
||||
/* Copy the configured addresses into the tor_addr_t* list */
|
||||
policies_copy_ipv4h_to_smartlist(configured_addresses, local_address);
|
||||
policies_copy_addr_to_smartlist(configured_addresses, ipv6_local_address);
|
||||
policies_copy_outbound_addresses_to_smartlist(configured_addresses,
|
||||
or_options);
|
||||
if (or_options->ExitPolicyRejectPrivate) {
|
||||
policies_copy_ipv4h_to_smartlist(configured_addresses, local_address);
|
||||
policies_copy_addr_to_smartlist(configured_addresses, ipv6_local_address);
|
||||
}
|
||||
|
||||
if (or_options->ExitPolicyRejectLocalInterfaces) {
|
||||
policies_copy_outbound_addresses_to_smartlist(configured_addresses,
|
||||
or_options);
|
||||
}
|
||||
|
||||
rv = policies_parse_exit_policy(or_options->ExitPolicy, result, parser_cfg,
|
||||
configured_addresses);
|
||||
@ -2822,7 +2851,8 @@ getinfo_helper_policies(control_connection_t *conn,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!options->ExitPolicyRejectPrivate) {
|
||||
if (!options->ExitPolicyRejectPrivate &&
|
||||
!options->ExitPolicyRejectLocalInterfaces) {
|
||||
*answer = tor_strdup("");
|
||||
return 0;
|
||||
}
|
||||
@ -2831,16 +2861,22 @@ getinfo_helper_policies(control_connection_t *conn,
|
||||
smartlist_t *configured_addresses = smartlist_new();
|
||||
|
||||
/* Copy the configured addresses into the tor_addr_t* list */
|
||||
policies_copy_ipv4h_to_smartlist(configured_addresses, me->addr);
|
||||
policies_copy_addr_to_smartlist(configured_addresses, &me->ipv6_addr);
|
||||
policies_copy_outbound_addresses_to_smartlist(configured_addresses,
|
||||
options);
|
||||
if (options->ExitPolicyRejectPrivate) {
|
||||
policies_copy_ipv4h_to_smartlist(configured_addresses, me->addr);
|
||||
policies_copy_addr_to_smartlist(configured_addresses, &me->ipv6_addr);
|
||||
}
|
||||
|
||||
if (options->ExitPolicyRejectLocalInterfaces) {
|
||||
policies_copy_outbound_addresses_to_smartlist(configured_addresses,
|
||||
options);
|
||||
}
|
||||
|
||||
policies_parse_exit_policy_reject_private(
|
||||
&private_policy_list,
|
||||
options->IPv6Exit,
|
||||
configured_addresses,
|
||||
1, 1);
|
||||
&private_policy_list,
|
||||
options->IPv6Exit,
|
||||
configured_addresses,
|
||||
options->ExitPolicyRejectLocalInterfaces,
|
||||
options->ExitPolicyRejectLocalInterfaces);
|
||||
*answer = policy_dump_to_string(private_policy_list, 1, 1);
|
||||
|
||||
addr_policy_list_free(private_policy_list);
|
||||
|
@ -18,9 +18,10 @@
|
||||
*/
|
||||
#define POLICY_BUF_LEN 72
|
||||
|
||||
#define EXIT_POLICY_IPV6_ENABLED (1 << 0)
|
||||
#define EXIT_POLICY_REJECT_PRIVATE (1 << 1)
|
||||
#define EXIT_POLICY_ADD_DEFAULT (1 << 2)
|
||||
#define EXIT_POLICY_IPV6_ENABLED (1 << 0)
|
||||
#define EXIT_POLICY_REJECT_PRIVATE (1 << 1)
|
||||
#define EXIT_POLICY_ADD_DEFAULT (1 << 2)
|
||||
#define EXIT_POLICY_REJECT_LOCAL_INTERFACES (1 << 3)
|
||||
|
||||
typedef enum firewall_connection_t {
|
||||
FIREWALL_OR_CONNECTION = 0,
|
||||
|
@ -1082,10 +1082,12 @@ test_policies_getinfo_helper_policies(void *arg)
|
||||
append_exit_policy_string(&mock_my_routerinfo.exit_policy, "reject *6:*");
|
||||
|
||||
mock_options.IPv6Exit = 1;
|
||||
mock_options.ExitPolicyRejectPrivate = 1;
|
||||
tor_addr_from_ipv4h(&mock_options.OutboundBindAddressIPv4_, TEST_IPV4_ADDR);
|
||||
tor_addr_parse(&mock_options.OutboundBindAddressIPv6_, TEST_IPV6_ADDR);
|
||||
|
||||
mock_options.ExitPolicyRejectPrivate = 1;
|
||||
mock_options.ExitPolicyRejectLocalInterfaces = 1;
|
||||
|
||||
rv = getinfo_helper_policies(NULL, "exit-policy/reject-private/relay",
|
||||
&answer, &errmsg);
|
||||
tt_assert(rv == 0);
|
||||
@ -1093,6 +1095,36 @@ test_policies_getinfo_helper_policies(void *arg)
|
||||
tt_assert(strlen(answer) > 0);
|
||||
tor_free(answer);
|
||||
|
||||
mock_options.ExitPolicyRejectPrivate = 1;
|
||||
mock_options.ExitPolicyRejectLocalInterfaces = 0;
|
||||
|
||||
rv = getinfo_helper_policies(NULL, "exit-policy/reject-private/relay",
|
||||
&answer, &errmsg);
|
||||
tt_assert(rv == 0);
|
||||
tt_assert(answer != NULL);
|
||||
tt_assert(strlen(answer) > 0);
|
||||
tor_free(answer);
|
||||
|
||||
mock_options.ExitPolicyRejectPrivate = 0;
|
||||
mock_options.ExitPolicyRejectLocalInterfaces = 1;
|
||||
|
||||
rv = getinfo_helper_policies(NULL, "exit-policy/reject-private/relay",
|
||||
&answer, &errmsg);
|
||||
tt_assert(rv == 0);
|
||||
tt_assert(answer != NULL);
|
||||
tt_assert(strlen(answer) > 0);
|
||||
tor_free(answer);
|
||||
|
||||
mock_options.ExitPolicyRejectPrivate = 0;
|
||||
mock_options.ExitPolicyRejectLocalInterfaces = 0;
|
||||
|
||||
rv = getinfo_helper_policies(NULL, "exit-policy/reject-private/relay",
|
||||
&answer, &errmsg);
|
||||
tt_assert(rv == 0);
|
||||
tt_assert(answer != NULL);
|
||||
tt_assert(strlen(answer) == 0);
|
||||
tor_free(answer);
|
||||
|
||||
rv = getinfo_helper_policies(NULL, "exit-policy/ipv4", &answer,
|
||||
&errmsg);
|
||||
tt_assert(rv == 0);
|
||||
|
Loading…
Reference in New Issue
Block a user