Stem Docs

Exit Policy

Exit Policy

Representation of tor exit policies. These can be easily used to check if exiting to a destination is permissible or not. For instance...

>>> from stem.exit_policy import ExitPolicy, MicroExitPolicy
>>> policy = ExitPolicy('accept *:80', 'accept *:443', 'reject *:*')
>>> print policy
accept *:80, accept *:443, reject *:*
>>> print policy.summary()
accept 80, 443
>>> policy.can_exit_to('75.119.206.243', 80)
True

>>> policy = MicroExitPolicy('accept 80,443')
>>> print policy
accept 80,443
>>> policy.can_exit_to('75.119.206.243', 80)
True
ExitPolicy - Exit policy for a Tor relay
  |  + MicroExitPolicy - Microdescriptor exit policy
  |- can_exit_to - check if exiting to this destination is allowed or not
  |- is_exiting_allowed - check if any exiting is allowed
  |- summary - provides a short label, similar to a microdescriptor
  |- __str__  - string representation
  +- __iter__ - ExitPolicyRule entries that this contains

ExitPolicyRule - Single rule of an exit policy chain
  |- is_address_wildcard - checks if we'll accept any address
  |- is_port_wildcard - checks if we'll accept any port
  |- get_address_type - provides the protocol our ip address belongs to
  |- is_match - checks if we match a given destination
  |- get_mask - provides the address representation of our mask
  |- get_masked_bits - provides the bit representation of our mask
  +- __str__ - string representation for this rule

get_config_policy - provides the ExitPolicy based on torrc rules
stem.exit_policy.AddressType(enum)

Enumerations for IP address types that can be in an exit policy.

AddressType Description
WILDCARD any address of either IPv4 or IPv6
IPv4 IPv4 address
IPv6 IPv6 address
stem.exit_policy.get_config_policy(rules)[source]

Converts an ExitPolicy found in a torrc to a proper exit pattern. This accounts for...

  • ports being optional
  • the 'private' keyword
Parameters:rules (str,list) -- comma separated rules or list to be converted
Returns:ExitPolicy reflected by the rules
Raises:ValueError if input isn't a valid tor exit policy
class stem.exit_policy.ExitPolicy(*rules)[source]

Bases: object

Policy for the destinations that a relay allows or denies exiting to. This is, in effect, just a list of ExitPolicyRule entries.

Parameters:rules (list) -- str or ExitPolicyRule entries that make up this policy
can_exit_to(*args, **kwds)[source]

Checks if this policy allows exiting to a given destination or not. If the address or port is omitted then this will check if we're allowed to exit to any instances of the defined address or port.

Parameters:
  • address (str) -- IPv4 or IPv6 address (with or without brackets)
  • port (int) -- port number
  • strict (bool) -- if the address or port is excluded then check if we can exit to all instances of the defined address or port
Returns:

True if exiting to this destination is allowed, False otherwise

is_exiting_allowed(*args, **kwds)[source]

Provides True if the policy allows exiting whatsoever, False otherwise.

summary(*args, **kwds)[source]

Provides a short description of our policy chain, similar to a microdescriptor. This excludes entries that don't cover all IP addresses, and is either white-list or blacklist policy based on the final entry. For instance...

>>> policy = ExitPolicy('accept *:80', 'accept *:443', 'reject *:*')
>>> policy.summary()
'accept 80, 443'

>>> policy = ExitPolicy('accept *:443', 'reject *:1-1024', 'accept *:*')
>>> policy.summary()
'reject 1-442, 444-1024'
Returns:str with a concise summary for our policy
class stem.exit_policy.MicroExitPolicy(policy)[source]

Bases: stem.exit_policy.ExitPolicy

Exit policy provided by the microdescriptors. This is a distilled version of a normal ExitPolicy contains, just consisting of a list of ports that are either accepted or rejected. For instance...

accept 80,443       # only accepts common http ports
reject 1-1024       # only accepts non-privileged ports

Since these policies are a subset of the exit policy information (lacking IP ranges) clients can only use them to guess if a relay will accept traffic or not. To quote the dir-spec (section 3.2.1)...

With microdescriptors, clients don't learn exact exit policies:
clients can only guess whether a relay accepts their request, try the
BEGIN request, and might get end-reason-exit-policy if they guessed
wrong, in which case they'll have to try elsewhere.
Variables:is_accept (bool) -- True if these are ports that we accept, False if they're ports that we reject
Parameters:policy (str) -- policy string that describes this policy
class stem.exit_policy.ExitPolicyRule(rule)[source]

Bases: object

Single rule from the user's exit policy. These rules are chained together to form complete policies that describe where a relay will and will not allow traffic to exit.

The format of these rules are formally described in the dir-spec as an 'exitpattern'. Note that while these are similar to tor's man page entry for ExitPolicies, it's not the exact same. An exitpattern is better defined and stricter in what it'll accept. For instance, ports are not optional and it does not contain the 'private' alias.

This should be treated as an immutable object.

Variables:
  • is_accept (bool) -- indicates if exiting is allowed or disallowed
  • address (str) -- address that this rule is for
  • min_port (int) -- lower end of the port range that we include (inclusive)
  • max_port (int) -- upper end of the port range that we include (inclusive)
Parameters:

rule (str) -- exit policy rule to be parsed

Raises:

ValueError if input isn't a valid tor exit policy rule

is_address_wildcard()[source]

True if we'll match against any address, False otherwise.

Note that if this policy can apply to both IPv4 and IPv6 then this is different from being for a /0 (since, for instance, 0.0.0.0/0 wouldn't match against an IPv6 address). That said, /0 addresses are highly unusual and most things citing exit policies are IPv4 specific anyway, making this moot.

Returns:bool for if our address matching is a wildcard
is_port_wildcard()[source]

True if we'll match against any port, False otherwise.

Returns:bool for if our port matching is a wildcard
is_match(address=None, port=None, strict=False)[source]

True if we match against the given destination, False otherwise. If the address or port is omitted then this will check if we're allowed to exit to any instances of the defined address or port.

Parameters:
  • address (str) -- IPv4 or IPv6 address (with or without brackets)
  • port (int) -- port number
  • strict (bool) -- if the address or port is excluded then check if we can exit to all instances of the defined address or port
Returns:

bool indicating if we match against this destination

Raises:

ValueError if provided with a malformed address or port

get_address_type()[source]

Provides the AddressType for our policy.

Returns:AddressType for the type of address that we have
get_mask(cache=True)[source]

Provides the address represented by our mask. This is None if our address type is a wildcard.

Parameters:cache (bool) -- caches the result if True
Returns:str of our subnet mask for the address (ex. '255.255.255.0')
get_masked_bits()[source]

Provides the number of bits our subnet mask represents. This is None if our mask can't have a bit representation.

Returns:int with the bit representation of our mask
class stem.exit_policy.MicroExitPolicyRule(is_accept, min_port, max_port)[source]

Bases: stem.exit_policy.ExitPolicyRule

Lighter weight ExitPolicyRule derivative for microdescriptors.

is_address_wildcard()[source]
get_address_type()[source]
get_mask(cache=True)[source]
get_masked_bits()[source]