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
  |- has_private - checks if policy has anything expanded from the 'private' keyword
  |- strip_private - provides a copy of the policy without 'private' entries
  |- has_default - checks if policy ends with the defaultly appended suffix
  |- strip_default - provides a copy of the policy without the default suffix
  |- __str__  - string representation
  +- __iter__ - ExitPolicyRule entries that this contains

ExitPolicyRule - Single rule of an exit policy chain
  |- MicroExitPolicyRule - Single rule for a microdescriptor policy
  |
  |- 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
  |- is_default - flag indicating if this was part of the default end of a policy
  |- is_private - flag indicating if this was expanded from a 'private' keyword
  +- __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, ip_address=None)[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
  • ip_address (str) -- this relay's IP address for the 'private' policy if it's present, this defaults to the local address
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
has_private()[source]

Checks if we have any rules expanded from the 'private' keyword. Tor appends these by default to the start of the policy and includes a dynamic address (the relay's public IP).

New in version 1.3.0.

Returns:True if we have any private rules expanded from the 'private' keyword, False otherwise
strip_private()[source]

Provides a copy of this policy without 'private' policy entries.

New in version 1.3.0.

Returns:ExitPolicy without private rules
has_default()[source]

Checks if we have the default policy suffix.

New in version 1.3.0.

Returns:True if we have the default policy suffix, False otherwise
strip_default()[source]

Provides a copy of this policy without the default policy suffix.

New in version 1.3.0.

Returns:ExitPolicy without default rules
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.

Changed in version 1.5.0: Support for 'accept6/reject6' entries and '*4/6' wildcards.

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 this is different than *4, *6, or '/0' address which are wildcards for only either IPv4 or IPv6.

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
is_private()[source]

Checks if this rule was expanded from the 'private' policy keyword.

New in version 1.3.0.

Returns:True if this rule was expanded from the 'private' keyword, False otherwise.
is_default()[source]

Checks if this rule belongs to the default exit policy suffix.

New in version 1.3.0.

Returns:True if this rule was part of the default end of a policy, False otherwise.
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]