Showing preview only (562K chars total). Download the full file or copy to clipboard to get everything.
Repository: EFForg/starttls-everywhere
Branch: master
Commit: 1ac62c425674
Files: 27
Total size: 544.4 KB
Directory structure:
gitextract_h1n5mfwv/
├── .dir-locals.el
├── .gitignore
├── .pylintrc
├── .travis.yml
├── LICENSE.TXT
├── README.md
├── RULES.md
├── USAGE.md
├── VALIDATION.md
├── code_legacy/
│ ├── PostfixConfigGenerator.py
│ ├── PostfixLogSummary.py
│ └── TestPostfixConfigGenerator.py
├── policy.json
├── policy.json.asc
├── schema/
│ └── policy-0.1.schema.json
├── scripts/
│ ├── starttls-policy.cron.d
│ ├── update_and_verify.sh
│ └── verify.sh
├── share/
│ ├── golden-domains.txt
│ └── google-starttls-domains.csv
├── test_rules/
│ ├── bigger_test_config.json
│ └── config.json
├── tests/
│ ├── policy_test.py
│ ├── test-requirements.txt
│ └── validate_signature.sh
└── tools/
├── CheckSTARTTLS.py
└── ProcessGoogleSTARTTLSDomains.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .dir-locals.el
================================================
;; emacs local configuration settings for starttls source
((js-mode
(indent-tabs-mode . nil)
(js-indent-level . 2)))
================================================
FILE: .gitignore
================================================
*.orig
*.pyc
*~
================================================
FILE: .pylintrc
================================================
[MASTER]
# use as many jobs as there are cores
jobs=0
# Specify a configuration file.
#rcfile=
# Python code to execute, usually for sys.path manipulation such as
# pygtk.require().
#init-hook=
# Profiled execution.
profile=no
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=CVS
# Pickle collected data for later comparisons.
persistent=yes
# Ignore pycurl, since no source access
extension-pkg-whitelist=pycurl
[MESSAGES CONTROL]
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time. See also the "--disable" option for examples.
#enable=
# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=fixme,locally-disabled,abstract-class-not-used,abstract-class-little-used,bad-continuation,too-few-public-methods,no-self-use,invalid-name,too-many-instance-attributes,cyclic-import,duplicate-code
# abstract-class-not-used cannot be disabled locally (at least in
# pylint 1.4.1), same for abstract-class-little-used
[REPORTS]
# Set the output format. Available formats are text, parseable, colorized, msvs
# (visual studio) and html. You can also give a reporter class, eg
# mypackage.mymodule.MyReporterClass.
output-format=text
# Put messages in a separate file for each module / package specified on the
# command line instead of printing them on stdout. Reports (if any) will be
# written in a file name "pylint_global.[txt|html]".
files-output=no
# Tells whether to display a full report or only the messages
reports=yes
# Python expression which should return a note less than 10 (10 is the highest
# note). You have access to the variables errors warning, statement which
# respectively contain the number of errors / warnings messages and the total
# number of statements analyzed. This is used by the global evaluation report
# (RP0004).
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
# Add a comment according to your evaluation note. This is used by the global
# evaluation report (RP0004).
comment=no
# Template used to display messages. This is a python new-style format string
# used to format the message information. See doc for all details
#msg-template=
[BASIC]
# Required attributes for module, separated by a comma
required-attributes=
# List of builtins function names that should not be used, separated by a comma
bad-functions=map,filter,apply,input,file
# Good variable names which should always be accepted, separated by a comma
good-names=f,i,j,k,ex,Run,_,fd,logger
# Bad variable names which should always be refused, separated by a comma
bad-names=foo,bar,baz,toto,tutu,tata
# Colon-delimited sets of names that determine each other's naming style when
# the name regexes allow several styles.
name-group=
# Include a hint for the correct naming format with invalid-name
include-naming-hint=no
# Regular expression matching correct function names
function-rgx=[a-z_][a-z0-9_]{2,40}$
# Naming hint for function names
function-name-hint=[a-z_][a-z0-9_]{2,40}$
# Regular expression matching correct variable names
variable-rgx=[a-z_][a-z0-9_]{1,30}$
# Naming hint for variable names
variable-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct constant names
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Naming hint for constant names
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
# Regular expression matching correct attribute names
attr-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for attribute names
attr-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct argument names
argument-rgx=[a-z_][a-z0-9_]{2,30}$
# Naming hint for argument names
argument-name-hint=[a-z_][a-z0-9_]{2,30}$
# Regular expression matching correct class attribute names
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Naming hint for class attribute names
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
# Regular expression matching correct inline iteration names
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
# Naming hint for inline iteration names
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
# Regular expression matching correct class names
class-rgx=[A-Z_][a-zA-Z0-9]+$
# Naming hint for class names
class-name-hint=[A-Z_][a-zA-Z0-9]+$
# Regular expression matching correct module names
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Naming hint for module names
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
# Regular expression matching correct method names
method-rgx=[a-z_][a-z0-9_]{2,50}$
# Naming hint for method names
method-name-hint=[a-z_][a-z0-9_]{2,50}$
# Regular expression which should only match function or class names that do
# not require a docstring.
no-docstring-rgx=(__.*__)|(test_[A-Za-z0-9_]*)|(_.*)|(.*Test$)
# Minimum line length for functions/classes that require docstrings, shorter
# ones are exempt.
docstring-min-length=-1
[MISCELLANEOUS]
# List of note tags to take in consideration, separated by a comma.
notes=FIXME,XXX,TODO
[LOGGING]
# Logging modules to check that the string format arguments are in logging
# function parameter format
logging-modules=logging,logger
[VARIABLES]
# Tells whether we should check for unused import in __init__ files.
init-import=no
# A regular expression matching the name of dummy variables (i.e. expectedly
# not used).
dummy-variables-rgx=(unused)?_.*|dummy
# List of additional names supposed to be defined in builtins. Remember that
# you should avoid to define new builtins when possible.
additional-builtins=
[SIMILARITIES]
# Minimum lines number of a similarity.
min-similarity-lines=6
# Ignore comments when computing similarities.
ignore-comments=yes
# Ignore docstrings when computing similarities.
ignore-docstrings=yes
# Ignore imports when computing similarities.
ignore-imports=yes
[FORMAT]
# Maximum number of characters on a single line.
max-line-length=100
# Regexp for a line that is allowed to be longer than the limit.
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
# Allow the body of an if to be on the same line as the test if there is no
# else.
single-line-if-stmt=no
# List of optional constructs for which whitespace checking is disabled
no-space-check=trailing-comma
# Maximum number of lines in a module
max-module-lines=1250
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
# tab).
indent-string=' '
# Number of spaces of indent required inside a hanging or continued line.
# This does something silly/broken...
#indent-after-paren=4
[TYPECHECK]
# Tells whether missing members accessed in mixin class should be ignored. A
# mixin class is detected if its name ends with "mixin" (case insensitive).
ignore-mixin-members=yes
# List of module names for which member attributes should not be checked
# (useful for modules/projects where namespaces are manipulated during runtime
# and thus existing member attributes cannot be deduced by static analysis
ignored-modules=pkg_resources,confargparse,argparse,six.moves,six.moves.urllib
# import errors ignored only in 1.4.4
# https://bitbucket.org/logilab/pylint/commits/cd000904c9e2
# List of classes names for which member attributes should not be checked
# (useful for classes with attributes dynamically set).
ignored-classes=SQLObject
# When zope mode is activated, add a predefined set of Zope acquired attributes
# to generated-members.
zope=yes
# List of members which are set dynamically and missed by pylint inference
# system, and so shouldn't trigger E0201 when accessed. Python regular
# expressions are accepted.
generated-members=REQUEST,acl_users,aq_parent
[IMPORTS]
# Deprecated modules which should not be used, separated by a comma
deprecated-modules=regsub,TERMIOS,Bastion,rexec
# Create a graph of every (i.e. internal and external) dependencies in the
# given file (report RP0402 must not be disabled)
import-graph=
# Create a graph of external dependencies in the given file (report RP0402 must
# not be disabled)
ext-import-graph=
# Create a graph of internal dependencies in the given file (report RP0402 must
# not be disabled)
int-import-graph=
[CLASSES]
# List of interface methods to ignore, separated by a comma. This is used for
# instance to not check methods defined in Zope's Interface base class.
ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by,implementedBy,providedBy
# List of method names used to declare (i.e. assign) instance attributes.
defining-attr-methods=__init__,__new__,setUp
# List of valid names for the first argument in a class method.
valid-classmethod-first-arg=cls
# List of valid names for the first argument in a metaclass class method.
valid-metaclass-classmethod-first-arg=mcs
[DESIGN]
# Maximum number of arguments for function / method
max-args=6
# Argument names that match this expression will be ignored. Default to name
# with leading underscore
ignored-argument-names=_.*
# Maximum number of locals for function / method body
max-locals=15
# Maximum number of return / yield for function / method body
max-returns=6
# Maximum number of branch for function / method body
max-branches=12
# Maximum number of statements in function / method body
max-statements=50
# Maximum number of parents for a class (see R0901).
max-parents=12
# Maximum number of attributes for a class (see R0902).
max-attributes=7
# Minimum number of public methods for a class (see R0903).
min-public-methods=2
# Maximum number of public methods for a class (see R0904).
max-public-methods=20
[EXCEPTIONS]
# Exceptions that will emit a warning when being caught. Defaults to
# "Exception"
overgeneral-exceptions=Exception
================================================
FILE: .travis.yml
================================================
language: python
python:
- "3.6"
install:
- pip install -r tests/test-requirements.txt
script:
- pytest
- ./tests/validate_signature.sh
================================================
FILE: LICENSE.TXT
================================================
STARTTLS Everywhere Policy Database and Helper Code
Copyright (c) Electronic Frontier Foundation and others
This repository is licensed under the Apache License Version 2.0.
The STARTTLS Everywhere Policy Database file (policy.json) is governed
by the following policy:
By contributing rules to the STARTTLS Everywhere Policy Database, or
modifying existing rules, you grant the Electronic Frontier Foundation
(EFF) a non-exclusive, transferable, sub-licensable, royalty-free,
worldwide license to use your contribution(s) in any manner that, in
EFF's sole discretion, furthers EFF's mission.
Text of Apache License
======================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
================================================
FILE: README.md
================================================
# STARTTLS Everywhere
STARTTLS Everywhere is an initiative for upgrading the security of the email ecosystem. Several sub-projects fit underneath the general umbrella of "STARTTLS Everywhere". The name itself is a bit of a misnomer, since the original idea for the project came about in 2014, when STARTTLS support hovered around 20% across the internet. Since then we've come a long way, with [Gmail's transparency report](https://transparencyreport.google.com/safer-email/overview) citing ~90% of inbound and outbound mail are encrypted with TLS, as of 2018.
We still have a long way to go. STARTTLS (opportunistic TLS) is vulnerable to [trivial downgrade attacks](https://stomp.colorado.edu/blog/blog/2012/12/31/on-smtp-starttls-and-the-cisco-asa/) that continue to be observed across the Internet. As of 2018, a quick Zmap query for a common STARTTLS-stripping fingerprint (a banner that reads "250 XXXXXXXX" rather than "250 STARTTLS") reveals around 8 thousand hosts. This is likely an under-estimate, since active attackers can perform the stripping in a less detectable way (simply by omitting the banner, for instance, rather than replacing its body with X's).
In addition, STARTTLS is also vulnerable to TLS man-in-the-middle attacks. Mailservers currently don't validate TLS certificates, since there has only [recently](https://tools.ietf.org/html/rfc8461#section-4.2) been an attempt to standardize the certificate validation rules across the email ecosystem.
Absent DNSSEC/DANE, STARTTLS by itself thwarts purely passive eavesdroppers. However, as currently deployed, it allows either bulk or semi-targeted attacks that are very unlikely to be detected. We would like to deploy both detection and prevention for such semi-targeted attacks.
### Goals
* Prevent [TLS stripping](https://www.eff.org/deeplinks/2014/11/starttls-downgrade-attacks) from revealing email contents to the network, when in transit between major MTAs that support STARTTLS.
* Prevent active MITM attacks at the DNS, SMTP, TLS, or other layers from revealing contents to the attacker.
* Zero or minimal decrease to deliverability rates unless network attacks are actually occurring.
* Create feedback-loops on targeted attacks and bulk surveilance in an opt-in, anonymized way.
### Non-goals
* Prevent fully-targeted exploits of vulnerabilities on endpoints or on mail hosts.
* Refuse delivery on the recipient side if sender does not negotiate TLS (this may be a future project).
* Develop a fully-decentralized solution.
* Initially we are not engineering to scale to all mail domains on the Internet, though we believe this design can be scaled as required if large numbers of domains publish policies to it.
## Solution stacks
A solution needs the following things:
- [ ] Server can advertise TLS support and MX data
- [ ] In a non-downgrade-able way
- [ ] Minimize deliverability impact
- [ ] Widely deployed
### DNSSEC, DANE, and TLSRPT
With [DNSSEC](https://tools.ietf.org/html/rfc4034) and [DANE](https://tools.ietf.org/html/rfc6698) [for email](https://tools.ietf.org/html/rfc7672), mailservers can essentially publish or pin their public keys via authenticated DNS records. If a domain has DNSSEC-signed their records, the absence/presence of a DANE TLSA record indicates non-support/support for STARTTLS, respectively.
Our goals can also be accomplished through use of [DNSSEC and DANE](https://tools.ietf.org/html/rfc7672), which is a very scalable solution. DANE adoption has been slow primarily since it is dependent on upstream support for DNSSEC; operators have been very slow to roll out DNSSEC. Making DNSSEC easier to deploy and improving its deployment is, for now, outside the scope of this project, though making DANE easier to deploy may be in-scope.
The mention of [TLSRPT](https://tools.ietf.org/html/rfc8460) is due to the fact that several operators consistently deploy DNSSEC or DANE incorrectly. We want to close the misconfiguration reporting feedback loop. TLSRPT is an RFC for publishing a "reporting mechanism" to DNS. This endpoint can be an email address or a web endpoint; it is expected that senders will publish to these when failures occur, and that receivers will aggregate these reports and fix their configurations if problems arise.
- [x] Server can advertise TLS support and MX data *(DANE TLSA records)*
- [x] In a non-downgrade-able way *(NSEC3 for DNSSEC)*
- [x] Minimize deliverability impact *(TLSRPT, ideally)*
### MTA-STS, Preloading, and TLSRPT
MTA-STS is a specification for mailservers to publish their TLS policy and ask senders to cache that policy, absent DNSSEC. The policy can be discovered at a `.well-known` address served over HTTPS at the email domain (for instance, [Gmail's record](https://mta-sts.gmail.com/.well-known/mta-sts.txt)). MTA-STS support is discovered through an initial DNS lookup.
There is value in deploying an intermediate solution, perhaps through [MTA-STS](https://tools.ietf.org/html/rfc8461), that does not rely on DNSSEC. This will improve the email security situation more quickly. It will also provide operational experience with authenticated SMTP over TLS that will make eventual rollout of DANE-based solutions easier.
However, MTA-STS, unlike DNSSEC + DANE, is trust-on-first-use. Since MTA-STS assumes no DNSSEC, the initial DNS query to discover MTA-STS support is downgradable. A full solution would include distributing an MTA-STS preload list via our email security database.
- [x] Server can advertise TLS support and MX data *(MTA-STS)*
- [x] In a non-downgrade-able way *(Preloading)*
- [x] Minimize deliverability impact *(TLSRPT, ideally)*
## Project scope
The project scope is very large, though our development team is extremely small. The following is a list of things that we care about doing, and afterwards is a short-term timeline of the currently prioritized tasks.
If you are working next to or directly on one or more of these things, feel free to shoot us an email at starttls-everywhere@eff.org.
### Email security database (STARTTLS policy list)
* [Usage guidelines](USAGE.md) (for configuration of sending mailservers)
* [Validation guidelines](VALIDATION.md) (for configuration of receiving mailservers)
* [Detailed spec](RULES.md) of list format.
* [Submission site for adding mail domains](https://starttls-everywhere.org)
* Maintaining and encouraging use of [starttls-policy-cli](https://github.com/EFForg/starttls-policy-cli).
### Tracking and encouraging deployment of existing standards.
* DANE
* Several other folks do a great job of monitoring [DANE deployment](https://mail.sys4.de/pipermail/dane-users/) and [misconfigurations](https://danefail.org/) on the internet.
* MTA-STS
* Encouraging MTA-STS validation support in popular MTA software.
* Encouraging mailservers to publish their policies.
* TLSRPT
* Encouraging reporting support in popular MTA software.
* Encouraging mailservers to host reporting servers/endpoints.
### Currently actively maintaining/building
* Maintaining the [email security database](policy.json) and [submission site](https://starttls-everywhere.org)
* Building out integrations for [starttls-policy-cli](https://github.com/EFForg/starttls-policy-cli/blob/master/README.md)
* Encouraging MTA-STS validation support in other MTA software.
### Contributing
* Announcements mailing list: starttls-everywhere@eff.org, https://lists.eff.org/mailman/listinfo/starttls-everywhere
* Developer mailing list: starttls-everywhere-devs@lists.eff.org, https://lists.eff.org/mailman/listinfo/starttls-everywhere-devs
* IRC/dev channel: TBD
* We host a weekly development call every Thursday at 11AM Pacific Time. Shoot the mailing list an email if you're interested in joining or just sitting in.
================================================
FILE: RULES.md
================================================
# Policy rule configuration format
The TLS policy file is a `json` file which conforms to the following specification. These fields draw inspiration from the [MTA-STS policy file format](https://tools.ietf.org/html/rfc8461) as well as [Chromium's HSTS Preload List](https://hstspreload.org/).
The basic file format will be JSON. Example:
```
{
"timestamp": "2014-06-06T14:30:16+00:00",
"author": "Electronic Frontier Foundation https://eff.org",
"expires": "2014-06-06T14:30:16+00:00",
"version": "0.1",
"policy-aliases": {
"gmail": {
"mode": "testing",
"mxs": [".mail.google.com"],
}
},
"policies": {
"yahoo.com": {
"mode": "enforce",
"mxs": [".yahoodns.net"]
},
"eff.org": {
"mode": "enforce",
"mxs": [".eff.org"]
},
"gmail.com": {
"policy-alias": "gmail"
},
"example.com": {
"mode": "testing",
"mxs": ["mail.example.com", ".example.net"]
},
},
}
```
At a high level, senders will expect the following for recipient domains:
- 1. Email domain resolves to an MX hostname which matches an entry in `mxs`
- 2. Provides a valid certificate. Validity means:
- a. The CN or DNS entry under subjectAltName matches an appropriate hostname.
- b. The certificate is unexpired.
- c. There is a valid chain from the certificate to a root included in [Mozilla's trust store](https://www.mozilla.org/en-US/about/governance/policies/security-group/certs/included/) (available as [Debian package ca-certificates](https://packages.debian.org/sid/ca-certificates)).
- 3. Successfully negotiates a TLS session (>= TLS 1.2).
A user of this file format may choose to override individual domain policies. For instance, the EFF might provide an overall configuration covering major mail providers, and another organization might produce an overlay for mail providers in a specific country.
Before adding a policy to this list, we validate that the email domain conforms to the policy, as above.
Note that there is no inline signature field. The configuration file should be distributed with authentication using an offline signing key, generated using `gpg --clearsign`. Config-generator should validate the signature against a known GPG public key before extracting. The public key is part of the permanent system configuration, like the fetch URL.
### Top-level fields
#### expires
When this configuration file expires, in UTC. Can be in epoch seconds from 00:00:00 UTC on 1 January 1970, or a string `yyyy-MM-dd'T'HH:mm:ssZZZZ`. If the file has ceased being regularly updated for any reason, and the policy file has expired, the MTA should fall-back to opportunistic TLS for e-mail delivery, and the system operator should be alerted.
#### timestamp
When this configuration file was distributed/fetched, in UTC. Can be in epoch seconds from 00:00:00 UTC on 1 January 1970, or a string `yyyy-MM-dd'T'HH:mm:ssZZZZ`. This field will be monotonically increasing for every update to the policy file. When updating this policy file, should validate that the timestamp is greater than or equal to the existing one.
#### policy-aliases
A mapping of alias names onto a policy. Domains in the `policies` field can refer to policies defined in this object.
#### policies
A mapping of mail domains (the part of an address after the "@") onto a "policy". Matching of mail domains is on an exact-match basis. For instance, `eff.org` would be listed separately from `lists.eff.org`. Fields in this policy specify security requirements that should be applied when connecting to any MTA server for a given mail domain. If the `mode` is `testing`, then the sender should not stop mail delivery on policy failures, but should produce logging information.
#### version
Version of the configuration file.
### Policy fields
Every field in `policies` maps to a policy object. A policy object can have the following fields:
#### policy-alias
If set, other fields are ignored. This value should be a key in the upper-level "policy-aliases" configuration object. The policy for this domain will be configured as the denoted policy in the "policy-aliases" object.
#### mode
Default: `testing` (required)
Either `testing` or `enforce`. If `testing` is set, then the recipient expects any failure in TLS negotiation to be reported via a mechanism such as TLSRPT, but the message is still sent over the insecure communication.
#### mxs
A list of the expected MX hostnames for your server. At least one of the names on each mailserver's certificate should match one of these patterns. The pattern can be a suffix, like `.eff.org`, or a fully-qualified domain name, like `mx.eff.org`. Suffixes will only match one subdomain label, so `.eff.org` would match names `*.eff.org` and `mx.eff.org`, but not `good.mx.eff.org` or `*.mx.eff.org`.
================================================
FILE: USAGE.md
================================================
# STARTTLS Policy List Usage Guidelines
For information about configuration of receiving mailservers and addition of a receiving mailserver to the list, please see [VALIDATION.md](VALIDATION.md) instead.
## MTA-STS interoperation for sending mailservers
The ideal is for the STARTTLS policy list to act as a "preload list" for MTA-STS domains. Although there are many parallels to the web situation with HSTS and the HSTS preload list, this list is not an exact equivalent. There are a couple of edge cases to consider when implementing both MTA-STS and the policy list. This describes the expected behavior of **sending** mailservers that both validate MTA-STS and follow the policy list.
If a mailserver is able to successfully discover and validate an MTA-STS record that conflicts with a policy on the list, then the mailserver should use the MTA-STS policy. Similarly, if a mailserver has an MTA-STS record cached that conflicts with a policy on the list, then the mailserver should use the MTA-STS policy.
That is, MTA-STS should take precedence over the STARTTLS policy list. The primary benefit of the STARTTLS policy list with MTA-STS is to secure MTA-STS on first-use.
## Using the list
To download and verify the most up-to-date version of the STARTTLS policy list:
```
wget https://dl.eff.org/starttls-everywhere/policy.json
wget https://dl.eff.org/starttls-everywhere/policy.json.asc
gpg --recv-key B693F33372E965D76D55368616EEA65D03326C9D
gpg --trusted-key 842AEA40C5BCD6E1 --verify policy.json.asc
```
Our sample [update_and_verify.sh script](https://github.com/EFForg/starttls-everywhere/blob/master/scripts/update_and_verify.sh) does the same. If you are actively using the list, **you must fetch updates at least once every 48 hours**. We provide [a sample cronjob](https://github.com/EFForg/starttls-everywhere/blob/master/scripts/starttls-policy.cron.d) to do this.
Every policy JSON has an expiry date in the top-level configuration, after which we cannot guarantee deliverability if you are using the expired list.
#### Behavior
A domain's policy, `enforce` or `testing`, asks that relays which connect to that domain's MX server and cannot initiate a TLS connection perform different behaviors depending on the policy (e.g. reporting what went wrong to the target domain for `testing`, and additionally aborting the connection for `enforce`). That is the behavior specified by [SMTP MTA Strict Transport Security (MTA-STS)](https://tools.ietf.org/html/rfc8461), an upcoming protocol which this Policy List aims to complement by providing an alternative method for advertising a mail server’s security policy.
#### Tooling
Our [starttls-policy](https://github.com/EFForg/starttls-everywhere/tree/master/starttls-policy) Python package can fetch updates to and iterate over the existing list. If you use Postfix, we provide utilities to transform the policy list into configuration parameters that Postfix understands.
We welcome [contributions](https://github.com/EFForg/starttls-everywhere) for different MTAs!
================================================
FILE: VALIDATION.md
================================================
# STARTTLS Policy List Validation
For information about configuration of sending mailservers and using the list to validate TLS configurations, please see [USAGE.md](USAGE.md) instead.
## MTA-STS
In order to be preloaded onto the STARTTLS policy list, the easiest way to do and maintain this is to have a valid MTA-STS record up for a max-age of at least half a year (10886400).
To change your entry on the list, you can serve a valid MTA-STS record with your new expected policy.
To be removed from the list, you can serve a valid MTA-STS record with `mode: none`.
## Manual addition
If you don't have an MTA-STS file up, For your email domain to be eligible for addition to the STARTTLS policy list, the requirements are that your domain:
* Supports STARTTLS (as a receiving mailserver)
* Supplied MX hostnames are valid (DNS lookup from this perspective resolves to hostnames that match the given patterns).
* Provides a valid PKI certificate. Validity is defined as in [RFC 3280](https://tools.ietf.org/html/rfc3280#section-6). To clarify:
* The certificate's Common Name or a subjectAltName should match the server's MX hostname.
* There is a valid chain, served by the server, from the certificate to a root included in [Mozilla's trust store](https://wiki.mozilla.org/CA/Included_Certificates) (available as Debian package [ca-certificates](https://packages.debian.org/sid/ca-certificates)).
* The certificate is not expired or revoked.
(Note: you can obtain a valid certificate for free via [Certbot](https://certbot.eff.org), a client for the [Let's Encrypt](https://letsencrypt.org) certificate authority.)
Before adding a domain to the list, we continue to perform validation against the mailserver for at least one week. If it fails at any point, **it must be resubmitted.**
With that in mind, you can [queue your mail domain](https://starttls-everywhere.org/add-domain) for the STARTTLS policy list. Alternatively, you can send an email to [starttls-policy@eff.org](mailto:starttls-policy@eff.org) or [submit a pull request](https://github.com/EFForg/starttls-everywhere) to add your domain, though these other channels may take longer for your domain to be submitted.
#### Continued requirements
Failure to continue meeting these requirements could result in deliverability issues to your mailserver, from any mail clients configured to use the STARTTLS policy list.
We continue to validate all the domains on the list daily. If we notice any oddities, we will notify the contact email associated with the policy submission and urge you to either update or remove your policy.
## Manually removing your policy entry from the list
If you're migrating email hosting, you'll need to update the MX hostnames associated with your domain's policy. Contact us beforehand so we can minimize the deliverability impact and remove your policy from the list-- we may also issue a challenge, solvable over DNS or HTTPS, in order to validate your intentions (more details in the threat modelling section). If we notice that you have migrated domains, we will reach out to you through a contact email that you provide, and the postmaster@ address.
If you'd like to request removal from the list, or an update to your policy entry (or associated contact email), contact us at [starttls-policy@eff.org](mailto:starttls-policy@eff.org)
## Threat modelling and security considerations
### DNS forgery
An attacker with the ability to forge DNS requests to a sending mailserver for a particular receiving mailserver might provide fake MX records for the receiving mailserver, causing the sender to direct its mail towards a malicious server. This is thwarted if the sender validates against the policy list and discovers that the receiving server uses a different set of hostnames.
This type of attacker may try and induce a removal and re-addition of a policy to the list. To do this, they might need to induce a validating CA to misissue a certificate, or maintain a machine-in-the-middle position on our validation server for several weeks, and against our notification email server, which will send updates to the policy's email contact (also unknown to the attacker, and could be hosted on a different server) about these attempts.
### TCP on-path attacker
Normally, a regular on-path attacker might simply downgrade TLS. A more sophisticated one might perform a certificate man-in-the-middle. In either case, this is thwarted if the sender is validating against the policy list and discovers that the receiving server should support TLS with a valid certificate.
This type of attacker may try and induce removal of that receiving server from the policy list. To prevent this, we'll issue a DNS challenge to validate any policy list removal.
### CA compromise or induced misissuance
When a valid MTA-STS record is discovered, the STARTTLS policy list cannot necessarily provide a higher degree of security, since we also validate TLS policies from our own network position. Thus, MTA-STS policies should take precedence over the STARTTLS policy list.
This means that we do assume CA compromise or misissuance is more difficult (in terms of cost, risk, and detectability thanks to Certificate Transparency, or CT) than performing a single DNS on-path attack or forgery, and than performing a TCP on-path attack. However, it is possible, with a temporary DNS machine-in-the-middle position (perhaps due to BGP hijacking) with respect to an automated CA like Let's Encrypt, to induce certificate misissuance.
Some of these judgments depend on an adversary's relative network perspective to the target mailserver and various automated CAs. Regardless, inducing misissuance is at least detectable if a domain owner is [monitoring CT logs](), and may require extra effort (depending on network perspective) in addition to having a machine-in-the-middle DNS position targeted towards a particular mailserver. Hopefully, with [multi-perspective validation](https://letsencrypt.org/upcoming-features/) on the horizon for Let's Encrypt, the bar could be raised even higher for an attacker to induce misissuance.
================================================
FILE: code_legacy/PostfixConfigGenerator.py
================================================
#!/usr/bin/env python
import logging
import sys
import string
import subprocess
import os, os.path
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
log_handler = logging.StreamHandler()
log_handler.setLevel(logging.DEBUG)
logger.addHandler(log_handler)
def parse_line(line_data):
"""
Return the (line number, left hand side, right hand side) of a stripped
postfix config line.
Lines are like:
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
"""
num,line = line_data
left, sep, right = line.partition("=")
if not sep:
return None
return (num, left.strip(), right.strip())
class ExistingConfigError(ValueError): pass
class PostfixConfigGenerator:
def __init__(self,
policy_config,
postfix_dir,
fixup=False,
fopen=open,
version=None):
self.fixup = fixup
self.postfix_dir = postfix_dir
self.policy_config = policy_config
self.policy_file = os.path.join(postfix_dir,
"starttls_everywhere_policy")
self.ca_file = os.path.join(postfix_dir, "starttls_everywhere_CAfile")
self.additions = []
self.deletions = []
self.fn = self.find_postfix_cf()
self.raw_cf = fopen(self.fn).readlines()
self.cf = map(string.strip, self.raw_cf)
#self.cf = [line for line in cf if line and not line.startswith("#")]
self.policy_lines = []
self.new_cf = ""
# Set in .prepare() unless running in a test
self.postfix_version = version
def find_postfix_cf(self):
"Search far and wide for the correct postfix configuration file"
return os.path.join(self.postfix_dir, "main.cf")
def ensure_cf_var(self, var, ideal, also_acceptable):
"""
Ensure that existing postfix config @var is in the list of @acceptable
values; if not, set it to the ideal value.
"""
acceptable = [ideal] + also_acceptable
l = [(num,line) for num,line in enumerate(self.cf)
if line.startswith(var)]
if not any(l):
self.additions.append(var + " = " + ideal)
else:
values = map(parse_line, l)
if len(set(values)) > 1:
if self.fixup:
conflicting_lines = [num for num,_var,val in values]
self.deletions.extend(conflicting_lines)
self.additions.append(var + " = " + ideal)
else:
raise ExistingConfigError(
"Conflicting existing config values " + `l`
)
val = values[0][2]
if val not in acceptable:
if self.fixup:
self.deletions.append(values[0][0])
self.additions.append(var + " = " + ideal)
else:
raise ExistingConfigError(
"Existing config has %s=%s"%(var,val)
)
def wrangle_existing_config(self):
"""
Try to ensure/mutate that the config file is in a sane state.
Fixup means we'll delete existing lines if necessary to get there.
"""
# Check we're currently accepting inbound STARTTLS sensibly
self.ensure_cf_var("smtpd_use_tls", "yes", [])
# Ideally we use it opportunistically in the outbound direction
self.ensure_cf_var("smtp_tls_security_level", "may", ["encrypt","dane"])
# Maximum verbosity lets us collect failure information
self.ensure_cf_var("smtp_tls_loglevel", "1", [])
# Inject a reference to our per-domain policy map
policy_cf_entry = "texthash:" + self.policy_file
self.ensure_cf_var("smtp_tls_policy_maps", policy_cf_entry, [])
self.ensure_cf_var("smtp_tls_CAfile", self.ca_file, [])
# Disable SSLv2 and SSLv3. Syntax for `smtp_tls_protocols` changed
# between Postfix version 2.5 and 2.6, since we only support => 2.11
# we don't use nor support legacy Postfix syntax.
# - Server:
self.ensure_cf_var("smtpd_tls_protocols", "!SSLv2, !SSLv3", [])
self.ensure_cf_var("smtpd_tls_mandatory_protocols", "!SSLv2, !SSLv3", [])
# - Client:
self.ensure_cf_var("smtp_tls_protocols", "!SSLv2, !SSLv3", [])
self.ensure_cf_var("smtp_tls_mandatory_protocols", "!SSLv2, !SSLv3", [])
def maybe_add_config_lines(self, fopen=open):
if not self.additions:
return
if self.fixup:
logger.info('Deleting lines: {}'.format(self.deletions))
self.additions[:0]=["#",
"# New config lines added by STARTTLS Everywhere",
"#"]
new_cf_lines = "\n".join(self.additions) + "\n"
logger.info('Adding to {}:'.format(self.fn))
logger.info(new_cf_lines)
if self.raw_cf[-1][-1] == "\n": sep = ""
else: sep = "\n"
for num, line in enumerate(self.raw_cf):
if self.fixup and num in self.deletions:
self.new_cf += "# Line removed by STARTTLS Everywhere\n# " + line
else:
self.new_cf += line
self.new_cf += sep + new_cf_lines
if not os.access(self.fn, os.W_OK):
raise Exception("Can't write to %s, please re-run as root."
% self.fn)
with fopen(self.fn, "w") as f:
f.write(self.new_cf)
def set_domainwise_tls_policies(self, fopen=open):
all_acceptable_mxs = self.policy_config.acceptable_mxs
for address_domain, properties in all_acceptable_mxs.items():
mx_list = properties.accept_mx_domains
if len(mx_list) > 1:
logger.warn('Lists of multiple accept-mx-domains not yet '
'supported.')
logger.warn('Using MX {} for {}'.format(mx_list[0],
address_domain)
)
logger.warn('Ignoring: {}'.format(', '.join(mx_list[1:])))
mx_domain = mx_list[0]
mx_policy = self.policy_config.get_tls_policy(mx_domain)
entry = address_domain + " encrypt"
if mx_policy.min_tls_version.lower() == "tlsv1":
entry += " protocols=!SSLv2:!SSLv3"
elif mx_policy.min_tls_version.lower() == "tlsv1.1":
entry += " protocols=!SSLv2:!SSLv3:!TLSv1"
elif mx_policy.min_tls_version.lower() == "tlsv1.2":
entry += " protocols=!SSLv2:!SSLv3:!TLSv1:!TLSv1.1"
else:
logger.warn('Unknown minimum TLS version: {} '.format(
mx_policy.min_tls_version)
)
self.policy_lines.append(entry)
with fopen(self.policy_file, "w") as f:
f.write("\n".join(self.policy_lines) + "\n")
### Let's Encrypt client IPlugin ###
# https://github.com/letsencrypt/letsencrypt/blob/master/letsencrypt/plugins/common.py#L35
def prepare(self):
"""Prepare the plugin.
Finish up any additional initialization.
:raises .PluginError:
when full initialization cannot be completed.
:raises .MisconfigurationError:
when full initialization cannot be completed. Plugin will
be displayed on a list of available plugins.
:raises .NoInstallationError:
when the necessary programs/files cannot be located. Plugin
will NOT be displayed on a list of available plugins.
:raises .NotSupportedError:
when the installation is recognized, but the version is not
currently supported.
:rtype tuple:
"""
# XXX ensure we raise the right kinds of exceptions
if not self.postfix_version:
self.postfix_version = self.get_version()
if self.postfix_version < (2, 11, 0):
raise Exception(
'NotSupportedError: Postfix version is too old -- test.'
)
# Postfix has changed support for TLS features, supported protocol versions
# KEX methods, ciphers et cetera over the years. We sort out version dependend
# differences here and pass them onto other configuration functions.
# see:
# http://www.postfix.org/TLS_README.html
# http://www.postfix.org/FORWARD_SECRECY_README.html
# Postfix == 2.2:
# - TLS support introduced via 3rd party patch, see:
# http://www.postfix.org/TLS_LEGACY_README.html
# Postfix => 2.2:
# - built-in TLS support added
# - Support for PFS introduced
# - Support for (E)DHE params >= 1024bit (need to be generated), default 1k
# Postfix => 2.5:
# - Syntax to specify mandatory protocol version changes:
# * < 2.5: `smtpd_tls_mandatory_protocols = TLSv1`
# * => 2.5: `smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3`
# - Certificate fingerprint verification added
# Postfix => 2.6:
# - Support for ECDHE NIST P-256 curve (enable `smtpd_tls_eecdh_grade = strong`)
# - Support for configurable cipher-suites and protocol versions added, pre-2.6
# releases always set EXPORT, options: `smtp_tls_ciphers` and `smtp_tls_protocols`
# - `smtp_tls_eccert_file` and `smtp_tls_eckey_file` config. options added
# Postfix => 2.8:
# - Override Client suite preference w. `tls_preempt_cipherlist = yes`
# - Elliptic curve crypto. support enabled by default
# Postfix => 2.9:
# - Public key fingerprint support added
# - `permit_tls_clientcerts`, `permit_tls_all_clientcerts` and
# `check_ccert_access` config. options added
# Postfix <= 2.9.5:
# - BUG: Public key fingerprint is computed incorrectly
# Postfix => 3.1:
# - Built-in support for TLS management and DANE added, see:
# http://www.postfix.org/postfix-tls.1.html
def get_version(self):
"""Return the mail version of Postfix.
Version is returned as a tuple. (e.g. '2.11.3' is (2, 11, 3))
:returns: version
:rtype: tuple
:raises .PluginError:
Unable to find Postfix version.
"""
# Parse Postfix version number (feature support, syntax changes etc.)
cmd = subprocess.Popen(['/usr/sbin/postconf', '-d', 'mail_version'],
stdout=subprocess.PIPE)
stdout, _ = cmd.communicate()
if cmd.returncode != 0:
raise Exception('PluginError: Unable to determine Postfix version.')
# grabs version component of string like "mail_version = 2.11.3"
mail_version = stdout.split()[2]
postfix_version = tuple([int(i) for i in mail_version.split('.')])
return postfix_version
def more_info(self):
"""Human-readable string to help the user.
Should describe the steps taken and any relevant info to help the user
decide which plugin to use.
:rtype str:
"""
return (
"Configures Postfix to try to authenticate mail servers, use "
"installed certificates and disable weak ciphers and protocols.{0}"
"Server root: {root}{0}"
"Version: {version}".format(
os.linesep,
root=self.postfix_dir,
version='.'.join([str(i) for i in self.postfix_version]))
)
### Let's Encrypt client IInstaller ###
# https://github.com/letsencrypt/letsencrypt/blob/master/letsencrypt/interfaces.py#L232
def get_all_names(self):
"""Returns all names that may be authenticated.
:rtype: `list` of `str`
"""
var_names = ('myhostname', 'mydomain', 'myorigin')
names_found = set()
for num, line in enumerate(self.cf):
num, found_var, found_value = parse_line((num, line))
if found_var in var_names:
names_found.add(found_value)
name_list = list(names_found)
name_list.sort()
return name_list
def deploy_cert(self, domain, _cert_path, key_path, _chain_path, fullchain_path):
"""Deploy certificate.
:param str domain: domain to deploy certificate file
:param str cert_path: absolute path to the certificate file
:param str key_path: absolute path to the private key file
:param str chain_path: absolute path to the certificate chain file
:param str fullchain_path: absolute path to the certificate fullchain
file (cert plus chain)
:raises .PluginError: when cert cannot be deployed
"""
self.wrangle_existing_config()
self.ensure_cf_var("smtpd_tls_cert_file", fullchain_path, [])
self.ensure_cf_var("smtpd_tls_key_file", key_path, [])
self.set_domainwise_tls_policies()
self.update_CAfile()
def enhance(self, domain, enhancement, options=None):
"""Perform a configuration enhancement.
:param str domain: domain for which to provide enhancement
:param str enhancement: An enhancement as defined in
:const:`~letsencrypt.constants.ENHANCEMENTS`
:param options: Flexible options parameter for enhancement.
Check documentation of
:const:`~letsencrypt.constants.ENHANCEMENTS`
for expected options for each enhancement.
:raises .PluginError: If Enhancement is not supported, or if
an error occurs during the enhancement.
"""
def supported_enhancements(self):
"""Returns a list of supported enhancements.
:returns: supported enhancements which should be a subset of
:const:`~letsencrypt.constants.ENHANCEMENTS`
:rtype: :class:`list` of :class:`str`
"""
def get_all_certs_keys(self):
"""Retrieve all certs and keys set in configuration.
:returns: tuples with form `[(cert, key, path)]`, where:
- `cert` - str path to certificate file
- `key` - str path to associated key file
- `path` - file path to configuration file
:rtype: list
"""
cert_materials = {'smtpd_tls_key_file': None,
'smtpd_tls_cert_file': None,
}
for num, line in enumerate(self.cf):
num, found_var, found_value = parse_line((num, line))
if found_var in cert_materials.keys():
cert_materials[found_var] = found_value
if not all(cert_materials.values()):
cert_material_tuples = []
else:
cert_material_tuples = [(cert_materials['smtpd_tls_cert_file'],
cert_materials['smtpd_tls_key_file'],
self.fn),]
return cert_material_tuples
def save(self, title=None, temporary=False):
"""Saves all changes to the configuration files.
Both title and temporary are needed because a save may be
intended to be permanent, but the save is not ready to be a full
checkpoint. If an exception is raised, it is assumed a new
checkpoint was not created.
:param str title: The title of the save. If a title is given, the
configuration will be saved as a new checkpoint and put in a
timestamped directory. `title` has no effect if temporary is true.
:param bool temporary: Indicates whether the changes made will
be quickly reversed in the future (challenges)
:raises .PluginError: when save is unsuccessful
"""
self.maybe_add_config_lines()
def rollback_checkpoints(self, rollback=1):
"""Revert `rollback` number of configuration checkpoints.
:raises .PluginError: when configuration cannot be fully reverted
"""
def recovery_routine(self):
"""Revert configuration to most recent finalized checkpoint.
Remove all changes (temporary and permanent) that have not been
finalized. This is useful to protect against crashes and other
execution interruptions.
:raises .errors.PluginError: If unable to recover the configuration
"""
def view_config_changes(self):
"""Display all of the LE config changes.
:raises .PluginError: when config changes cannot be parsed
"""
def config_test(self):
"""Make sure the configuration is valid.
:raises .MisconfigurationError: when the config is not in a usable state
"""
if os.geteuid() != 0:
rc = os.system('sudo /usr/sbin/postfix check')
else:
rc = os.system('/usr/sbin/postfix check')
if rc != 0:
raise Exception('MisconfigurationError: Postfix failed self-check.')
def restart(self):
"""Restart or refresh the server content.
:raises .PluginError: when server cannot be restarted
"""
logger.info('Reloading postfix config...')
if os.geteuid() != 0:
rc = os.system("sudo service postfix reload")
else:
rc = os.system("service postfix reload")
if rc != 0:
raise Exception('PluginError: cannot restart postfix')
def update_CAfile(self):
os.system("cat /usr/share/ca-certificates/mozilla/*.crt > " + self.ca_file)
def usage():
print ("Usage: %s starttls-everywhere.json /etc/postfix "
"/etc/letsencrypt/live/example.com/" % sys.argv[0])
sys.exit(1)
if __name__ == "__main__":
import Config as config
if len(sys.argv) != 4:
usage()
c = config.Config()
c.load_from_json_file(sys.argv[1])
postfix_dir = sys.argv[2]
le_lineage = sys.argv[3]
pieces = [os.path.join(le_lineage, f) for f in (
"cert.pem", "privkey.pem", "chain.pem", "fullchain.pem")]
if not os.path.isdir(le_lineage) or not all(os.path.isfile(p) for p in pieces) :
print "Let's Encrypt directory", le_lineage, "does not appear to contain a valid lineage"
print
usage()
cert, key, chain, fullchain = pieces
pcgen = PostfixConfigGenerator(c, postfix_dir, fixup=True)
pcgen.prepare()
pcgen.deploy_cert("example.com", cert, key, chain, fullchain)
pcgen.save()
pcgen.restart()
================================================
FILE: code_legacy/PostfixLogSummary.py
================================================
#!/usr/bin/env python
import argparse
import collections
import os
import re
import sys
import time
import Config
TIME_FORMAT = "%b %d %H:%M:%S"
# TODO: There's more to be learned from postfix logs! Here's one sample
# observed during failures from the sender vagrant vm:
# Jun 6 00:21:31 precise32 postfix/smtpd[3648]: connect from localhost[127.0.0.1]
# Jun 6 00:21:34 precise32 postfix/smtpd[3648]: lost connection after STARTTLS from localhost[127.0.0.1]
# Jun 6 00:21:34 precise32 postfix/smtpd[3648]: disconnect from localhost[127.0.0.1]
# Jun 6 00:21:56 precise32 postfix/master[3001]: reload -- version 2.9.6, configuration /etc/postfix
# Jun 6 00:22:01 precise32 postfix/pickup[3674]: AF3B6480475: uid=0 from=<root>
# Jun 6 00:22:01 precise32 postfix/cleanup[3680]: AF3B6480475: message-id=<20140606002201.AF3B6480475@sender.example.com>
# Jun 6 00:22:01 precise32 postfix/qmgr[3673]: AF3B6480475: from=<root@sender.example.com>, size=576, nrcpt=1 (queue active)
# Jun 6 00:22:01 precise32 postfix/smtp[3682]: SSL_connect error to valid-example-recipient.com[192.168.33.7]:25: -1
# Jun 6 00:22:01 precise32 postfix/smtp[3682]: warning: TLS library problem: 3682:error:140740BF:SSL routines:SSL23_CLIENT_HELLO:no protocols available:s23_clnt.c:381:
# Jun 6 00:22:01 precise32 postfix/smtp[3682]: AF3B6480475: to=<vagrant@valid-example-recipient.com>, relay=valid-example-recipient.com[192.168.33.7]:25, delay=0.06, delays=0.03/0.03/0/0, dsn=4.7.5, status=deferred (Cannot start TLS: handshake failure)
#
# Also:
# Oct 10 19:12:13 sender postfix/smtp[1711]: 62D3F481249: to=<vagrant@valid-example-recipient.com>, relay=valid-example-recipient.com[192.168.33.7]:25, delay=0.07, delays=0.03/0.01/0.03/0, dsn=4.7.4, status=deferred (TLS is required, but was not offered by host valid-example-recipient.com[192.168.33.7])
def get_counts(input, config, earliest_timestamp):
seen_trusted = False
counts = collections.defaultdict(lambda: collections.defaultdict(int))
tls_deferred = collections.defaultdict(int)
# Typical line looks like:
# Jun 12 06:24:14 sender postfix/smtp[9045]: Untrusted TLS connection established to valid-example-recipient.com[192.168.33.7]:25: TLSv1.1 with cipher AECDH-AES256-SHA (256/256 bits)
# indicate a problem that should be alerted on.
# ([^[]*) <--- any group of characters that is not "["
# Log lines for when a message is deferred for a TLS-related reason. These
deferred_re = re.compile("relay=([^[ ]*).* status=deferred.*TLS")
# Log lines for when a TLS connection was successfully established. These can
# indicate the difference between Untrusted, Trusted, and Verified certs.
connected_re = re.compile("([A-Za-z]+) TLS connection established to ([^[]*)")
mx_to_domain_mapping = config.get_mx_to_domain_policy_map()
timestamp = 0
for line in sys.stdin:
timestamp = time.strptime(line[0:15], TIME_FORMAT)
if timestamp < earliest_timestamp:
continue
deferred = deferred_re.search(line)
connected = connected_re.search(line)
if connected:
validation = connected.group(1)
mx_hostname = connected.group(2).lower()
if validation == "Trusted" or validation == "Verified":
seen_trusted = True
address_domains = config.get_address_domains(mx_hostname, mx_to_domain_mapping)
if address_domains:
domains_str = [ a.domain for a in address_domains ]
d = ', '.join(domains_str)
counts[d][validation] += 1
counts[d]["all"] += 1
elif deferred:
mx_hostname = deferred.group(1).lower()
tls_deferred[mx_hostname] += 1
return (counts, tls_deferred, seen_trusted, timestamp)
def print_summary(counts):
for mx_hostname, validations in counts.items():
for validation, validation_count in validations.items():
if validation == "all":
continue
print mx_hostname, validation, validation_count / validations["all"], "of", validations["all"]
if __name__ == "__main__":
arg_parser = argparse.ArgumentParser(description='Detect delivery problems'
' in Postfix log files that may be caused by security policies')
arg_parser.add_argument('-c', action="store_true", dest="cron", default=False)
arg_parser.add_argument("policy_file", nargs='?',
default=os.path.join("examples", "starttls-everywhere.json"),
help="STARTTLS Everywhere policy file")
args = arg_parser.parse_args()
config = Config.Config()
config.load_from_json_file(args.policy_file)
last_timestamp_processed = 0
timestamp_file = '/tmp/starttls-everywhere-last-timestamp-processed.txt'
if os.path.isfile(timestamp_file):
last_timestamp_processed = time.strptime(open(timestamp_file).read(), TIME_FORMAT)
(counts, tls_deferred, seen_trusted, latest_timestamp) = get_counts(sys.stdin, config, last_timestamp_processed)
with open(timestamp_file, "w") as f:
f.write(time.strftime(TIME_FORMAT, latest_timestamp))
# If not running in cron, print an overall summary of log lines seen from known hosts.
if not args.cron:
print_summary(counts)
if not seen_trusted:
print 'No Trusted connections seen! Probably need to install a CAfile.'
if len(tls_deferred) > 0:
print "Some mail was deferred due to TLS problems:"
for (k, v) in tls_deferred.iteritems():
print "%s: %s" % (k, v)
================================================
FILE: code_legacy/TestPostfixConfigGenerator.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import io
import logging
import unittest
import Config
import PostfixConfigGenerator as pcg
logger = logging.getLogger(__name__)
logger.addHandler(logging.StreamHandler())
# Fake Postfix Configs
names_only_config = """myhostname = mail.fubard.org
mydomain = fubard.org
myorigin = fubard.org"""
certs_only_config = (
"""smtpd_tls_cert_file = /etc/letsencrypt/live/www.fubard.org/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/www.fubard.org/privkey.pem""")
def GetFakeOpen(fake_file_contents):
fake_file = io.StringIO()
# cast this to unicode for py2
fake_file.write(fake_file_contents)
fake_file.seek(0)
def FakeOpen(_):
return fake_file
return FakeOpen
class TestPostfixConfigGenerator(unittest.TestCase):
def setUp(self):
self.fopen_names_only_config = GetFakeOpen(names_only_config)
self.fopen_certs_only_config = GetFakeOpen(certs_only_config)
self.fopen_no_certs_only_config = self.fopen_names_only_config
#self.config = Config.Config()
self.config = None
self.postfix_dir = 'tests/'
def tearDown(self):
pass
def testGetAllNames(self):
sorted_names = ['fubard.org', 'mail.fubard.org']
postfix_config_gen = pcg.PostfixConfigGenerator(
self.config,
self.postfix_dir,
fixup=True,
fopen=self.fopen_names_only_config
)
self.assertEqual(sorted_names, postfix_config_gen.get_all_names())
def testGetAllCertAndKeys(self):
return_vals = [('/etc/letsencrypt/live/www.fubard.org/fullchain.pem',
'/etc/letsencrypt/live/www.fubard.org/privkey.pem',
'tests/main.cf'),]
postfix_config_gen = pcg.PostfixConfigGenerator(
self.config,
self.postfix_dir,
fixup=True,
fopen=self.fopen_certs_only_config
)
self.assertEqual(return_vals, postfix_config_gen.get_all_certs_keys())
def testGetAllCertsAndKeys_With_None(self):
postfix_config_gen = pcg.PostfixConfigGenerator(
self.config,
self.postfix_dir,
fixup=True,
fopen=self.fopen_no_certs_only_config
)
self.assertEqual([], postfix_config_gen.get_all_certs_keys())
if __name__ == '__main__':
unittest.main()
================================================
FILE: policy.json
================================================
{
"timestamp": "2020-05-20T10:25:12.710034-07:00",
"expires": "2020-06-03T10:25:12.710055-07:00",
"version": "0.1",
"author": "Electronic Frontier Foundation https://eff.org",
"policy-aliases": {
"google": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"icloud": {
"mode": "testing",
"mxs": [
"mx1.mail.icloud.com",
"mx2.mail.icloud.com",
"mx3.mail.icloud.com",
"mx4.mail.icloud.com",
"mx5.mail.icloud.com",
"mx6.mail.icloud.com",
".mail.icloud.com"
]
},
"outlook": {
"mode": "testing",
"mxs": [
".olc.protection.outlook.com",
".mail.protection.outlook.com"
]
},
"yahoo": {
"mode": "testing",
"mxs": [
".am0.yahoodns.net",
"mta5.am0.yahoodns.net",
"mta6.am0.yahoodns.net",
"mta7.am0.yahoodns.net"
]
}
},
"policies": {
"aol.com": {
"policy-alias": "yahoo"
},
"comcast.net": {
"mode": "enforce",
"mxs": [
"mx1.comcast.net",
"mx2.comcast.net"
]
},
"eff.org": {
"mode": "testing",
"mxs": [
".eff.org"
]
},
"facebook.com": {
"mode": "testing",
"mxs": [
".facebook.com"
]
},
"gmail.com": {
"mode": "enforce",
"mxs": [
"gmail-smtp-in.l.google.com",
".gmail-smtp-in.l.google.com"
]
},
"hotmail.com": {
"policy-alias": "outlook"
},
"icloud.com": {
"policy-alias": "icloud"
},
"live.com": {
"policy-alias": "outlook"
},
"me.com": {
"policy-alias": "icloud"
},
"msn.com": {
"policy-alias": "outlook"
},
"outlook.com": {
"policy-alias": "outlook"
},
"qq.com": {
"mode": "testing",
"mxs": [
".qq.com"
]
},
"rocketmail.com": {
"policy-alias": "yahoo"
},
"salesforce.com": {
"policy-alias": "google"
},
"yahoo.com": {
"policy-alias": "yahoo"
},
"yahoogroups.com": {
"policy-alias": "yahoo"
},
"yandex.ru": {
"mode": "testing",
"mxs": [
".yandex.ru"
]
},
"ymail.com": {
"policy-alias": "yahoo"
},
"0xheap.org": {
"mode": "testing",
"mxs": [
"mail.0xheap.org"
]
},
"alainwolf.ch": {
"mode": "enforce",
"mxs": [
"norris.urown.net",
"pace.urown.net",
"mail.urown.net"
]
},
"alainwolf.net": {
"mode": "enforce",
"mxs": [
"norris.urown.net",
"pace.urown.net",
"mail.urown.net"
]
},
"apbox.de": {
"mode": "testing",
"mxs": [
"srv.apbox.de"
]
},
"avdagic.net": {
"mode": "testing",
"mxs": [
"avdagic.net"
]
},
"bfg-10k.ru": {
"mode": "testing",
"mxs": [
"orion.bfg-10k.ru"
]
},
"bitpath.de": {
"mode": "testing",
"mxs": [
"bitpath.de"
]
},
"cfenns.de": {
"mode": "testing",
"mxs": [
"mail.cfenns.de"
]
},
"chas.se": {
"mode": "testing",
"mxs": [
"mail.chas.se"
]
},
"chatras.me": {
"mode": "testing",
"mxs": [
"smtp.chatras.me"
]
},
"compucation.de": {
"mode": "enforce",
"mxs": [
"mail.compucation.de"
]
},
"crasline.de": {
"mode": "testing",
"mxs": [
"ina.pt-server.de"
]
},
"dahoam.de": {
"mode": "testing",
"mxs": [
"cloud.eltrich.name",
"axon.gand.de"
]
},
"davidkevork.me": {
"mode": "testing",
"mxs": [
"mx.zoho.com",
"mx2.zoho.com"
]
},
"dayman.net": {
"mode": "testing",
"mxs": [
"dayman.net"
]
},
"deepztream.com": {
"mode": "testing",
"mxs": [
"deepztream.com",
"mail.deepztream.com"
]
},
"delfic.org": {
"mode": "testing",
"mxs": [
".delfic.org"
]
},
"dietrich.cx": {
"mode": "enforce",
"mxs": [
"mxext1.mailbox.org",
"mxext2.mailbox.org",
"mxext3.mailbox.org"
]
},
"eltrich.name": {
"mode": "testing",
"mxs": [
"cloud.eltrich.name",
"axon.gand.de"
]
},
"eruditium.org": {
"mode": "testing",
"mxs": [
"mail.eruditium.org"
]
},
"expertisale.com": {
"mode": "testing",
"mxs": [
"smtpmx2.expertisale.com",
"smtpmx3.expertisale.com"
]
},
"fabje.nl": {
"mode": "testing",
"mxs": [
"mail.fabje.nl",
"in.hes.trendmicro.eu"
]
},
"familieblume.nl": {
"mode": "testing",
"mxs": [
"in.hes.trendmicro.eu",
"mail.fabje.nl"
]
},
"fau.org": {
"mode": "testing",
"mxs": [
"mail.fau.org"
]
},
"fayeline.nl": {
"mode": "testing",
"mxs": [
"mail.fabje.nl"
]
},
"federation-interstellar.org": {
"mode": "enforce",
"mxs": [
"norris.urown.net",
"pace.urown.net",
"mail.urown.net"
]
},
"fivl.it": {
"mode": "testing",
"mxs": [
".fivl.it"
]
},
"flawy.de": {
"mode": "enforce",
"mxs": [
"lx1.flawy.de"
]
},
"friendlyfire.ca": {
"mode": "testing",
"mxs": [
"mail.friendlyfire.ca"
]
},
"gaertner-im-internet.de": {
"mode": "testing",
"mxs": [
"mailtomailserver08.de"
]
},
"grepular.com": {
"mode": "enforce",
"mxs": [
"mail.grepular.com"
]
},
"gwalarn.eu": {
"mode": "testing",
"mxs": [
"gwalarn.eu",
"saintlu.gwalarn.eu"
]
},
"hypermeganet.uk": {
"mode": "testing",
"mxs": [
"mail.hypermeganet.uk",
"mail2.hypermeganet.uk"
]
},
"iddya.com": {
"mode": "testing",
"mxs": [
".iddya.com"
]
},
"itzer.de": {
"mode": "enforce",
"mxs": [
"mail.itzer.de"
]
},
"joelmediatv.de": {
"mode": "testing",
"mxs": [
"mail.codethink.de"
]
},
"kjkobes.com": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"knthost.com": {
"mode": "testing",
"mxs": [
"mx.knthost.com",
"secure-mx.knthost.com",
"inbound01.knthost.com",
"secure-inbound01.knthost.com",
"inbound02.knthost.com",
"secure-inbound02.knthost.com"
]
},
"krapace.fr": {
"mode": "testing",
"mxs": [
"mail.krapace.fr"
]
},
"latinist.net": {
"mode": "testing",
"mxs": [
"latinist.net",
"mail.latinist.net"
]
},
"linecorp.com": {
"mode": "testing",
"mxs": [
"mx1.navercorp.com",
"mx2.navercorp.com"
]
},
"linuxfirewall.no-ip.org": {
"mode": "testing",
"mxs": [
"linuxfirewall.no-ip.org"
]
},
"livoris.net": {
"mode": "enforce",
"mxs": [
"livoris.net",
"chris-schuster.net"
]
},
"locker.email": {
"mode": "testing",
"mxs": [
"locker.email"
]
},
"luup.info": {
"mode": "testing",
"mxs": [
"adrastea.luup.info"
]
},
"macaw.me": {
"mode": "testing",
"mxs": [
"mail.macaw.me"
]
},
"maddes.net": {
"mode": "testing",
"mxs": [
"mail.maddes.net"
]
},
"miggy.org": {
"mode": "enforce",
"mxs": [
"mail.fysh.org"
]
},
"misguide.de": {
"mode": "testing",
"mxs": [
"h18.ogga.de"
]
},
"modum.by": {
"mode": "enforce",
"mxs": [
"mail.office.modum.by"
]
},
"mpcompany.ru": {
"mode": "testing",
"mxs": [
"mx.mpcompany.ru",
".mpcompany.ru"
]
},
"mycloudmail.ooo": {
"mode": "testing",
"mxs": [
"mail.mycloudmail.ooo"
]
},
"myriapolis.net": {
"mode": "testing",
"mxs": [
".myriapolis.net"
]
},
"naver.com": {
"mode": "testing",
"mxs": [
".naver.com"
]
},
"navercorp.com": {
"mode": "testing",
"mxs": [
".navercorp.com"
]
},
"neffets.de": {
"mode": "testing",
"mxs": [
"mail.neffets.de"
]
},
"node-nine.com": {
"mode": "testing",
"mxs": [
"mx2.node-nine.com"
]
},
"nottori.com": {
"mode": "testing",
"mxs": [
"mail.nottori.com"
]
},
"pharmbiotest.com.ua": {
"mode": "testing",
"mxs": [
"pharmbiotest.com.ua"
]
},
"pt-server.de": {
"mode": "testing",
"mxs": [
"ina.pt-server.de"
]
},
"rbbaader.de": {
"mode": "testing",
"mxs": [
"ina.pt-server.de"
]
},
"rbr.info": {
"mode": "testing",
"mxs": [
"mail.eruditium.org"
]
},
"reisebuero-baader.de": {
"mode": "testing",
"mxs": [
"ina.pt-server.de"
]
},
"saccani.net": {
"mode": "testing",
"mxs": [
".fivl.it"
]
},
"sheogorath.shivering-isles.com": {
"mode": "testing",
"mxs": [
"srv02.shivering-isles.com"
]
},
"shivering-isles.com": {
"mode": "testing",
"mxs": [
"srv02.shivering-isles.com"
]
},
"spodhuis.org": {
"mode": "enforce",
"mxs": [
"mx.spodhuis.org"
]
},
"teichsurfer.de": {
"mode": "testing",
"mxs": [
"one.teichsurfer.de"
]
},
"thelinuxtree.net": {
"mode": "testing",
"mxs": [
".thelinuxtree.net"
]
},
"tspu.edu.ru": {
"mode": "testing",
"mxs": [
"mail.tspu.edu.ru"
]
},
"tspu.ru": {
"mode": "testing",
"mxs": [
"mail.tspu.edu.ru"
]
},
"4zal.net": {
"mode": "enforce",
"mxs": [
".4zal.net",
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"anongoth.pl": {
"mode": "enforce",
"mxs": [
"mail.anongoth.pl"
]
},
"arkadiyt.com": {
"mode": "enforce",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"bingbong.epac.to": {
"mode": "testing",
"mxs": [
"bingbong.epac.to"
]
},
"bjrn.io": {
"mode": "testing",
"mxs": [
"mail.bjrn.io"
]
},
"boerner.click": {
"mode": "testing",
"mxs": [
".boerner.click",
"hfyqtgmxim0iim3l.myfritz.net"
]
},
"bolshaw.me.uk": {
"mode": "testing",
"mxs": [
"vm1.bolshaw.me.uk",
"vm2.bolshaw.me.uk"
]
},
"c3w.at": {
"mode": "enforce",
"mxs": [
"dergeraet.c3w.at"
]
},
"cert.br": {
"mode": "testing",
"mxs": [
"woq.cert.br"
]
},
"chamberlain.net.au": {
"mode": "testing",
"mxs": [
"mail.chamberlain.net.au",
"mail2.chamberlain.net.au",
"mail3.chamberlain.net.au"
]
},
"clearbus.fr": {
"mode": "testing",
"mxs": [
"zimbra.clearbus.fr"
]
},
"conchaudron.net": {
"mode": "testing",
"mxs": [
"mail.conchaudron.net",
".conchaudron.net"
]
},
"corecha.in": {
"mode": "testing",
"mxs": [
"mx.corecha.in"
]
},
"cosysco.com": {
"mode": "testing",
"mxs": [
"mail.mobydog.net"
]
},
"crustytoothpaste.net": {
"mode": "testing",
"mxs": [
".crustytoothpaste.net"
]
},
"decimatechnologies.eu": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"desgrange.net": {
"mode": "testing",
"mxs": [
".desgrange.net"
]
},
"desu.ne.jp": {
"mode": "testing",
"mxs": [
"kanna.desu.ne.jp",
"mx.desu.ne.jp"
]
},
"dismail.de": {
"mode": "enforce",
"mxs": [
"mx1.dismail.de",
"mx2.dismail.de"
]
},
"druwe.net": {
"mode": "enforce",
"mxs": [
"delores.druwe.net"
]
},
"ergobyte.gr": {
"mode": "testing",
"mxs": [
".ergobyte.gr"
]
},
"f00f.org": {
"mode": "enforce",
"mxs": [
"proxima.stupidest.org"
]
},
"familieverberne.nl": {
"mode": "testing",
"mxs": [
"smtp.verberne.nu"
]
},
"fbreest.de": {
"mode": "testing",
"mxs": [
"mail.fbreest.de"
]
},
"fireserve.com": {
"mode": "testing",
"mxs": [
"mail.fireserve.net",
"mx1.fireserve.net"
]
},
"fireserve.net": {
"mode": "testing",
"mxs": [
"mail.fireserve.net",
"mx1.fireserve.net"
]
},
"flarn.com": {
"mode": "testing",
"mxs": [
"mail.flarn.com"
]
},
"fran.cr": {
"mode": "testing",
"mxs": [
".fran.cr"
]
},
"getappetite.tv": {
"mode": "testing",
"mxs": [
"mail.getappetite.tv"
]
},
"ggp2.com": {
"mode": "enforce",
"mxs": [
"c.fsckd.com",
"d.fsckd.com"
]
},
"gkd-el.de": {
"mode": "enforce",
"mxs": [
"mailgw.gkd-el.de",
"filter.gkd-el.de"
]
},
"guyromm.com": {
"mode": "testing",
"mxs": [
"mx.guyromm.com"
]
},
"harrysmallbones.co.uk": {
"mode": "testing",
"mxs": [
"mail.harrysmallbones.co.uk",
"harrysmallbones.co.uk"
]
},
"hesketh.net.au": {
"mode": "testing",
"mxs": [
"mail.hesketh.net.au"
]
},
"incenp.org": {
"mode": "enforce",
"mxs": [
"mail.incenp.org"
]
},
"iq.pl": {
"mode": "testing",
"mxs": [
"mail.iq.pl"
]
},
"jcea.es": {
"mode": "testing",
"mxs": [
"smtp.jcea.es"
]
},
"jtg.business": {
"mode": "testing",
"mxs": [
"box.jtg.business"
]
},
"jvb.ca": {
"mode": "testing",
"mxs": [
".jvb.ca"
]
},
"klausen.dk": {
"mode": "enforce",
"mxs": [
"mail.klausen.dk"
]
},
"klingele.me": {
"mode": "testing",
"mxs": [
"mail.leonklingele.de",
"alt1.mail.leonklingele.de",
"alt2.mail.leonklingele.de"
]
},
"ko-sys.com": {
"mode": "enforce",
"mxs": [
"smtp.ko-sys.com"
]
},
"kubica.ch": {
"mode": "enforce",
"mxs": [
".burzum.ch"
]
},
"levinus.de": {
"mode": "testing",
"mxs": [
"mail.levinus.de"
]
},
"lifechurch.at": {
"mode": "testing",
"mxs": [
"mail.lifechurch.at"
]
},
"maclemon.at": {
"mode": "enforce",
"mxs": [
"dungeon.maclemon.at"
]
},
"menthiere.fr": {
"mode": "testing",
"mxs": [
".mail.gandi.net"
]
},
"michaelpjohnson.com": {
"mode": "testing",
"mxs": [
"mail.michaelpjohnson.com",
"michaelpjohnson.com"
]
},
"mnium.de": {
"mode": "testing",
"mxs": [
"mail.mnium.de"
]
},
"monopod.net": {
"mode": "testing",
"mxs": [
".electricembers.net"
]
},
"nic.br": {
"mode": "testing",
"mxs": [
"mail.nic.br",
"enqueuer.nic.br"
]
},
"ninetailed.ninja": {
"mode": "testing",
"mxs": [
".ninetailed.ninja"
]
},
"ninov.de": {
"mode": "testing",
"mxs": [
"ofen.nv.gw"
]
},
"nothing.net.nz": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com"
]
},
"petersons.me": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch"
]
},
"pf.id.au": {
"mode": "testing",
"mxs": [
".pf.id.au",
".ironicfate.com.au"
]
},
"ppt.com": {
"mode": "testing",
"mxs": [
".ppt.com"
]
},
"privacyweek.at": {
"mode": "testing",
"mxs": [
"dergeraet.c3w.at"
]
},
"raitisoja.com": {
"mode": "testing",
"mxs": [
"box.prvcy.email"
]
},
"randolf.at": {
"mode": "enforce",
"mxs": [
"mail.randolf.at"
]
},
"registro.br": {
"mode": "testing",
"mxs": [
"clone.registro.br",
"clonev4.registro.br",
"fe.registro.br"
]
},
"s-hertogenbosch.nl": {
"mode": "testing",
"mxs": [
"mx1.s-hertogenbosch.nl",
"mx2.s-hertogenbosch.nl"
]
},
"sauerburger.io": {
"mode": "testing",
"mxs": [
"mail.sit-servers.net"
]
},
"sbs.co.nz": {
"mode": "testing",
"mxs": [
"mail.sbs.co.nz"
]
},
"schlarb.eu": {
"mode": "testing",
"mxs": [
".ninetailed.ninja"
]
},
"sdeziel.info": {
"mode": "enforce",
"mxs": [
"smtp.sdeziel.info"
]
},
"sertelon.fr": {
"mode": "testing",
"mxs": [
"smtp.sertelon.fr"
]
},
"sixpak.org": {
"mode": "enforce",
"mxs": [
"sixpak.sixpak.org",
".sixpak.org",
"sixpak.org"
]
},
"sufix.cz": {
"mode": "enforce",
"mxs": [
"sufix-cz.mail.protection.outlook.com"
]
},
"sunsetdynamics.com": {
"mode": "testing",
"mxs": [
"mail.fireserve.net",
"mx1.fireserve.net"
]
},
"sven.de": {
"mode": "testing",
"mxs": [
"mail.sven.de"
]
},
"tala.dk": {
"mode": "testing",
"mxs": [
"mail.tala.dk",
"smtp.tala.dk",
"tala.dk"
]
},
"tepas.de": {
"mode": "testing",
"mxs": [
"mail.tepas.de"
]
},
"tgoss.de": {
"mode": "testing",
"mxs": [
"tgoss.de"
]
},
"thenetw.org": {
"mode": "testing",
"mxs": [
"thenetw-org.mail.protection.outlook.com"
]
},
"thewiesners.org": {
"mode": "testing",
"mxs": [
"box.thewiesners.org",
"thewiesners.org"
]
},
"tifaware.com": {
"mode": "testing",
"mxs": [
"sal.tifaware.com",
"mail.tifaware.com"
]
},
"tilde.team": {
"mode": "testing",
"mxs": [
".tilde.team"
]
},
"tynan.com": {
"mode": "testing",
"mxs": [
"cloud.tynan.com"
]
},
"valorizmusic.com": {
"mode": "testing",
"mxs": [
".ninetailed.ninja"
]
},
"volitans-software.com": {
"mode": "testing",
"mxs": [
"mail.volitans-software.com"
]
},
"vosky.fr": {
"mode": "testing",
"mxs": [
"aga.vosky.fr",
"scw.vosky.fr"
]
},
"wakesecure.com": {
"mode": "testing",
"mxs": [
"wakesecure.com",
"marcabel.com"
]
},
"webgma.co.il": {
"mode": "testing",
"mxs": [
"mx.webgma.co.il"
]
},
"xel.nl": {
"mode": "testing",
"mxs": [
"mx1.xel.nl",
"mx2.xel.nl",
"mx3.xel.nl"
]
},
"yoursafe.se": {
"mode": "testing",
"mxs": [
"mail.yoursafe.se"
]
},
"zl1ab.nz": {
"mode": "testing",
"mxs": [
"zl1ab.nz"
]
},
"babioch.de": {
"mode": "testing",
"mxs": [
"mail.babioch.de"
]
},
"bpce.fr": {
"mode": "testing",
"mxs": [
"mail-in.bpce-it.fr"
]
},
"curttech.com": {
"mode": "testing",
"mxs": [
"mail.curttech.net"
]
},
"dhautefeuille.eu": {
"mode": "enforce",
"mxs": [
"arch-server.dhautefeuille.eu"
]
},
"duesterhus.eu": {
"mode": "testing",
"mxs": [
".xqk7.com"
]
},
"durel.org": {
"mode": "enforce",
"mxs": [
"corrin.geekwu.org",
"arrakeen.geekwu.org"
]
},
"eckhofer.com": {
"mode": "testing",
"mxs": [
"mail.tribut.de"
]
},
"edam-volendam.nl": {
"mode": "testing",
"mxs": [
"gen1.edam-volendam.nl"
]
},
"fladnag.net": {
"mode": "testing",
"mxs": [
"mail.fladnag.net",
"gateway.mail.fladnag.net"
]
},
"hany.sk": {
"mode": "testing",
"mxs": [
".hany.sk"
]
},
"hewgill.net": {
"mode": "testing",
"mxs": [
"stratus.hewgill.net"
]
},
"it4sure.nl": {
"mode": "testing",
"mxs": [
"mx1.it4sure.cloud",
"mx2.it4sure.cloud",
"mail.it4sure.cloud"
]
},
"jndata.dk": {
"mode": "testing",
"mxs": [
"mailin01.jndata.dk",
"mailin02.jndata.dk",
"mailin03.jndata.dk"
]
},
"knop.eu": {
"mode": "testing",
"mxs": [
"srv01.knop.info"
]
},
"lancashirebeekeepers.org.uk": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"aspmx2.googlemail.com",
"aspmx3.googlemail.com"
]
},
"ledovskis.lv": {
"mode": "enforce",
"mxs": [
"ariake.ledovskis.lv"
]
},
"lmcm.io": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"mail.de": {
"mode": "enforce",
"mxs": [
"mx01.mail.de",
"mx02.mail.de"
]
},
"mattleidholm.com": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"mingjie.info": {
"mode": "testing",
"mxs": [
".mingjie.info",
".messagingengine.com"
]
},
"netcompany.com": {
"mode": "testing",
"mxs": [
"netcompany-com.mail.protection.outlook.com"
]
},
"netgalaxy.ca": {
"mode": "testing",
"mxs": [
"nyc.netgalaxy.ca"
]
},
"ozark.be": {
"mode": "testing",
"mxs": [
"mail.hypnotized.org"
]
},
"pa5am.nl": {
"mode": "enforce",
"mxs": [
"ipoac.nl"
]
},
"sanker.by": {
"mode": "testing",
"mxs": [
"mail.sanker.by"
]
},
"santoshpandit.com": {
"mode": "enforce",
"mxs": [
"mail.tutanota.de"
]
},
"saskpension.com": {
"mode": "testing",
"mxs": [
"saskpension-com.mail.protection.outlook.com"
]
},
"seffner-schlesier.de": {
"mode": "testing",
"mxs": [
".seffner-schlesier.de"
]
},
"sovereign-order-of-saint-john.org": {
"mode": "testing",
"mxs": [
"mxext1.mailbox.org",
"mxext2.mailbox.org",
"mxext3.mailbox.org"
]
},
"t-senger.de": {
"mode": "testing",
"mxs": [
".t-senger.de"
]
},
"taintedbit.com": {
"mode": "testing",
"mxs": [
"mail.taintedbit.com"
]
},
"thisishugo.com": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"vixrapedia.org": {
"mode": "enforce",
"mxs": [
"mail.vixrapedia.org"
]
},
"vulnscan.org": {
"mode": "testing",
"mxs": [
"mail.vulnscan.org"
]
},
"w4eg.de": {
"mode": "testing",
"mxs": [
"w4eg.de"
]
},
"wiktel.com": {
"mode": "enforce",
"mxs": [
"mail.wiktel.com"
]
},
"xylon.de": {
"mode": "testing",
"mxs": [
"mail.xylon.de"
]
},
"aegee.org": {
"mode": "enforce",
"mxs": [
"mail.aegee.org",
"mxf-1.aegee.org",
"mxf-2.aegee.org"
]
},
"anthonyvadala.me": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"artikel10.org": {
"mode": "enforce",
"mxs": [
"mxext1.mailbox.org",
"mxext2.mailbox.org",
"mxext3.mailbox.org"
]
},
"aztecface.email": {
"mode": "enforce",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"backschues.com": {
"mode": "enforce",
"mxs": [
"mail.backschues.net",
"mx0.backschues.net",
"mx00.backschues.net",
"mx01.backschues.net",
"mx1.backschues.net"
]
},
"backschues.de": {
"mode": "enforce",
"mxs": [
"mail.backschues.net",
"mx0.backschues.net",
"mx00.backschues.net",
"mx01.backschues.net",
"mx1.backschues.net"
]
},
"backschues.net": {
"mode": "enforce",
"mxs": [
"mail.backschues.net",
"mx0.backschues.net",
"mx00.backschues.net",
"mx01.backschues.net",
"mx1.backschues.net"
]
},
"bearsunderland.com": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"aspmx2.googlemail.com",
"aspmx3.googlemail.com"
]
},
"benjamin.computer": {
"mode": "testing",
"mxs": [
"mail.section9.london",
"post.section9.london"
]
},
"billaud.eu.org": {
"mode": "enforce",
"mxs": [
"www2.billaud.eu.org",
"billaud.eu.org"
]
},
"boenning.me": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"bolte.org": {
"mode": "enforce",
"mxs": [
"mail.bolte.org"
]
},
"bornwebserver.nl": {
"mode": "testing",
"mxs": [
"bornwebserver.nl",
"mail.bornwebserver.nl"
]
},
"bugabinga.net": {
"mode": "testing",
"mxs": [
"box.bugabinga.net"
]
},
"caletka.cz": {
"mode": "enforce",
"mxs": [
"flexi.oskarcz.net"
]
},
"castlehoward.co.uk": {
"mode": "testing",
"mxs": [
"mail.castlehoward.co.uk"
]
},
"cdom.de": {
"mode": "testing",
"mxs": [
"mailfilter2.cdom.de"
]
},
"ck-energy.de": {
"mode": "enforce",
"mxs": [
"alpha.mail.ck-energy.info",
"beta.mail.ck-energy.info"
]
},
"colincogle.name": {
"mode": "enforce",
"mxs": [
"rhymeswithmogul.com",
"colincogle.name",
"ec2.colincogle.name",
"greenpartyofnewmilford.org",
"mta-sts.rhymeswithmogul.com",
"mta-sts.colincogle.name",
"mta-sts.greenpartyofnewmilford.org"
]
},
"connordav.is": {
"mode": "enforce",
"mxs": [
"mx.zoho.com",
"mx2.zoho.com",
"mx3.zoho.com"
]
},
"dancingsnails.com": {
"mode": "testing",
"mxs": [
"mail.dancingsnails.com"
]
},
"ddimension.net": {
"mode": "enforce",
"mxs": [
"gamenet.ddimension.net"
]
},
"divegearexpress.com": {
"mode": "enforce",
"mxs": [
"smtp.divegearexpress.com",
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com",
"smtp.postmarkapp.com",
".messagingengine.com",
".divegearexpress.com",
".postmarkapp.com"
]
},
"domblogger.net": {
"mode": "enforce",
"mxs": [
"mail.domblogger.net"
]
},
"donnerdoof.de": {
"mode": "testing",
"mxs": [
"mail.donnerdoof.de"
]
},
"e9a.at": {
"mode": "testing",
"mxs": [
"mail.e9a.at"
]
},
"email.ctrl.blog": {
"mode": "testing",
"mxs": [
"email.ctrl.blog"
]
},
"french-interface.com": {
"mode": "testing",
"mxs": [
"french-interface.com"
]
},
"fruweb.de": {
"mode": "testing",
"mxs": [
"hermes.fruweb.de",
".mailbox.org"
]
},
"gehrke.in": {
"mode": "enforce",
"mxs": [
"mail.backschues.net",
"mx0.backschues.net",
"mx00.backschues.net",
"mx01.backschues.net",
"mx1.backschues.net"
]
},
"giebel.it": {
"mode": "testing",
"mxs": [
"mailfilter2.cdom.de"
]
},
"goppold.net": {
"mode": "enforce",
"mxs": [
"mail.goppold.net",
"mail2.goppold.net"
]
},
"halla.lv": {
"mode": "testing",
"mxs": [
"mail.halla.lv"
]
},
"hengroenet.de": {
"mode": "enforce",
"mxs": [
"mail.hengroenet.de"
]
},
"honigdachse.de": {
"mode": "testing",
"mxs": [
".honigdachse.de",
"mail.honigdachse.de"
]
},
"iatmgu.com": {
"mode": "testing",
"mxs": [
"mail.iatmgu.com"
]
},
"inethost.eu": {
"mode": "enforce",
"mxs": [
"mail.inethost.eu"
]
},
"it-zahner.de": {
"mode": "testing",
"mxs": [
"mx.it-zahner.net"
]
},
"jonaswitmer.ch": {
"mode": "enforce",
"mxs": [
"jonaswitmer.ch"
]
},
"js-webcoding.de": {
"mode": "enforce",
"mxs": [
"mail.js-webcoding.de"
]
},
"kc1hbk.com": {
"mode": "enforce",
"mxs": [
"ec2.colincogle.name",
"colincogle.name"
]
},
"kimihia.org.nz": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"kmm.im": {
"mode": "testing",
"mxs": [
"mail.domob.eu"
]
},
"koehn-consulting.com": {
"mode": "enforce",
"mxs": [
"mail.koehn.com",
".googlemail.com",
".aspmx.l.google.com",
"aspmx.l.google.com"
]
},
"koehn.com": {
"mode": "enforce",
"mxs": [
"mail.koehn.com",
".googlemail.com",
".aspmx.l.google.com",
"aspmx.l.google.com"
]
},
"kryptonresearch.com": {
"mode": "enforce",
"mxs": [
"mail.tutanota.de"
]
},
"laxu.de": {
"mode": "testing",
"mxs": [
"mx.nanubo.de"
]
},
"lemon-kiwi.co": {
"mode": "testing",
"mxs": [
"alt4.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"aspmx.l.google.com",
"alt2.aspmx.l.google.com"
]
},
"librelamp.com": {
"mode": "enforce",
"mxs": [
"librelamp.com"
]
},
"m9r1s.com": {
"mode": "testing",
"mxs": [
"mail.m9r1s.com",
"m9r1s.com"
]
},
"mach-politik.ch": {
"mode": "testing",
"mxs": [
"mach-politik.ch"
]
},
"mahlendur.de": {
"mode": "testing",
"mxs": [
"mail.mahlendur.de"
]
},
"mail.aegee.org": {
"mode": "enforce",
"mxs": [
"mail.aegee.org",
"mxf-1.aegee.org",
"mxf-2.aegee.org"
]
},
"mail.com": {
"mode": "testing",
"mxs": [
"mx00.mail.com",
"mx01.mail.com"
]
},
"megane.it": {
"mode": "testing",
"mxs": [
"mail.megane.it",
"mail2.megane.it",
"mail3.megane.it"
]
},
"meproduction.org": {
"mode": "testing",
"mxs": [
"meproduction.org",
".meproduction.org",
"mail.meproduction.org"
]
},
"mercedcapital.com": {
"mode": "enforce",
"mxs": [
"smtp1-mke.securence.com",
"smtp1-msp.securence.com"
]
},
"mewp.pl": {
"mode": "testing",
"mxs": [
"mail.mewp.pl"
]
},
"naundorf.it": {
"mode": "testing",
"mxs": [
"mail.bummelwelt.com"
]
},
"netera.com": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"onex.de": {
"mode": "testing",
"mxs": [
"efa1.onexdienste.de",
"efa2.onexdienste.de"
]
},
"pienpa.nl": {
"mode": "testing",
"mxs": [
"mail.pienpa.nl"
]
},
"piratenpartei.at": {
"mode": "testing",
"mxs": [
"piratenpartei.at",
"pikachu.piratenpartei.at"
]
},
"piratenpartei.de": {
"mode": "testing",
"mxs": [
"mail.piratenpartei.de",
"piratenpartei.de"
]
},
"projectografico.com": {
"mode": "testing",
"mxs": [
"mail.projectografico.com"
]
},
"protonmail.com": {
"mode": "enforce",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"robwillis.org": {
"mode": "testing",
"mxs": [
"vade-in1.mail.dreamhost.com",
"vade-in2.mail.dreamhost.com"
]
},
"rupostel.com": {
"mode": "testing",
"mxs": [
"mx.aububu.com"
]
},
"s2net.ch": {
"mode": "testing",
"mxs": [
"smtp.s2net.ch"
]
},
"salford.gov.uk": {
"mode": "testing",
"mxs": [
"mailmx.salford.gov.uk",
"mailout.ictservices.co.uk"
]
},
"sandbornvoglfarms.com": {
"mode": "testing",
"mxs": [
"www.sandbornvoglfarms.com"
]
},
"saulchristie.com": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"schleifenbaum.email": {
"mode": "enforce",
"mxs": [
"mail.js-webcoding.de"
]
},
"schleifenbaum.org": {
"mode": "enforce",
"mxs": [
"mail.js-webcoding.de"
]
},
"scotthsmith.com": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"secure.mailbox.org": {
"mode": "testing",
"mxs": [
"mxtls1.mailbox.org",
"mxtls2.mailbox.org"
]
},
"seite3.net": {
"mode": "testing",
"mxs": [
"post.seite3.net"
]
},
"semox.de": {
"mode": "enforce",
"mxs": [
"www.semox.de"
]
},
"setemares.org": {
"mode": "enforce",
"mxs": [
"mail.setemares.org",
".setemares.org"
]
},
"skynet-devices.com": {
"mode": "enforce",
"mxs": [
"mail.tutanota.de"
]
},
"snowpaws.de": {
"mode": "enforce",
"mxs": [
"mail.snowpaws.de"
]
},
"sodium.gr": {
"mode": "testing",
"mxs": [
"mail.sodium.gr"
]
},
"srs-sys.de": {
"mode": "enforce",
"mxs": [
"mx01a.srs-sys.de",
"mx01b.srs-sys.de",
"mx02a.srs-sys.de",
"mx02b.srs-sys.de"
]
},
"svengo.de": {
"mode": "testing",
"mxs": [
"mail.svengo.net"
]
},
"systemausfall.org": {
"mode": "enforce",
"mxs": [
"mx1.systemausfall.org",
"mx2.systemausfall.org"
]
},
"tbz-pariv.de": {
"mode": "enforce",
"mxs": [
"mail.tbz-pariv.de",
"mail2.tbz-pariv.de"
]
},
"technikumnukleoniczne.pl": {
"mode": "enforce",
"mxs": [
"TechnikumNukleoniczne-pl.mail.protection.outlook.com",
"mx1.comcast.net",
"mx2.comcast.net"
]
},
"the.sexy": {
"mode": "testing",
"mxs": [
"mail.the.sexy"
]
},
"thinking-bit.com": {
"mode": "testing",
"mxs": [
"mail.thinking-bit.com"
]
},
"thinktank.co.nz": {
"mode": "testing",
"mxs": [
"thinktank.co.nz",
"mail.thinktank.co.nz",
"mail2.thinktank.co.nz",
"southern.thinktank.co.nz"
]
},
"tresdouteux.com": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch"
]
},
"treussart.com": {
"mode": "testing",
"mxs": [
".treussart.com"
]
},
"tutanota.com": {
"mode": "testing",
"mxs": [
"mail.tutanota.de"
]
},
"vm-0.com": {
"mode": "enforce",
"mxs": [
"mx.vm-0.com"
]
},
"waldkindergarten-ausstattung.de": {
"mode": "testing",
"mxs": [
"mail.bummelwelt.com"
]
},
"ybti.net": {
"mode": "enforce",
"mxs": [
"ybti.net"
]
},
"zip-support.de": {
"mode": "testing",
"mxs": [
"mail.zip-support.de"
]
},
"accessnetwork.ro": {
"mode": "testing",
"mxs": [
"zimbra.accessnetwork.ro"
]
},
"acloud.one": {
"mode": "testing",
"mxs": [
"srv02.acloud.one",
"mail.acloud.one",
"autodiscover.acloud.one"
]
},
"aipi.de": {
"mode": "enforce",
"mxs": [
"mx.aipi.de"
]
},
"airpost.pw": {
"mode": "enforce",
"mxs": [
"w.robotham.dev",
"mx2.robotham.dev"
]
},
"allnetwork.de": {
"mode": "testing",
"mxs": [
"mail.allnetwork.de"
]
},
"artemyev.com": {
"mode": "testing",
"mxs": [
"naksitrallid.com"
]
},
"artemyev.net": {
"mode": "testing",
"mxs": [
"naksitrallid.com"
]
},
"artemyev.org": {
"mode": "testing",
"mxs": [
"naksitrallid.com"
]
},
"cgfreaks.com": {
"mode": "testing",
"mxs": [
"mail.cgfreaks.com"
]
},
"cpexre.com": {
"mode": "testing",
"mxs": [
"cpexre-com.mail.protection.outlook.com"
]
},
"cryptomilk.org": {
"mode": "testing",
"mxs": [
"milliways.cryptomilk.org"
]
},
"dotmol.nl": {
"mode": "testing",
"mxs": [
"sigma.dotmol.nl"
]
},
"emilstahl.dk": {
"mode": "enforce",
"mxs": [
"mx1.smtp.goog",
"mx2.smtp.goog",
"mx3.smtp.goog",
"mx4.smtp.goog"
]
},
"klinikum-oldenburg.de": {
"mode": "testing",
"mxs": [
"mail.klinikum-oldenburg.de",
"mx.aipi.de"
]
},
"ldwg.us": {
"mode": "testing",
"mxs": [
"mail.ldwg.us"
]
},
"lists.aegee.org": {
"mode": "enforce",
"mxs": [
"mail.aegee.org",
"mxf-1.aegee.org",
"mxf-2.aegee.org"
]
},
"maelstrom.ninja": {
"mode": "testing",
"mxs": [
".maelstrom.ninja"
]
},
"mailbox.org": {
"mode": "testing",
"mxs": [
"mx1.mailbox.org",
"mx2.mailbox.org",
"mx3.mailbox.org",
"mxtls1.mailbox.org",
"mxtls2.mailbox.org"
]
},
"php.watch": {
"mode": "testing",
"mxs": [
"mx.yandex.net"
]
},
"railduction.eu": {
"mode": "testing",
"mxs": [
"mail.railduction.eu"
]
},
"systemli.org": {
"mode": "enforce",
"mxs": [
"mail.systemli.org"
]
},
"touraineverte.com": {
"mode": "testing",
"mxs": [
"mxb.ovh.net",
"mx3.ovh.net",
"mx4.ovh.net"
]
},
"wpd-group.com": {
"mode": "testing",
"mxs": [
"mta01.wpd.de",
"mta02.wpd.de"
]
},
"wpd.de": {
"mode": "testing",
"mxs": [
"mta01.wpd.de",
"mta02.wpd.de"
]
},
"wpd.fr": {
"mode": "testing",
"mxs": [
"mta01.wpd.de",
"mta02.wpd.de"
]
},
"burzmali.com": {
"mode": "enforce",
"mxs": [
"ix.burzmali.com"
]
},
"centerclick.org": {
"mode": "testing",
"mxs": [
"mail.centerclick.org"
]
},
"davej.org": {
"mode": "testing",
"mxs": [
"mail.centerclick.org"
]
},
"dombox.org": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"espci.fr": {
"mode": "testing",
"mxs": [
"mx3.espci.fr",
"mx4.espci.fr"
]
},
"eurocontrol.int": {
"mode": "enforce",
"mxs": [
"esa1.eurocontrol.c3s2.iphmx.com",
"esa2.eurocontrol.c3s2.iphmx.com"
]
},
"grupoicot.es": {
"mode": "testing",
"mxs": [
"correo.grupoicot.es"
]
},
"hmdb.org": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"kwain.net": {
"mode": "testing",
"mxs": [
"smtp.kwain.net",
"spool.mail.gandi.net",
"fb.mail.gandi.net"
]
},
"mnfgroup.limited": {
"mode": "testing",
"mxs": [
"mail.mnfgroup.limited",
"mail2.mnfgroup.limited"
]
},
"rhymeswithmogul.com": {
"mode": "testing",
"mxs": [
"ec2.colincogle.name",
"colincogle.name"
]
},
"rogerkunz.ch": {
"mode": "testing",
"mxs": [
"mail.rogerkunz.ch",
"rogerkunz.ch"
]
},
"scarf.org.uk": {
"mode": "testing",
"mxs": [
".scarf.org.uk"
]
},
"sequitur.tech": {
"mode": "testing",
"mxs": [
"santos.coffee.co.uk",
"colombia.coffee.co.uk"
]
},
"spendy.org": {
"mode": "testing",
"mxs": [
"toasty.spendy.org"
]
},
"synergynh.com": {
"mode": "testing",
"mxs": [
"mail.centerclick.org"
]
},
"vectro.co": {
"mode": "testing",
"mxs": [
".mail.protection.outlook.com"
]
},
"alfa-system.pl": {
"mode": "testing",
"mxs": [
"smtp.alfa-system.pl",
"mx-backup.alfa-system.pl"
]
},
"allombradelpero.it": {
"mode": "testing",
"mxs": [
"as01.secureme.it",
"as02.secureme.it"
]
},
"blackhats.org": {
"mode": "testing",
"mxs": [
"mx.blackhats.org"
]
},
"boothlabs.me": {
"mode": "testing",
"mxs": [
"Jolteon.boothlabs.me",
"boothlabs.me"
]
},
"cahagne.fr": {
"mode": "testing",
"mxs": [
"mail.cahagne.fr"
]
},
"camsleygrangerda.org.uk": {
"mode": "testing",
"mxs": [
"linsrv104.linuxcontrolpanel.co.uk"
]
},
"cardiff.gov.uk": {
"mode": "testing",
"mxs": [
"mail2.cardiff.gov.uk",
"mail3.cardiff.gov.uk",
"mail4.cardiff.gov.uk"
]
},
"carolineeball.com": {
"mode": "enforce",
"mxs": [
".johndball.com",
".carolineeball.com",
".carolineball.com",
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"cca-bank.com": {
"mode": "testing",
"mxs": [
"mail.cca-bank.com"
]
},
"chicagocomputers.com.ar": {
"mode": "enforce",
"mxs": [
"vade-in1.mail.dreamhost.com",
"vade-in2.mail.dreamhost.com"
]
},
"clinique-velpeau.com": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"aspmx3.googlemail.com",
"aspmx2.googlemail.com"
]
},
"cloudadministrator.com.au": {
"mode": "testing",
"mxs": [
"forecast.rain.email"
]
},
"code5.ca": {
"mode": "testing",
"mxs": [
"mail.code5.ca"
]
},
"compukix.net": {
"mode": "testing",
"mxs": [
"smtp.compukix.net",
"mail.compukix.net",
".compukix.net",
"bumblebee.vn2.compukix.net"
]
},
"coreboot.org": {
"mode": "testing",
"mxs": [
"mail.coreboot.org"
]
},
"corpocar.com": {
"mode": "testing",
"mxs": [
"corpocar.com",
"smtp.corpocar.com"
]
},
"countyhall.london": {
"mode": "testing",
"mxs": [
"linsrv104.linuxcontrolpanel.co.uk"
]
},
"cybercrew.cc": {
"mode": "testing",
"mxs": [
"slartibartfass.ursa-minor-beta.org",
"humma-kavula.ursa-minor-beta.org"
]
},
"denaehula.com": {
"mode": "testing",
"mxs": [
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com",
"aspmx.l.google.com"
]
},
"desfontain.es": {
"mode": "testing",
"mxs": [
"desfontain.es",
"damien.desfontain.es",
"smtp.desfontain.es",
"www.desfontain.es"
]
},
"dssr.ch": {
"mode": "testing",
"mxs": [
"mail.dssr.ch"
]
},
"eagleview.it": {
"mode": "testing",
"mxs": [
"us-smtp-inbound-1.mimecast.com",
"us-smtp-inbound-2.mimecast.com"
]
},
"ecki-netz.de": {
"mode": "testing",
"mxs": [
"mail.ecki-netz.de"
]
},
"fivegenerationshomestead.com": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"frauenarzt-niendorf.de": {
"mode": "testing",
"mxs": [
"srv01.knop.info"
]
},
"freehold.countyhall.london": {
"mode": "testing",
"mxs": [
"linsrv104.linuxcontrolpanel.co.uk"
]
},
"fripost.org": {
"mode": "testing",
"mxs": [
"mx1.fripost.org",
"mx2.fripost.org"
]
},
"gauthier.dk": {
"mode": "enforce",
"mxs": [
"mail.wjg.dk"
]
},
"giesen.me": {
"mode": "testing",
"mxs": [
"mx.giesen.me",
"mx2.giesen.me",
"smtp.giesen.me",
"ego.giesen.me",
"psyche.giesen.me"
]
},
"graeber.dev": {
"mode": "enforce",
"mxs": [
"c.fsckd.com",
"d.fsckd.com"
]
},
"hacktivis.me": {
"mode": "testing",
"mxs": [
".the-delta.net.eu.org"
]
},
"halmex.com.mx": {
"mode": "testing",
"mxs": [
"mail.halmex.com.mx"
]
},
"handorf.org": {
"mode": "testing",
"mxs": [
"mail.handorf.org"
]
},
"hase-online.eu": {
"mode": "testing",
"mxs": [
"mail.hase-online.eu"
]
},
"hermod.arnested.dk": {
"mode": "testing",
"mxs": [
"hermod.arnested.dk"
]
},
"hiya.be": {
"mode": "testing",
"mxs": [
"mail.hiya.be"
]
},
"ing.unlp.edu.ar": {
"mode": "testing",
"mxs": [
"ampere.ing.unlp.edu.ar",
"joule.ing.unlp.edu.ar",
"smtp.ing.unlp.edu.ar"
]
},
"intelliflo.com": {
"mode": "testing",
"mxs": [
"intelliflo-com.mail.protection.outlook.com"
]
},
"iris.mystia.org": {
"mode": "testing",
"mxs": [
"lyra.margatroid.com"
]
},
"it-inside.ch": {
"mode": "enforce",
"mxs": [
"mx.it-inside.ch"
]
},
"jacksball.com": {
"mode": "enforce",
"mxs": [
".johndball.com",
".jacksball.com",
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"jamesevans.is": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"jenzi.com": {
"mode": "testing",
"mxs": [
"webmail.jenzi.com"
]
},
"jenzi.de": {
"mode": "testing",
"mxs": [
"webmail.jenzi.com"
]
},
"jltctech.com": {
"mode": "enforce",
"mxs": [
".johndball.com",
".jltctech.com",
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"johndball.com": {
"mode": "enforce",
"mxs": [
".johndball.com",
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"juggle.fr": {
"mode": "testing",
"mxs": [
"mail.juggle.fr"
]
},
"kalatzis.net": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"knockaert.nl": {
"mode": "enforce",
"mxs": [
"mail.knockaert.nl"
]
},
"kresta.no": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"krvtz.net": {
"mode": "testing",
"mxs": [
"webcookies.org"
]
},
"landegge.nl": {
"mode": "testing",
"mxs": [
"landegge-nl.mail.protection.outlook.com"
]
},
"lanodan.eu": {
"mode": "testing",
"mxs": [
".the-delta.net.eu.org"
]
},
"laurencball.com": {
"mode": "enforce",
"mxs": [
".johndball.com",
".laurencball.com",
".laurenball.com",
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"lindemann.space": {
"mode": "testing",
"mxs": [
".lindemann.space"
]
},
"lohmeyer-it.de": {
"mode": "testing",
"mxs": [
"mail.lohmeyer-it.de"
]
},
"lohmeyer.cc": {
"mode": "testing",
"mxs": [
"mail.srv05.de"
]
},
"lumicon.co.uk": {
"mode": "testing",
"mxs": [
"linsrv104.linuxcontrolpanel.co.uk"
]
},
"margatroid.com": {
"mode": "testing",
"mxs": [
"lyra.margatroid.com"
]
},
"martinploug.dk": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"marwan.ma": {
"mode": "testing",
"mxs": [
"mx.marwan.ma"
]
},
"mblmail.net": {
"mode": "testing",
"mxs": [
"mblmail.net"
]
},
"mdewendt.de": {
"mode": "enforce",
"mxs": [
"ben.mdewendt.de",
"tim.mdewendt.de"
]
},
"megacash.com.ve": {
"mode": "testing",
"mxs": [
"mx.megacash.com.ve"
]
},
"midlothian.gov.uk": {
"mode": "testing",
"mxs": [
"cust13649-1-in.mailcontrol.com",
"cust13649-2-in.mailcontrol.com"
]
},
"mmn.on.ca": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"mohlek.net": {
"mode": "enforce",
"mxs": [
"mail.mohlek.net"
]
},
"mystia.org": {
"mode": "testing",
"mxs": [
"lyra.margatroid.com"
]
},
"mza.com": {
"mode": "testing",
"mxs": [
"dns1.mza.com",
"dns2.mza.com",
"dns3.mza.com"
]
},
"nerdheim.se": {
"mode": "enforce",
"mxs": [
"mail.nerdheim.se"
]
},
"nydig.com": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"aspmx2.googlemail.com",
"aspmx3.googlemail.com"
]
},
"nztechie.com": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch"
]
},
"osemka.biz": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"aspmx2.googlemail.com",
"aspmx3.googlemail.com",
"aspmx4.googlemail.com",
"aspmx5.googlemail.com"
]
},
"owl-ict.nl": {
"mode": "testing",
"mxs": [
"smtp.emailadmin.nl",
".emailadmin.nl",
".owl-ict.nl"
]
},
"pmf.uns.ac.rs": {
"mode": "enforce",
"mxs": [
"mail.pmf.uns.ac.rs"
]
},
"podolak.net": {
"mode": "testing",
"mxs": [
"webmail.podolak.net"
]
},
"pokeinthe.io": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"polak.email": {
"mode": "enforce",
"mxs": [
"npmail.at",
"it.np-edv.at"
]
},
"professionaldigitalservices.ltd.uk": {
"mode": "testing",
"mxs": [
"linsrv104.linuxcontrolpanel.co.uk"
]
},
"psharp.net": {
"mode": "testing",
"mxs": [
"linsrv104.linuxcontrolpanel.co.uk"
]
},
"r42.ch": {
"mode": "testing",
"mxs": [
"mail.r42.ch"
]
},
"rain.email": {
"mode": "testing",
"mxs": [
"sa.rain.email"
]
},
"rin.rs": {
"mode": "enforce",
"mxs": [
"mail.rin.rs"
]
},
"section9.co.uk": {
"mode": "testing",
"mxs": [
"mail.section9.london",
"post.section9.london"
]
},
"secumail.nl": {
"mode": "testing",
"mxs": [
"inbound-smtp.eu-west-1.amazonaws.com",
"mail.secumail.nl"
]
},
"secureme.it": {
"mode": "enforce",
"mxs": [
"as01.secureme.it",
"as02.secureme.it"
]
},
"shoelace.org": {
"mode": "testing",
"mxs": [
"shoelace.org"
]
},
"spekadyon.org": {
"mode": "testing",
"mxs": [
"rainbow-mail.spekadyon.org",
"smtp.spekadyon.org",
"mail.spekadyon.org",
"imap.spekadyon.org"
]
},
"startmail.com": {
"mode": "enforce",
"mxs": [
"mx1.startmail.com",
"mx2.startmail.com",
".smtp.startmail.com"
]
},
"stonefirefarms.com": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"tech-ninja.de": {
"mode": "enforce",
"mxs": [
"alderaan.tech-ninja.de"
]
},
"trampel.org": {
"mode": "testing",
"mxs": [
"mail.trampel.org"
]
},
"trindonball.com": {
"mode": "enforce",
"mxs": [
".johndball.com",
".trindonball.com",
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"twelveletter.com": {
"mode": "testing",
"mxs": [
"mail.twelveletter.com"
]
},
"twolife.be": {
"mode": "enforce",
"mxs": [
"loki.twolife.be",
"hp.twolife.be"
]
},
"use.startmail.com": {
"mode": "enforce",
"mxs": [
"mx1.startmail.com",
"mx2.startmail.com",
".smtp.startmail.com"
]
},
"valasens.io": {
"mode": "testing",
"mxs": [
"mx.zoho.com",
"mx2.zoho.com",
"mx3.zoho.com"
]
},
"webcookies.org": {
"mode": "enforce",
"mxs": [
"webcookies.org"
]
},
"2718282.net": {
"mode": "enforce",
"mxs": [
"mx.2718282.net"
]
},
"2straws.com.au": {
"mode": "testing",
"mxs": [
"2straws-com-au.mail.protection.outlook.com"
]
},
"3733366.xyz": {
"mode": "enforce",
"mxs": [
"mx.nixnet.email"
]
},
"3b.pm": {
"mode": "enforce",
"mxs": [
"3b.pm"
]
},
"4wrd.cc": {
"mode": "enforce",
"mxs": [
"mail.anonaddy.me"
]
},
"647630.xyz": {
"mode": "enforce",
"mxs": [
"mx.nixnet.email"
]
},
"7748229.xyz": {
"mode": "enforce",
"mxs": [
"mx.nixnet.email"
]
},
"aati.be": {
"mode": "testing",
"mxs": [
"server.aati.be",
"mail.aati.be"
]
},
"accretus.com": {
"mode": "testing",
"mxs": [
"accretus-com.mail.protection.outlook.com"
]
},
"accretus.nl": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"acsemb.org": {
"mode": "enforce",
"mxs": [
"arch-server.dhautefeuille.eu"
]
},
"adagia.eu": {
"mode": "enforce",
"mxs": [
"mail.adagia.eu",
"adagia.eu"
]
},
"addk.ru": {
"mode": "testing",
"mxs": [
"mail.addk.ru"
]
},
"aehe.us": {
"mode": "enforce",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"affinityvision.com": {
"mode": "enforce",
"mxs": [
"mail.affinityvision.com",
"mail.affinityvision.com.au"
]
},
"affinityvision.com.au": {
"mode": "enforce",
"mxs": [
"mail.affinityvision.com",
"mail.affinityvision.com.au"
]
},
"aircraftnoisemodel.org": {
"mode": "testing",
"mxs": [
"esa1.eurocontrol.c3s2.iphmx.com",
"esa2.eurocontrol.c3s2.iphmx.com"
]
},
"aivd.lol": {
"mode": "enforce",
"mxs": [
"mx.soverin.net"
]
},
"aixm.aero": {
"mode": "testing",
"mxs": [
"esa1.eurocontrol.c3s2.iphmx.com",
"esa2.eurocontrol.c3s2.iphmx.com"
]
},
"ak-krasavia.ru": {
"mode": "enforce",
"mxs": [
"gaston.ak-krasavia.ru",
".ak-krasavia.ru",
"pam.ak-krasavia.ru"
]
},
"alanwest.com": {
"mode": "testing",
"mxs": [
"mail2.alanwest.com",
"mail2.sheridanwest.com"
]
},
"albourne.com": {
"mode": "testing",
"mxs": [
"despam-fra-0.albourne.com",
"despam-fra-1.albourne.com",
"despam-hpn-0.albourne.com",
"despam-hpn-1.albourne.com",
"despam-sin-0.albourne.com",
"despam-sin-1.albourne.com"
]
},
"alesund.kommune.no": {
"mode": "testing",
"mxs": [
"ns1.esunnmore.no",
"ns2.esunnmore.no"
]
},
"alexyang.me": {
"mode": "enforce",
"mxs": [
"alexyang-me.mail.protection.outlook.com"
]
},
"alio.fr": {
"mode": "testing",
"mxs": [
"spool.mail.gandi.net",
"fb.mail.gandi.net"
]
},
"alphachat.net": {
"mode": "enforce",
"mxs": [
"mail.alphachat.net"
]
},
"amegrund.com": {
"mode": "enforce",
"mxs": [
".us-core.com"
]
},
"amolindo.com": {
"mode": "testing",
"mxs": [
"mx.yandex.net"
]
},
"andreasrohner.net": {
"mode": "testing",
"mxs": [
"spool.mail.gandi.net",
"fb.mail.gandi.net"
]
},
"anguta.net": {
"mode": "enforce",
"mxs": [
"mail.anguta.net"
]
},
"anonaddy.com": {
"mode": "enforce",
"mxs": [
"mail.tutanota.de"
]
},
"anonaddy.me": {
"mode": "enforce",
"mxs": [
"mail.anonaddy.me"
]
},
"anubisnetworks.com": {
"mode": "testing",
"mxs": [
".eu.mpssec.net"
]
},
"apex.ac": {
"mode": "enforce",
"mxs": [
"mx.apex.ac"
]
},
"arcana.jp": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"arch-libertas.net": {
"mode": "enforce",
"mxs": [
"bouquetin.arch-libertas.net",
"mail.arch-libertas.net"
]
},
"asdzxc.eu": {
"mode": "testing",
"mxs": [
"lexi.xxblackburnxx.nl"
]
},
"aurorafest.org": {
"mode": "enforce",
"mxs": [
".aurorafest.org"
]
},
"babysittor.fr": {
"mode": "enforce",
"mxs": [
"arch-server.dhautefeuille.eu"
]
},
"backstrom.me": {
"mode": "enforce",
"mxs": [
"postal.pebe.net"
]
},
"bad-wurzach.de": {
"mode": "testing",
"mxs": [
"mx1.rz-kiru.de",
"mx2.rz-kiru.de"
]
},
"barneshay.com": {
"mode": "enforce",
"mxs": [
"mx.zoho.com",
"mx2.zoho.com",
"mx3.zoho.com"
]
},
"baucum.me": {
"mode": "enforce",
"mxs": [
"mail.baucum.me",
"baucum.me"
]
},
"bayerstefan.de": {
"mode": "enforce",
"mxs": [
"ncars.douzer.de",
"lcars.douzer.de"
]
},
"bbtmv.de": {
"mode": "enforce",
"mxs": [
"mail.bbtmv.de"
]
},
"beckorg.com": {
"mode": "enforce",
"mxs": [
"box.beckemail.net"
]
},
"belgraver.email": {
"mode": "testing",
"mxs": [
"mx.soverin.net"
]
},
"belgraver.eu": {
"mode": "testing",
"mxs": [
"mx.soverin.net"
]
},
"belgraver.xyz": {
"mode": "testing",
"mxs": [
"mx.soverin.net"
]
},
"belmaachi.com": {
"mode": "testing",
"mxs": [
"mx1.belmaachi.com",
"mx2.belmaachi.com"
]
},
"blackscape.de": {
"mode": "testing",
"mxs": [
".mailbox.org",
"mxext1.mailbox.org",
"mxext2.mailbox.org",
"mxext3.mailbox.org"
]
},
"blitiri.com.ar": {
"mode": "enforce",
"mxs": [
"cdt.blitiri.com.ar",
"alerce.blitiri.com.ar"
]
},
"bodis.nl": {
"mode": "testing",
"mxs": [
"mx01.bodis.nl",
"mx99.bodis.nl"
]
},
"c0x0.com": {
"mode": "enforce",
"mxs": [
"io.onefellow.com",
"shield.c0x0.com"
]
},
"c3pb.de": {
"mode": "testing",
"mxs": [
"mail.services.c3pb.de"
]
},
"calvertk9search.org": {
"mode": "enforce",
"mxs": [
"mail.calvertk9search.org"
]
},
"calypsohost.net": {
"mode": "enforce",
"mxs": [
"mail.calypsohost.net"
]
},
"camshah.com": {
"mode": "testing",
"mxs": [
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"aspmx2.googlemail.com",
"aspmx3.googlemail.com",
"aspmx4.googlemail.com",
"aspmx5.googlemail.com",
"aspmx.l.google.com"
]
},
"carobme.de": {
"mode": "enforce",
"mxs": [
".carobme.de"
]
},
"carolineball.com": {
"mode": "enforce",
"mxs": [
".johndball.com",
".carolineeball.com",
".carolineball.com",
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"castaing.org": {
"mode": "enforce",
"mxs": [
"mta-gw.infomaniak.ch",
"mta-gw.scubadata.net"
]
},
"castlepointanime.com": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
".aspmx.l.google.com",
".googlemail.com",
"smtp-relay.gmail.com",
"smtp.gmail.com",
".castlepointanime.com"
]
},
"catram.org": {
"mode": "enforce",
"mxs": [
"mail.catram.org"
]
},
"cavew.com": {
"mode": "testing",
"mxs": [
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"aspmx2.googlemail.com",
"aspmx3.googlemail.com",
"aspmx.l.google.com"
]
},
"cendata.co.uk": {
"mode": "enforce",
"mxs": [
"a.mx.cendata.co.uk"
]
},
"centurion-consulting.net": {
"mode": "enforce",
"mxs": [
"centurion-consulting.tech"
]
},
"cfv.biz": {
"mode": "enforce",
"mxs": [
".dcfv.com",
".itrust.com.tw",
".ibon.ws",
".cfv.biz"
]
},
"cgsecurity.org": {
"mode": "testing",
"mxs": [
".global-sp.net"
]
},
"chris-schuster.net": {
"mode": "enforce",
"mxs": [
"chris-schuster.net"
]
},
"cock.li": {
"mode": "testing",
"mxs": [
"mx1.cock.li"
]
},
"coincoin.eu.org": {
"mode": "testing",
"mxs": [
"coincoin.eu.org"
]
},
"coldmail.cc": {
"mode": "testing",
"mxs": [
"main.coldmail.cc",
"mail.coldmail.cc",
"smtp.coldmail.cc"
]
},
"cool110.xyz": {
"mode": "enforce",
"mxs": [
"mail.cool110.xyz"
]
},
"core.md": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"covingtondoan.com": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"covisp.net": {
"mode": "testing",
"mxs": [
"Mail.covisp.net"
]
},
"creativesandbox.de": {
"mode": "enforce",
"mxs": [
"mail.creativesandbox.de"
]
},
"ctemplar.com": {
"mode": "enforce",
"mxs": [
"mail.ctemplar.com"
]
},
"currentc.capital": {
"mode": "enforce",
"mxs": [
"arch-server.dhautefeuille.eu"
]
},
"cyber-core.co.uk": {
"mode": "enforce",
"mxs": [
"mail.cyber-core.co.uk"
]
},
"cyberdynesecuritysystems.com": {
"mode": "enforce",
"mxs": [
"mail.anonaddy.me"
]
},
"cyberpathogen.me": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"cygnaltech.com": {
"mode": "testing",
"mxs": [
"mail.cygnaltech.com",
".cygnaltech.com"
]
},
"cygnitec.com": {
"mode": "enforce",
"mxs": [
"mx0.cygnitec.com"
]
},
"dalliard.ch": {
"mode": "testing",
"mxs": [
"mail.dalliard.ch"
]
},
"dano.bzh": {
"mode": "testing",
"mxs": [
"smtp.dano.bzh",
"mx.zoho.eu"
]
},
"darknetlive.com": {
"mode": "enforce",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"datahoarder.dev": {
"mode": "enforce",
"mxs": [
"mail.datahoarder.dev"
]
},
"datamerica.com": {
"mode": "testing",
"mxs": [
"mail-1.datamerica.com"
]
},
"dcfv.com": {
"mode": "enforce",
"mxs": [
".dcfv.com",
".itrust.com.tw",
".ibon.ws",
".cfv.biz"
]
},
"debien.fr": {
"mode": "enforce",
"mxs": [
"smtp.namaste.ovh"
]
},
"deboca.net": {
"mode": "testing",
"mxs": [
"bocanium.deboca.net",
"bocanium.soleus.nu"
]
},
"deesse.com": {
"mode": "testing",
"mxs": [
"mail.deesse.com"
]
},
"deigner.eu": {
"mode": "testing",
"mxs": [
"box.deigner.eu"
]
},
"demoulin.mobi": {
"mode": "testing",
"mxs": [
"mx1.mail.ovh.net"
]
},
"deprecate.de": {
"mode": "enforce",
"mxs": [
".deprecate.de"
]
},
"dinepont.fr": {
"mode": "enforce",
"mxs": [
"arch-server.dhautefeuille.eu"
]
},
"ding.net": {
"mode": "enforce",
"mxs": [
"server9.comtrends.net"
]
},
"dips.no": {
"mode": "enforce",
"mxs": [
"mx1.dips.no"
]
},
"disroot.org": {
"mode": "enforce",
"mxs": [
"disroot.org",
"mx01.disroot.org"
]
},
"dnns.no": {
"mode": "testing",
"mxs": [
"smtp.dnns.no"
]
},
"dnsprivado.com.es": {
"mode": "enforce",
"mxs": [
"server.dnsprivado.com.es"
]
},
"domu.cat": {
"mode": "testing",
"mxs": [
"secpi.domu.cat"
]
},
"downey.net": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"dragas.it": {
"mode": "testing",
"mxs": [
"zimbra.dragashosting.com",
"zimbra.dragas.it"
]
},
"drcheap.com": {
"mode": "testing",
"mxs": [
"mail.drcheap.com",
"drcheap.com"
]
},
"drewhess.com": {
"mode": "enforce",
"mxs": [
"mxa.drewhess.com",
"mxb.drewhess.com"
]
},
"durel.eu": {
"mode": "enforce",
"mxs": [
"corrin.geekwu.org",
"arrakeen.geekwu.org"
]
},
"dwap.fr": {
"mode": "testing",
"mxs": [
"mx1.mail.ovh.net",
"mx2.mail.ovh.net",
"mx3.mail.ovh.net"
]
},
"e-doctor.com.ua": {
"mode": "enforce",
"mxs": [
"mx01.pnnsoft.com"
]
},
"ebrey-it.com": {
"mode": "testing",
"mxs": [
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"aspmx2.googlemail.com",
"aspmx3.googlemail.com",
"aspmx4.googlemail.com",
"aspmx5.googlemail.com",
"aspmx.l.google.com"
]
},
"eerie.garden": {
"mode": "enforce",
"mxs": [
"eerie.garden"
]
},
"ekvastra.in": {
"mode": "enforce",
"mxs": [
"server50.hostingraja.org",
"mx.zoho.in"
]
},
"el-solutionstech.com": {
"mode": "testing",
"mxs": [
"jane.the-kingdom.net",
"trent.the-kingdom.net"
]
},
"eleith.com": {
"mode": "enforce",
"mxs": [
"mail.eleith.com"
]
},
"elizabethbeck.net": {
"mode": "enforce",
"mxs": [
"box.beckemail.net"
]
},
"elvey.com": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"elvey.sent.com": {
"mode": "testing",
"mxs": [
".messagingengine.com"
]
},
"email.peterjin.org": {
"mode": "enforce",
"mxs": [
".aspmx.l.google.com",
"aspmx.l.google.com",
"apps-vm1.srv.peterjin.org",
"apps-vm3.srv.peterjin.org"
]
},
"email.teratorium.hu": {
"mode": "testing",
"mxs": [
"email.teratorium.hu"
]
},
"emilstahl.com": {
"mode": "enforce",
"mxs": [
"mx1.smtp.goog",
"mx2.smtp.goog",
"mx3.smtp.goog",
"mx4.smtp.goog"
]
},
"emisto.com.ua": {
"mode": "enforce",
"mxs": [
"mx01.pnnsoft.com"
]
},
"empost.eu": {
"mode": "enforce",
"mxs": [
"empost.eu"
]
},
"ennis.no": {
"mode": "testing",
"mxs": [
"smtp.dnns.no"
]
},
"escatech.fr": {
"mode": "testing",
"mxs": [
"escatech-fr.mail.protection.outlook.com"
]
},
"etyd.org": {
"mode": "enforce",
"mxs": [
"torgny.etyd.org"
]
},
"ewanto.de": {
"mode": "enforce",
"mxs": [
".lauterus.com"
]
},
"exon.name": {
"mode": "enforce",
"mxs": [
"exon.name"
]
},
"exploited.cz": {
"mode": "testing",
"mxs": [
"mx1.smtp.goog",
"mx2.smtp.goog",
"mx3.smtp.goog",
"mx4.smtp.goog"
]
},
"fabiankaindl.de": {
"mode": "testing",
"mxs": [
".fabiankaindl.de"
]
},
"fam-biewald.de": {
"mode": "testing",
"mxs": [
".fam-biewald.de",
".patfab.net",
".patfab.network",
".sbiewald.de"
]
},
"fam-verhagen.nl": {
"mode": "testing",
"mxs": [
"fam-verhagen.nl"
]
},
"family-martens.com": {
"mode": "testing",
"mxs": [
"familymartens-com01e.mail.protection.outlook.com"
]
},
"fantasmx.fr": {
"mode": "testing",
"mxs": [
"mail.fantasmx.fr"
]
},
"farmserv.org": {
"mode": "testing",
"mxs": [
"farmserv.org"
]
},
"florianstroeger.com": {
"mode": "testing",
"mxs": [
"mail.florianstroeger.com"
]
},
"fnds.gov.mz": {
"mode": "testing",
"mxs": [
"mail.fnds.gov.mz",
"mta.dotcom.co.mz"
]
},
"foixet.com": {
"mode": "enforce",
"mxs": [
"mx.snargol.com"
]
},
"freedom.nl": {
"mode": "testing",
"mxs": [
"mx.soverin.net"
]
},
"frenchsmart.net": {
"mode": "testing",
"mxs": [
"mail.frenchsmart.net"
]
},
"frogeye.fr": {
"mode": "enforce",
"mxs": [
"rana.frogeye.fr"
]
},
"frols.com": {
"mode": "testing",
"mxs": [
".frols.com"
]
},
"fsri.uni-due.de": {
"mode": "testing",
"mxs": [
"mail.fsri.uni-due.de"
]
},
"fvid.tk": {
"mode": "testing",
"mxs": [
"mx.yandex.net"
]
},
"fxdiler.com": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"aspmx2.googlemail.com",
"aspmx3.googlemail.com",
"aspmx4.googlemail.com",
"aspmx5.googlemail.com"
]
},
"gauthier.tel": {
"mode": "enforce",
"mxs": [
"mail.wjg.dk"
]
},
"gbif.es": {
"mode": "testing",
"mxs": [
"mail.gbif.es"
]
},
"gchq.lol": {
"mode": "enforce",
"mxs": [
"mx.soverin.net"
]
},
"geekwu.org": {
"mode": "enforce",
"mxs": [
"corrin.geekwu.org",
"arrakeen.geekwu.org"
]
},
"gekemoti.fr": {
"mode": "enforce",
"mxs": [
"gekemoti.fr"
]
},
"gennerator.com": {
"mode": "enforce",
"mxs": [
"mx.yandex.net"
]
},
"gentoo.org": {
"mode": "testing",
"mxs": [
"dev.gentoo.org",
"mail.gentoo.org",
"smtp.gentoo.org",
"woodpecker.gentoo.org",
"lists.gentoo.org"
]
},
"globalsp.com": {
"mode": "testing",
"mxs": [
".global-sp.net"
]
},
"google.com": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"gsd-software.com": {
"mode": "enforce",
"mxs": [
".antispameurope.com"
]
},
"gsuite.tonytan.io": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"gtaxl.net": {
"mode": "enforce",
"mxs": [
"mail.gtaxl.net"
]
},
"gwaza.co.uk": {
"mode": "testing",
"mxs": [
"gwaza-co-uk.mail.protection.outlook.com"
]
},
"hackworthltd.com": {
"mode": "enforce",
"mxs": [
"mxa.mail.hackworth-corp.com"
]
},
"hadrons.org": {
"mode": "enforce",
"mxs": [
".hadrons.org"
]
},
"hamiltoncoin.io": {
"mode": "enforce",
"mxs": [
"arch-server.dhautefeuille.eu"
]
},
"hase.dev": {
"mode": "enforce",
"mxs": [
"mail.hase.dev"
]
},
"hboeck.de": {
"mode": "enforce",
"mxs": [
"zucker.schokokeks.org"
]
},
"heijmans.blog": {
"mode": "testing",
"mxs": [
"mx.soverin.net",
".soverin.net"
]
},
"heijmans.cloud": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"heijmans.email": {
"mode": "enforce",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com",
".messagingengine.com"
]
},
"heijmans.io": {
"mode": "enforce",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com",
".messagingengine.com"
]
},
"heijmans.xyz": {
"mode": "enforce",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com",
".messagingengine.com"
]
},
"hermitant.fr": {
"mode": "enforce",
"mxs": [
"mail.rust.pm"
]
},
"heutger.net": {
"mode": "enforce",
"mxs": [
".heutger.net"
]
},
"hewgill.com": {
"mode": "testing",
"mxs": [
"stratus.hewgill.net"
]
},
"hklbgd.org": {
"mode": "testing",
"mxs": [
"hklbgd.org"
]
},
"hkmap.co": {
"mode": "testing",
"mxs": [
"mailsec.protonmail.ch",
"mail.protonmail.ch"
]
},
"hkmap.com": {
"mode": "testing",
"mxs": [
"mailsec.protonmail.ch",
"mail.protonmail.ch"
]
},
"hkmap.live": {
"mode": "enforce",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"hkmap.net": {
"mode": "testing",
"mxs": [
"mailsec.protonmail.ch",
"mail.protonmail.ch"
]
},
"hlfh.space": {
"mode": "enforce",
"mxs": [
"arch-server.dhautefeuille.eu"
]
},
"homunyan.com": {
"mode": "testing",
"mxs": [
"homunyan.com"
]
},
"hquest.pro.br": {
"mode": "enforce",
"mxs": [
"mx.hquest.pro.br"
]
},
"humblebee.eu": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"humblebee.ie": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"ibon.ws": {
"mode": "enforce",
"mxs": [
".dcfv.com",
".itrust.com.tw",
".ibon.ws",
".cfv.biz"
]
},
"id3.eu": {
"mode": "testing",
"mxs": [
"ext234.id3.eu"
]
},
"ievlev.email": {
"mode": "enforce",
"mxs": [
"ievlev.email"
]
},
"ifocus-consulting.com": {
"mode": "testing",
"mxs": [
"ifocusmail.com"
]
},
"iii.mm.st": {
"mode": "testing",
"mxs": [
".messagingengine.com"
]
},
"imds.nl": {
"mode": "testing",
"mxs": [
"mail.imds.nl"
]
},
"incardoc.com": {
"mode": "enforce",
"mxs": [
"mx01.pnnsoft.com"
]
},
"info-sec.ca": {
"mode": "testing",
"mxs": [
"mail.info-sec.ca"
]
},
"inittab.org": {
"mode": "testing",
"mxs": [
"hermes.inittab.org"
]
},
"innovametro.com": {
"mode": "enforce",
"mxs": [
".us-core.com"
]
},
"intermedia.mx": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"intermediacontrol.com": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"intr0.com": {
"mode": "enforce",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"intrax.com": {
"mode": "testing",
"mxs": [
"mail.intrax.com"
]
},
"ipv6-adresse.dk": {
"mode": "enforce",
"mxs": [
"mx1.smtp.goog",
"mx2.smtp.goog",
"mx3.smtp.goog",
"mx4.smtp.goog"
]
},
"itcreative.ro": {
"mode": "testing",
"mxs": [
"itcreative.ro",
"mail.itcreative.ro"
]
},
"itrust.com.tw": {
"mode": "enforce",
"mxs": [
".dcfv.com",
".itrust.com.tw",
".ibon.ws",
".cfv.biz"
]
},
"itsystemsteam.co.uk": {
"mode": "enforce",
"mxs": [
"a.mx.cendata.co.uk"
]
},
"jamieweb.net": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com",
"mxa.mailgun.org",
"mxb.mailgun.org"
]
},
"jarus-rpas.org": {
"mode": "testing",
"mxs": [
"esa1.eurocontrol.c3s2.iphmx.com",
"esa2.eurocontrol.c3s2.iphmx.com"
]
},
"jgoldman.net": {
"mode": "testing",
"mxs": [
"jgoldman-net.mail.protection.outlook.com"
]
},
"jgoldmanlp.com": {
"mode": "testing",
"mxs": [
"jgoldmanlp-com.mail.protection.outlook.com"
]
},
"jilworldwide.org": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"jkdhn.me": {
"mode": "testing",
"mxs": [
"mail.jkdhn.me"
]
},
"jordibelgraver.email": {
"mode": "testing",
"mxs": [
"mx.soverin.net",
".soverin.net"
]
},
"jordibelgraver.eu": {
"mode": "testing",
"mxs": [
"mx.soverin.net",
".soverin.net"
]
},
"jordibelgraver.xyz": {
"mode": "testing",
"mxs": [
"mx.soverin.net",
".soverin.net"
]
},
"joshuacasey.net": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"joshuar.id.au": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"joshuarobertson.id.au": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"jurnal.md": {
"mode": "testing",
"mxs": [
"mailgate.jurnaltv.md"
]
},
"jurnalfm.md": {
"mode": "testing",
"mxs": [
"mailgate.jurnaltv.md"
]
},
"jurnaltv.md": {
"mode": "testing",
"mxs": [
"mailgate.jurnaltv.md"
]
},
"k-telecom.org": {
"mode": "enforce",
"mxs": [
"relay.k-telecom.org"
]
},
"keemail.me": {
"mode": "testing",
"mxs": [
"mail.tutanota.de"
]
},
"keys.openpgp.org": {
"mode": "enforce",
"mxs": [
"mail.keys.openpgp.org"
]
},
"kgtv.tk": {
"mode": "testing",
"mxs": [
"mx.yandex.net"
]
},
"knrt.de": {
"mode": "enforce",
"mxs": [
"mail.kuhnerts.eu"
]
},
"koenrouwhorst.nl": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"kokomo.xyz": {
"mode": "testing",
"mxs": [
"mail.kokomo.xyz"
]
},
"konnected.vn": {
"mode": "testing",
"mxs": [
"mail.konnected.vn"
]
},
"kpopsource.com": {
"mode": "enforce",
"mxs": [
"mail.kpopsource.com"
]
},
"ksoft.si": {
"mode": "testing",
"mxs": [
"mx.postal.ksoft.si"
]
},
"kydara.com": {
"mode": "enforce",
"mxs": [
"mail.kydara.com"
]
},
"laatikainen.net": {
"mode": "enforce",
"mxs": [
"mx.1nt3r.net"
]
},
"lacordillere.com": {
"mode": "enforce",
"mxs": [
"arch-server.dhautefeuille.eu"
]
},
"lapidak.is": {
"mode": "testing",
"mxs": [
".messagingengine.com"
]
},
"laposte.net": {
"mode": "testing",
"mxs": [
"smtpz4.laposte.net"
]
},
"larrybeck.net": {
"mode": "enforce",
"mxs": [
"box.beckemail.net"
]
},
"laurenball.com": {
"mode": "enforce",
"mxs": [
".johndball.com",
".laurencball.com",
".laurenball.com",
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"lease-up.com": {
"mode": "enforce",
"mxs": [
".us-core.com"
]
},
"lebihan.pl": {
"mode": "testing",
"mxs": [
"lebihan.pl"
]
},
"leidinger.net": {
"mode": "enforce",
"mxs": [
"mailgate.leidinger.net"
]
},
"leonschwarze.com": {
"mode": "testing",
"mxs": [
"leonschwarze.com",
"smtpin.rzone.de"
]
},
"linux.pizza": {
"mode": "testing",
"mxs": [
"kebab.linux.pizza"
]
},
"litepost.no": {
"mode": "testing",
"mxs": [
"smtp.dnns.no"
]
},
"litepost.org": {
"mode": "testing",
"mxs": [
"smtp.dnns.no"
]
},
"liu-family.eu": {
"mode": "enforce",
"mxs": [
"random.randomcrap.eu",
"mini.randomcrap.eu"
]
},
"logsnitch.com": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"luqsus.pl": {
"mode": "testing",
"mxs": [
"srv.luqsus.pl"
]
},
"m01.info": {
"mode": "enforce",
"mxs": [
"mail.m01.info"
]
},
"m2.peterjin.org": {
"mode": "enforce",
"mxs": [
"apps-vm1.srv.peterjin.org",
"apps-vm3.srv.peterjin.org"
]
},
"mail.danielhinterlechner.eu": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"mail.logsnitch.com": {
"mode": "enforce",
"mxs": [
"feedback-smtp.us-east-1.amazonses.com"
]
},
"mail.m01.info": {
"mode": "enforce",
"mxs": [
"mail.m01.info"
]
},
"mail.mkpe.com": {
"mode": "testing",
"mxs": [
"host.mkpe.com"
]
},
"mailfence.com": {
"mode": "enforce",
"mxs": [
"smtp1.mailfence.com",
"smtp2.mailfence.com"
]
},
"mailhardener.com": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"aspmx2.googlemail.com",
"aspmx3.googlemail.com"
]
},
"malsec.com.au": {
"mode": "testing",
"mxs": [
"mail.malsec.com.au"
]
},
"maneraperez.com.ar": {
"mode": "enforce",
"mxs": [
"vade-in1.mail.dreamhost.com",
"vade-in2.mail.dreamhost.com"
]
},
"marcodoehring.com": {
"mode": "testing",
"mxs": [
"mxext1.mailbox.org",
"mxext2.mailbox.org",
"mxext3.mailbox.org"
]
},
"marywalesloomis.com": {
"mode": "enforce",
"mxs": [
"mail.richw.org",
"drizzle.richw.org",
"fogbank.richw.org",
"express.richw.org"
]
},
"matejgroma.com": {
"mode": "enforce",
"mxs": [
"mail.matejgroma.com"
]
},
"matrixwissen.de": {
"mode": "enforce",
"mxs": [
"alpha.meta-matrix.de",
"gamma.meta-matrix.de",
"omega.meta-matrix.de",
"delta.meta-matrix.de"
]
},
"matthew.elvey.com": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com",
".messagingengine.com"
]
},
"medway.gov.uk": {
"mode": "enforce",
"mxs": [
"mx0.medway.gov.uk"
]
},
"mega-turf.fr": {
"mode": "testing",
"mxs": [
"mx.selven.fr"
]
},
"megasoft.com.ve": {
"mode": "testing",
"mxs": [
"engine.megasoft.com.ve",
"engine1.megasoft.com.ve"
]
},
"meiliboxi.fi": {
"mode": "enforce",
"mxs": [
"meiliboxi.fi"
]
},
"meta-matrix.de": {
"mode": "enforce",
"mxs": [
"alpha.meta-matrix.de",
"gamma.meta-matrix.de",
"omega.meta-matrix.de",
"delta.meta-matrix.de"
]
},
"mfen.de": {
"mode": "enforce",
"mxs": [
"al.mfen.de"
]
},
"michaeljdean.com": {
"mode": "testing",
"mxs": [
"mx.upcbusiness.at"
]
},
"michalspacek.cz": {
"mode": "testing",
"mxs": [
"mx1.smtp.goog",
"mx2.smtp.goog",
"mx3.smtp.goog",
"mx4.smtp.goog"
]
},
"mihgroup.net": {
"mode": "enforce",
"mxs": [
"mail.mihgroup.net"
]
},
"minipli.net": {
"mode": "testing",
"mxs": [
"mail.r00tworld.net"
]
},
"mm.st": {
"mode": "testing",
"mxs": [
".messagingengine.com"
]
},
"mobilityworks.eu": {
"mode": "testing",
"mxs": [
"mobilityworks-eu.mail.protection.outlook.com"
]
},
"moutchic.com": {
"mode": "testing",
"mxs": [
"mail.moutchic.com",
"moutchic.com"
]
},
"mrwacky.com": {
"mode": "testing",
"mxs": [
"mail.mrwacky.com"
]
},
"mthode.org": {
"mode": "enforce",
"mxs": [
"mx1.mthode.org"
]
},
"myface.ph": {
"mode": "enforce",
"mxs": [
"mail.myface.ph"
]
},
"nadovich.com": {
"mode": "enforce",
"mxs": [
"hwsrv.nadovich.com"
]
},
"nadovich.net": {
"mode": "enforce",
"mxs": [
"hwsrv.nadovich.com"
]
},
"nadovich.org": {
"mode": "enforce",
"mxs": [
"hwsrv.nadovich.com"
]
},
"namaste.ovh": {
"mode": "enforce",
"mxs": [
"smtp.namaste.ovh"
]
},
"navigate-it-services.de": {
"mode": "enforce",
"mxs": [
"mx.nroute.de",
"mta01.nroute.de",
"mta02.nroute.de",
"mta03.nroute.de"
]
},
"nearon.nl": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"nebrius.org": {
"mode": "testing",
"mxs": [
"mx.zoho.com",
"mx2.zoho.com",
"mx3.zoho.com"
]
},
"neon.peterjin.org": {
"mode": "enforce",
"mxs": [
"apps-vm1.srv.peterjin.org",
"apps-vm3.srv.peterjin.org",
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"netcourrier.com": {
"mode": "testing",
"mxs": [
".netcourrier.com"
]
},
"nico.la": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"nixnetmail.com": {
"mode": "enforce",
"mxs": [
"mx.nixnet.email"
]
},
"nokt.is": {
"mode": "testing",
"mxs": [
"www.nokt.is"
]
},
"noveldatasolutions.com": {
"mode": "testing",
"mxs": [
"mail.noveldatasolutions.com"
]
},
"nsrc.nz": {
"mode": "testing",
"mxs": [
"zl1ab.nz",
"nsrc.nz",
"arec.nz",
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"nurnbergconsulting.com": {
"mode": "testing",
"mxs": [
"alt2.aspmx.l.google.com",
"aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com",
"alt1.aspmx.l.google.com"
]
},
"o9z.de": {
"mode": "testing",
"mxs": [
"mx.systemfreund.com"
]
},
"obd-car-doctor.com": {
"mode": "enforce",
"mxs": [
"mx01.pnnsoft.com"
]
},
"obdcardoc.com": {
"mode": "enforce",
"mxs": [
"mx01.pnnsoft.com"
]
},
"olbat.net": {
"mode": "testing",
"mxs": [
".messagingengine.com"
]
},
"onefellow.com": {
"mode": "enforce",
"mxs": [
"io.onefellow.com",
"shield.c0x0.com"
]
},
"oneweb.hu": {
"mode": "enforce",
"mxs": [
"filter.mx-eu-01.oneweb.hu"
]
},
"openmpt.org": {
"mode": "enforce",
"mxs": [
"mail.openmpt.org",
".openmpt.org",
"openmpt.org"
]
},
"orbglobal.com": {
"mode": "enforce",
"mxs": [
"mx0.orbglobal.com"
]
},
"osthome.de": {
"mode": "enforce",
"mxs": [
"mail.osthome.de",
".osthome.de"
]
},
"ournet.cloud": {
"mode": "enforce",
"mxs": [
"box.ournet.cloud"
]
},
"pagmaro.com": {
"mode": "testing",
"mxs": [
"mail.pagmaro.com"
]
},
"paranoidpenguin.net": {
"mode": "enforce",
"mxs": [
"server3.paranoidpenguin.net",
".paranoidpenguin.net"
]
},
"parinov.fr": {
"mode": "enforce",
"mxs": [
"arch-server.dhautefeuille.eu"
]
},
"paytogain.it": {
"mode": "testing",
"mxs": [
"paytogain.it"
]
},
"pebe.net": {
"mode": "enforce",
"mxs": [
"postal.pebe.net"
]
},
"peterjin.org": {
"mode": "enforce",
"mxs": [
".aspmx.l.google.com",
"aspmx.l.google.com",
"apps-vm1.srv.peterjin.org",
"apps-vm3.srv.peterjin.org"
]
},
"pjin.org": {
"mode": "enforce",
"mxs": [
".aspmx.l.google.com",
"aspmx.l.google.com",
"apps-vm1.srv.peterjin.org",
"apps-vm3.srv.peterjin.org"
]
},
"plastic-spoon.de": {
"mode": "testing",
"mxs": [
"rocket.plastic-spoon.de"
]
},
"pnn.com.ua": {
"mode": "enforce",
"mxs": [
"mx01.pnnsoft.com"
]
},
"pnn.in.ua": {
"mode": "enforce",
"mxs": [
"mx01.pnnsoft.com"
]
},
"pnn.org.ua": {
"mode": "enforce",
"mxs": [
"mx01.pnnsoft.com"
]
},
"pnnsoft.com": {
"mode": "enforce",
"mxs": [
"mx01.pnnsoft.com"
]
},
"pntz.us": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"politie.nl": {
"mode": "testing",
"mxs": [
"mail1.politie.nl",
"mail2.politie.nl"
]
},
"pollendine.co.uk": {
"mode": "enforce",
"mxs": [
"a.mx.cendata.co.uk"
]
},
"praxis-garnhaenki.ch": {
"mode": "enforce",
"mxs": [
"mailcow.praxis-garnhaenki.ch"
]
},
"printon.pro": {
"mode": "testing",
"mxs": [
"mail.printon.pro"
]
},
"privacytools.io": {
"mode": "testing",
"mxs": [
"mail.privacytools.io"
]
},
"propublica.org": {
"mode": "testing",
"mxs": [
"propublica-org.mail.protection.outlook.com"
]
},
"psyma.com": {
"mode": "testing",
"mxs": [
"mx.psyma.com"
]
},
"ptrk.io": {
"mode": "enforce",
"mxs": [
"mail.ptrk.io"
]
},
"pwned.life": {
"mode": "enforce",
"mxs": [
"mx.nixnet.email"
]
},
"quatulo.net": {
"mode": "testing",
"mxs": [
"mail.calypsohost.net"
]
},
"quoratetechnology.com": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
"aspmx2.googlemail.com",
"aspmx3.googlemail.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com"
]
},
"r13t.de": {
"mode": "enforce",
"mxs": [
"mail.r13t.de"
]
},
"r14t.de": {
"mode": "enforce",
"mxs": [
"mail.r13t.de"
]
},
"rafaelalmeida.pt": {
"mode": "testing",
"mxs": [
"mx.zoho.eu",
"mx2.zoho.eu",
"mx3.zoho.eu"
]
},
"railto.com": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"randomcrap.eu": {
"mode": "enforce",
"mxs": [
"random.randomcrap.eu",
"mini.randomcrap.eu"
]
},
"rbin.nl": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"rdcdesign.com": {
"mode": "testing",
"mxs": [
".rdcdesign.com"
]
},
"rheijmans.eu": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"rheijmans.nl": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"rhopi.io": {
"mode": "testing",
"mxs": [
"rhopi.io"
]
},
"richie.one": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"richieheijmans.cloud": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"richieheijmans.com": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"richieheijmans.email": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"richieheijmans.eu": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"richieheijmans.xyz": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"richw.org": {
"mode": "enforce",
"mxs": [
"mail.richw.org",
"drizzle.richw.org",
"fogbank.richw.org",
"express.richw.org"
]
},
"ricwein.com": {
"mode": "testing",
"mxs": [
"mail.ricwein.com"
]
},
"riechsteiner.tech": {
"mode": "testing",
"mxs": [
"mail.riechsteiner.tech"
]
},
"rije.de": {
"mode": "testing",
"mxs": [
"mail.rije.de"
]
},
"riseup.net": {
"mode": "enforce",
"mxs": [
"riseup.net",
".riseup.net"
]
},
"roboroscope-turf.fr": {
"mode": "testing",
"mxs": [
"mx.selven.fr"
]
},
"rodier.me": {
"mode": "enforce",
"mxs": [
"smtp.rodier.me",
"spool.mail.gandi.net",
"fb.mail.gandi.net"
]
},
"roseitsolutions.co.uk": {
"mode": "enforce",
"mxs": [
"384b6aa7.21.ik2.com",
"384b6aa7.22.ik2.io",
"384b6aa7.23.ik2.eu"
]
},
"roualland.net": {
"mode": "enforce",
"mxs": [
"mail.anguta.net"
]
},
"rte.ie": {
"mode": "testing",
"mxs": [
"rte-ie.mail.protection.outlook.com"
]
},
"rtf.org.uk": {
"mode": "testing",
"mxs": [
"simplex.rtf.org.uk"
]
},
"rust.pm": {
"mode": "enforce",
"mxs": [
"mail.rust.pm"
]
},
"rwhrst.nl": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"sabbottlabs.com": {
"mode": "enforce",
"mxs": [
"sabbottlabs.com"
]
},
"sammdu.com": {
"mode": "testing",
"mxs": [
"sammdu.com",
"mail.sammdu.com"
]
},
"sapience.com": {
"mode": "enforce",
"mxs": [
"sapience.com",
".sapience.com",
".ecohler.com",
".ecohler.net"
]
},
"saturne.cc": {
"mode": "testing",
"mxs": [
"casimir.saturne.cc"
]
},
"sbuddhe.net": {
"mode": "testing",
"mxs": [
"mx.sbuddhe.net",
"kal-el.sbuddhe.net",
"sameer.sbuddhe.net",
"mahesh.sbuddhe.net"
]
},
"scanmailx.com": {
"mode": "enforce",
"mxs": [
"mxdk01.scanmailx.com",
"mxdk02.scanmailx.com",
".scanmailx.com"
]
},
"schaltstube.de": {
"mode": "testing",
"mxs": [
"mx.schaltstube.de"
]
},
"scharlewsky.de": {
"mode": "testing",
"mxs": [
"mail.ud19.udmedia.de"
]
},
"schultz.re": {
"mode": "enforce",
"mxs": [
"mail.schultz.re",
".schultz.re",
"schultz.re"
]
},
"scribnerd.com": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"sdennie.net": {
"mode": "testing",
"mxs": [
"mail.sdennie.net",
"vpn.sdennie.net"
]
},
"sean.taipei": {
"mode": "enforce",
"mxs": [
"sean.taipei",
"mail.sean.taipei"
]
},
"secnd.me": {
"mode": "testing",
"mxs": [
"mail.secnd.me"
]
},
"securedlegion.com": {
"mode": "enforce",
"mxs": [
"mail.anonaddy.me"
]
},
"sermesa.es": {
"mode": "enforce",
"mxs": [
"server.dnsprivado.com.es"
]
},
"sethvargo.com": {
"mode": "enforce",
"mxs": [
"sethvargo.com",
"sethvargo.dev",
"sethvargo.me",
"vargo.dev",
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"shadowcp.eu": {
"mode": "testing",
"mxs": [
"mx.shadowcp.eu",
"dc.shadowcp.eu"
]
},
"shat.net": {
"mode": "enforce",
"mxs": [
"mailman.shaunc.com",
"mail.shaunc.com"
]
},
"shaunc.com": {
"mode": "enforce",
"mxs": [
"mailman.shaunc.com",
"mail.shaunc.com"
]
},
"sheridanwest.net": {
"mode": "testing",
"mxs": [
"mail2.sheridanwest.net",
"mail2.sheridanwest.com"
]
},
"shintag.com": {
"mode": "testing",
"mxs": [
"ASPMX.L.GOOGLE.COM",
"ALT1.ASPMX.L.GOOGLE.COM",
"ALT2.ASPMX.L.GOOGLE.COM",
"ALT3.ASPMX.L.GOOGLE.COM",
"ALT4.ASPMX.L.GOOGLE.COM"
]
},
"sigmalux.ca": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"sigmalux.co.nz": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"sigmalux.co.uk": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"sigmalux.com.au": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"sigmalux.es": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"sigmalux.llc": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"sigmalux.nz": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"sigmalux.sarl": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"sigmalux.uk": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"sigmalux.us": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
".aspmx.l.google.com"
]
},
"sit-test.dk": {
"mode": "enforce",
"mxs": [
"mx1.sit-test.dk",
"mx2.sit-test.dk"
]
},
"sldev.ovh": {
"mode": "testing",
"mxs": [
"mx1.sldev.ovh"
]
},
"smart-dm.de": {
"mode": "enforce",
"mxs": [
"sdm.smart-dm.de",
".smart-dm.de"
]
},
"sniffton.com": {
"mode": "enforce",
"mxs": [
".sniffton.com",
"mail.sniffton.com"
]
},
"snopyta.org": {
"mode": "enforce",
"mxs": [
"mail.snopyta.org"
]
},
"socketlabs.com": {
"mode": "enforce",
"mxs": [
"socketlabs-com.mail.protection.outlook.com"
]
},
"southsidebarbershop.fr": {
"mode": "enforce",
"mxs": [
"arch-server.dhautefeuille.eu"
]
},
"soverin.net": {
"mode": "enforce",
"mxs": [
"mx.soverin.net",
".soverin.net"
]
},
"steadmon.net": {
"mode": "testing",
"mxs": [
"steadmon.net"
]
},
"stefanheil.com": {
"mode": "enforce",
"mxs": [
"mail.stefanheil.com"
]
},
"storedsafe.com": {
"mode": "enforce",
"mxs": [
"smtp.xpd.se"
]
},
"stuartbell.uk": {
"mode": "enforce",
"mxs": [
".messagingengine.com"
]
},
"sufliarsky.sk": {
"mode": "enforce",
"mxs": [
"vps.sufliarsky.sk"
]
},
"swim.aero": {
"mode": "testing",
"mxs": [
"esa1.eurocontrol.c3s2.iphmx.com",
"esa2.eurocontrol.c3s2.iphmx.com"
]
},
"sylca.fr": {
"mode": "testing",
"mxs": [
"spool.mail.gandi.net",
"fb.mail.gandi.net"
]
},
"sylvan.io": {
"mode": "testing",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"tcy.com": {
"mode": "enforce",
"mxs": [
".tcy.com",
".tcy.com.tw",
".tcy.tw",
".tcy.cn"
]
},
"tcy.com.tw": {
"mode": "enforce",
"mxs": [
".tcy.com",
".tcy.com.tw",
".tcy.tw",
".tcy.cn"
]
},
"tcy.tw": {
"mode": "enforce",
"mxs": [
".tcy.com",
".tcy.com.tw",
".tcy.tw",
".tcy.cn"
]
},
"techlevel.org": {
"mode": "enforce",
"mxs": [
"mail.techlevel.org"
]
},
"technodro.me": {
"mode": "testing",
"mxs": [
".technodro.me"
]
},
"tecle.net": {
"mode": "testing",
"mxs": [
"mail.tecle.net"
]
},
"tecpron.com": {
"mode": "testing",
"mxs": [
"mx-01-us-west-2.prod.hydra.sophos.com",
"mx-02-us-west-2.prod.hydra.sophos.com"
]
},
"tedra.nz": {
"mode": "testing",
"mxs": [
"jane.the-kingdom.net",
"trent.the-kingdom.net"
]
},
"tegitur.com": {
"mode": "enforce",
"mxs": [
"mail.tegitur.com"
]
},
"teichroeb.net": {
"mode": "enforce",
"mxs": [
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"aspmx.l.google.com",
"aspmx2.googlemail.com",
"aspmx3.googlemail.com"
]
},
"tetsistemi.tech": {
"mode": "testing",
"mxs": [
"mail.tetsistemi.tech",
"inbound-smtp.us-east-1.amazonaws.com"
]
},
"the-kingdom.net": {
"mode": "testing",
"mxs": [
"jane.the-kingdom.net",
"trent.the-kingdom.net"
]
},
"thejonsey.com": {
"mode": "testing",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"thetorri.net": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"thomaskoscheck.de": {
"mode": "testing",
"mxs": [
"mail.thomaskoscheck.de",
"mx.zoho.eu"
]
},
"tigreraye.org": {
"mode": "enforce",
"mxs": [
"tigreraye.org"
]
},
"tilburg.nl": {
"mode": "testing",
"mxs": [
"mail1.tilburg.nl",
"mail2.tilburg.nl"
]
},
"timkoop.de": {
"mode": "testing",
"mxs": [
"mail.timkoop.de"
]
},
"tityrus.be": {
"mode": "testing",
"mxs": [
"r1.tityrus.be"
]
},
"tmthrgd.dev": {
"mode": "enforce",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"tomasmoberg.org": {
"mode": "enforce",
"mxs": [
"mail.protonmail.ch",
"mailsec.protonmail.ch"
]
},
"tomthorogood.co.uk": {
"mode": "enforce",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"tomthorogood.uk": {
"mode": "enforce",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"tonytan.io": {
"mode": "enforce",
"mxs": [
"mail.protonmail.ch"
]
},
"townofmineral.net": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"tritiumdisposal.com": {
"mode": "enforce",
"mxs": [
"tritiumdisposal.com"
]
},
"trolldi.eu.org": {
"mode": "enforce",
"mxs": [
"trolldi.eu.org"
]
},
"trousers.co.uk": {
"mode": "enforce",
"mxs": [
"a.mx.cendata.co.uk"
]
},
"truong.fi": {
"mode": "enforce",
"mxs": [
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"tst.nhs.uk": {
"mode": "testing",
"mxs": [
".tst.nhs.uk"
]
},
"tuta.io": {
"mode": "testing",
"mxs": [
"mail.tutanota.de"
]
},
"tutamail.com": {
"mode": "testing",
"mxs": [
"mail.tutanota.de"
]
},
"tutanota.de": {
"mode": "testing",
"mxs": [
"mail.tutanota.de"
]
},
"twancoenraad.nl": {
"mode": "enforce",
"mxs": [
"in1-smtp.messagingengine.com",
"in2-smtp.messagingengine.com"
]
},
"uleiko.lv": {
"mode": "testing",
"mxs": [
"pasts.uleiko.lv"
]
},
"ulys.ch": {
"mode": "enforce",
"mxs": [
"mta-gw.infomaniak.ch"
]
},
"umontpellier.fr": {
"mode": "testing",
"mxs": [
".umontpellier.fr"
]
},
"urbaninnovations.com": {
"mode": "testing",
"mxs": [
"mailcleaner.urbaninnovations.com"
]
},
"uriports.com": {
"mode": "enforce",
"mxs": [
"uriports.com"
]
},
"urti-k.fr": {
"mode": "enforce",
"mxs": [
"arch-server.dhautefeuille.eu"
]
},
"urtik.fr": {
"mode": "enforce",
"mxs": [
"arch-server.dhautefeuille.eu"
]
},
"us-core.com": {
"mode": "enforce",
"mxs": [
".us-core.com"
]
},
"vconesa.es": {
"mode": "enforce",
"mxs": [
"mx.flipmail.es"
]
},
"venev.name": {
"mode": "testing",
"mxs": [
"pmx1.venev.name",
"smx1.venev.name",
"smx2.venev.name"
]
},
"verzinkerei-rentrop.de": {
"mode": "testing",
"mxs": [
"mail.verzinkerei-rentrop.de"
]
},
"vestibtech.com": {
"mode": "enforce",
"mxs": [
"host-klax-c.vestibtech.com",
"host-kewr-e.vestibtech.com"
]
},
"vfdworld.com": {
"mode": "testing",
"mxs": [
"vfdworld.com",
"aws.vfdworld.com"
]
},
"vigilante.one": {
"mode": "testing",
"mxs": [
"aspmx.l.google.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com",
"alt3.aspmx.l.google.com",
"alt4.aspmx.l.google.com"
]
},
"virtualfreedom.de": {
"mode": "testing",
"mxs": [
"mail.virtualfreedom.de"
]
},
"volk.kiev.ua": {
"mode": "enforce",
"mxs": [
"mx01.pnnsoft.com"
]
},
"w5gfe.org": {
"mode": "testing",
"mxs": [
"ns.w5gfe.org"
]
},
"walkingandcycling.org.uk": {
"mode": "enforce",
"mxs": [
"6ae66d92.21.ik2.com",
"6ae66d92.22.ik2.io",
"6ae66d92.23.ik2.eu"
]
},
"wallisch.pro": {
"mode": "testing",
"mxs": [
".mailbox.org",
"mxext1.mailbox.org",
"mxext2.mailbox.org",
"mxext3.mailbox.org"
]
},
"walmsley.gen.nz": {
"mode": "testing",
"mxs": [
"home.walmsley.gen.nz"
]
},
"wapgc.com": {
"mode": "testing",
"mxs": [
"aspmx5.googlemail.com",
"aspmx2.googlemail.com",
"aspmx.l.google.com",
"aspmx3.googlemail.com",
"alt2.aspmx.l.google.com",
"aspmx4.googlemail.com",
"alt1.aspmx.l.google.com"
]
},
"wassa.io": {
"mode": "testing",
"mxs": [
"mail.wassa.io"
]
},
"williamjohngauthier.net": {
"mode": "enforce",
"mxs": [
"mail.wjg.dk"
]
},
"wjg.ca": {
"mode": "enforce",
"mxs": [
"mail.wjg.dk"
]
},
"wjg.dk": {
"mode": "enforce",
"mxs": [
"mail.wjg.dk"
]
},
"wjg.se": {
"mode": "enforce",
"mxs": [
"mail.wjg.dk"
]
},
"woofercare.uk": {
"mode": "enforce",
"mxs": [
"unaszplodrmann.plus.com"
]
},
"workroomhost.com": {
"mode": "testing",
"mxs": [
"mx.workroomhost.com"
]
},
"wto.economy.gov.ru": {
"mode": "testing",
"mxs": [
"mx.wto.economy.gov.ru"
]
},
"wurzelchaos.de": {
"mode": "testing",
"mxs": [
"mail.wurzelchaos.de",
"goldmund.wurzelchaos.de"
]
},
"ximex.at": {
"mode": "enforce",
"mxs": [
"mail.ximex.at",
"mxext1.mailbox.org",
"mxext2.mailbox.org",
"mxext3.mailbox.org"
]
},
"xmission.com": {
"mode": "testing",
"mxs": [
"mx.xmission.com"
]
},
"xpd.se": {
"mode": "enforce",
"mxs": [
"smtp.xpd.se"
]
},
"xsen.de": {
"mode": "enforce",
"mxs": [
".xsen.de"
]
},
"xserveshack.com": {
"mode": "testing",
"mxs": [
"jane.the-kingdom.net",
"trent.the-kingdom.net"
]
},
"xxblackburnxx.nl": {
"mode": "testing",
"mxs": [
".xxblackburnxx.nl",
"lexi.xxblackburnxx.nl"
]
},
"yafd.de": {
"mode": "testing",
"mxs": [
"mxext1.mailbox.org",
"mxext2.mailbox.org",
"mxext3.mailbox.org"
]
},
"ydh.nhs.uk": {
"mode": "testing",
"mxs": [
".ydh.nhs.uk"
]
},
"yq5.de": {
"mode": "testing",
"mxs": [
"yq5.de"
]
},
"zeroanarchy.com": {
"mode": "enforce",
"mxs": [
"zeroanarchy.com"
]
},
"zerobase.jp": {
"mode": "enforce",
"mxs": [
"aspmx.l.google.com",
"aspmx2.googlemail.com",
"aspmx3.googlemail.com",
"aspmx4.googlemail.com",
"aspmx5.googlemail.com",
"alt1.aspmx.l.google.com",
"alt2.aspmx.l.google.com"
]
},
"zerties.org": {
"mode": "testing",
"mxs": [
"mailgate.zerties.org"
]
},
"zli.ch": {
"mode": "enforce",
"mxs": [
"relay.zli.ch"
]
},
"zumbi.com.ar": {
"mode": "testing",
"mxs": [
"mail.zumbi.com.ar"
]
},
"zumbi.xyz": {
"mode": "enforce",
"mxs": [
"mail.zumbi.xyz"
]
}
}
}
================================================
FILE: policy.json.asc
================================================
-----BEGIN PGP SIGNATURE-----
iQFMBAABCgA2FiEELDGd5HBmwgDf3E1rhCrqQMW81uEFAl7FZ/gYHHN0YXJ0dGxz
LXBvbGljeUBlZmYub3JnAAoJEIQq6kDFvNbh97UH/0EgsDI1VPBwhTSKgR4dZi5X
HHS9uwWnhdHh2P9GhOul30n/qL4G3tLhTWXehdnOaRRhtYdrlGGmvffo2Rk+8xSI
L96HvnHR9zL4JS5MhVudsaYm12V87vHWhCoMR495gGSRMbxwHU9IZNRklc/KWvw6
M8LIXQDUM9dcmvg6S1Lak0/h8o6gRrJOul0SwDKYy5aM8oWrOUXpxiSwedjIetnX
G1XCBcr9UJNMrZc2/yOYwAEKjjS8uYy87O0oCfqCBNKT5nMKsnZuBeooL2uLT90Q
uryOxRuV3GZkBVN34HmpAA1D+MJ1dXM+yPVEy3WhHBJ6YOigeP7vrd+Y9leuXVI=
=s+pE
-----END PGP SIGNATURE-----
================================================
FILE: schema/policy-0.1.schema.json
================================================
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://raw.githubusercontent.com/EFForg/starttls-everywhere/master/schema/policy-0.1.schema.json",
"title": "STARTTLS-Everywhere policy list",
"description": "A list of email domains who meet a minimum set of security requirements.",
"type": "object",
"properties": {
"timestamp": {
"description": "When this configuration file was distributed/fetched, in UTC. Can be in epoch seconds from 00:00:00 UTC on 1 January 1970, or a string yyyy-MM-dd'T'HH:mm:ssZZZZ. This field will be monotonically increasing for every update to the policy file. When updating this policy file, should validate that the timestamp is greater than or equal to the existing one.",
"type": ["string", "integer"],
"minimum": 0,
"pattern": "^(?:[1-9]\\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d+)?(?:Z|[+-][01]\\d:[0-5]\\d)$"
},
"expires": {
"description": "When this configuration file expires, in UTC. Can be in epoch seconds from 00:00:00 UTC on 1 January 1970, or a string yyyy-MM-dd'T'HH:mm:ssZZZZ. If the file has ceased being regularly updated for any reason, and the policy file has expired, the MTA should fall-back to opportunistic TLS for e-mail delivery, and the system operator should be alerted.",
"type": ["string", "integer"],
"minimum": 0,
"pattern": "^(?:[1-9]\\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d+)?(?:Z|[+-][01]\\d:[0-5]\\d)$"
},
"version": {
"description": "Version of the configuration file.",
"type": "string",
"const": "0.1"
},
"author": {
"description": "Author of policy list.",
"type": "string"
},
"policy-aliases": {
"description": "A mapping of alias names onto a policy. Domains in the `policies` field can refer to policies defined in this object.",
"type": "object",
"patternProperties": {
".": { "$ref": "#/definitions/policyDefinition" }
},
"additionalProperties": false
},
"policies": {
"description": "A mapping of mail domains (the part of an address after the `@`) onto a policy. Matching of mail domains is on an exact-match basis. For instance, `eff.org` would be listed separately from `lists.eff.org`. Fields in this policy specify security requirements that should be applied when connecting to any MTA server for a given mail domain. If the `mode` is `testing`, then the sender should not stop mail delivery on policy failures, but should produce logging information.",
"type": "object",
"patternProperties": {
"^([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z0-9]{2,63}$": {
"oneOf": [
{ "$ref": "#/definitions/policyAliasReference" },
{ "$ref": "#/definitions/policyDefinition" }
]
}
},
"additionalProperties": false
}
},
"required": [ "timestamp", "expires", "version", "policies", "policy-aliases" ],
"additionalProperties": false,
"definitions": {
"policyAliasReference": {
"type": "object",
"properties": {
"policy-alias": {
"type": "string",
"description": "If set, other fields are ignored. This value should be a key in the upper-level `policy-aliases` configuration object. The policy for this domain will be configured as the denoted policy in the `policy-aliases` object."
}
},
"required": [ "policy-alias" ],
"additionalProperties": false
},
"policyDefinition": {
"type": "object",
"properties": {
"mode": {
"description": "Default: testing (required)\nEither testing or enforce. If testing is set, then any failure in TLS negotiation is logged and reported, but the message is sent over the insecure communication.",
"enum": [ "testing", "enforce" ]
},
"mxs": {
"type": "array",
"description": "A list of hostnames that the recipient email server's certificates could be valid for. If the server's certificate matches no entry in mxs, the MTA should fail delivery or log an advisory failure, according to mode. Entries in the mxs list can either be a suffix indicated by a leading dot .example.net or a fully qualified domain name mail.example.com. Arbitrarily deep subdomains can match a particular suffix. For instance, mta7.am0.yahoodns.net would match .yahoodns.net.",
"minItems": 1,
"uniqueItems": true,
"items": {
"type": "string",
"pattern": "^\\.?([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z0-9]{2,63}$"
},
"additionalItems": false
}
},
"required": [ "mxs", "mode" ],
"additionalProperties": false
}
}
}
================================================
FILE: scripts/starttls-policy.cron.d
================================================
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 */12 * * * root perl -e "sleep int(rand(3600))" && /bin/sh ./update_and_verify.sh
================================================
FILE: scripts/update_and_verify.sh
================================================
#!/bin/sh
# Depends on wget and gpgv
# Since this tries to modify an /etc/ directory, should be
# run with escalated permissions.
set -e
JSON_FILE="policy.json"
SIG_FILE="$JSON_FILE.asc"
REMOTE_DIR="https://dl.eff.org/starttls-everywhere"
LOCAL_DIR="/etc/starttls-policy"
TMP_DIR="$(mktemp -d)"
TMP_EXT="tmp"
clean_and_exit() {
rc=$?
rm -rf "$TMP_DIR"
exit $rc
}
# traps on regular exit, SIGHUP SIGINT SIGQUIT SIGTERM
trap clean_and_exit 0 1 2 3 15
# Fetch remote source
wget --quiet "$REMOTE_DIR/$JSON_FILE" -O "$TMP_DIR/$JSON_FILE"
wget --quiet "$REMOTE_DIR/$SIG_FILE" -O "$TMP_DIR/$SIG_FILE"
"$(dirname $0)/verify.sh" $LOCAL_DIR $TMP_DIR
# Perform update from tmp => local
mkdir -p $LOCAL_DIR
cp "$TMP_DIR/$JSON_FILE" "$LOCAL_DIR/$JSON_FILE.$TMP_EXT"
cp "$TMP_DIR/$SIG_FILE" "$LOCAL_DIR/$SIG_FILE.$TMP_EXT"
mv "$LOCAL_DIR/$JSON_FILE.$TMP_EXT" "$LOCAL_DIR/$JSON_FILE"
mv "$LOCAL_
gitextract_h1n5mfwv/
├── .dir-locals.el
├── .gitignore
├── .pylintrc
├── .travis.yml
├── LICENSE.TXT
├── README.md
├── RULES.md
├── USAGE.md
├── VALIDATION.md
├── code_legacy/
│ ├── PostfixConfigGenerator.py
│ ├── PostfixLogSummary.py
│ └── TestPostfixConfigGenerator.py
├── policy.json
├── policy.json.asc
├── schema/
│ └── policy-0.1.schema.json
├── scripts/
│ ├── starttls-policy.cron.d
│ ├── update_and_verify.sh
│ └── verify.sh
├── share/
│ ├── golden-domains.txt
│ └── google-starttls-domains.csv
├── test_rules/
│ ├── bigger_test_config.json
│ └── config.json
├── tests/
│ ├── policy_test.py
│ ├── test-requirements.txt
│ └── validate_signature.sh
└── tools/
├── CheckSTARTTLS.py
└── ProcessGoogleSTARTTLSDomains.py
SYMBOL INDEX (48 symbols across 5 files)
FILE: code_legacy/PostfixConfigGenerator.py
function parse_line (line 17) | def parse_line(line_data):
class ExistingConfigError (line 32) | class ExistingConfigError(ValueError): pass
class PostfixConfigGenerator (line 35) | class PostfixConfigGenerator:
method __init__ (line 36) | def __init__(self,
method find_postfix_cf (line 61) | def find_postfix_cf(self):
method ensure_cf_var (line 65) | def ensure_cf_var(self, var, ideal, also_acceptable):
method wrangle_existing_config (line 97) | def wrangle_existing_config(self):
method maybe_add_config_lines (line 124) | def maybe_add_config_lines(self, fopen=open):
method set_domainwise_tls_policies (line 151) | def set_domainwise_tls_policies(self, fopen=open):
method prepare (line 183) | def prepare(self):
method get_version (line 253) | def get_version(self):
method more_info (line 276) | def more_info(self):
method get_all_names (line 296) | def get_all_names(self):
method deploy_cert (line 310) | def deploy_cert(self, domain, _cert_path, key_path, _chain_path, fullc...
method enhance (line 326) | def enhance(self, domain, enhancement, options=None):
method supported_enhancements (line 339) | def supported_enhancements(self):
method get_all_certs_keys (line 346) | def get_all_certs_keys(self):
method save (line 370) | def save(self, title=None, temporary=False):
method rollback_checkpoints (line 385) | def rollback_checkpoints(self, rollback=1):
method recovery_routine (line 390) | def recovery_routine(self):
method view_config_changes (line 398) | def view_config_changes(self):
method config_test (line 403) | def config_test(self):
method restart (line 414) | def restart(self):
method update_CAfile (line 426) | def update_CAfile(self):
function usage (line 430) | def usage():
FILE: code_legacy/PostfixLogSummary.py
function get_counts (line 29) | def get_counts(input, config, earliest_timestamp):
function print_summary (line 68) | def print_summary(counts):
FILE: code_legacy/TestPostfixConfigGenerator.py
function GetFakeOpen (line 32) | def GetFakeOpen(fake_file_contents):
class TestPostfixConfigGenerator (line 44) | class TestPostfixConfigGenerator(unittest.TestCase):
method setUp (line 46) | def setUp(self):
method tearDown (line 55) | def tearDown(self):
method testGetAllNames (line 58) | def testGetAllNames(self):
method testGetAllCertAndKeys (line 68) | def testGetAllCertAndKeys(self):
method testGetAllCertsAndKeys_With_None (line 80) | def testGetAllCertsAndKeys_With_None(self):
FILE: tests/policy_test.py
class TestPolicyList (line 13) | class TestPolicyList(unittest.TestCase):
method setUp (line 14) | def setUp(self):
method test_schema_valid (line 20) | def test_schema_valid(self):
method test_links_ok (line 23) | def test_links_ok(self):
FILE: tools/CheckSTARTTLS.py
function mkdirp (line 19) | def mkdirp(path):
function extract_names (line 27) | def extract_names(pem):
function tls_connect (line 51) | def tls_connect(mx_host, mail_domain):
function valid_cert (line 70) | def valid_cert(filename):
function check_certs (line 89) | def check_certs(mail_domain):
function common_suffix (line 112) | def common_suffix(hosts):
function extract_names_from_openssl_output (line 123) | def extract_names_from_openssl_output(certificates_file):
function supports_starttls (line 128) | def supports_starttls(mx_host):
function min_tls_version (line 147) | def min_tls_version(mail_domain):
function collect (line 156) | def collect(mail_domain):
Condensed preview — 27 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (586K chars).
[
{
"path": ".dir-locals.el",
"chars": 121,
"preview": ";; emacs local configuration settings for starttls source\n((js-mode\n (indent-tabs-mode . nil)\n (js-indent-level . 2)))"
},
{
"path": ".gitignore",
"chars": 16,
"preview": "*.orig\n*.pyc\n*~\n"
},
{
"path": ".pylintrc",
"chars": 10525,
"preview": "[MASTER]\n\n# use as many jobs as there are cores\njobs=0\n\n# Specify a configuration file.\n#rcfile=\n\n# Python code to execu"
},
{
"path": ".travis.yml",
"chars": 144,
"preview": "language: python\npython:\n - \"3.6\"\ninstall:\n - pip install -r tests/test-requirements.txt\nscript:\n - pytest\n - ./test"
},
{
"path": "LICENSE.TXT",
"chars": 10789,
"preview": "STARTTLS Everywhere Policy Database and Helper Code\nCopyright (c) Electronic Frontier Foundation and others\n\nThis reposi"
},
{
"path": "README.md",
"chars": 7821,
"preview": "# STARTTLS Everywhere\n\nSTARTTLS Everywhere is an initiative for upgrading the security of the email ecosystem. Several s"
},
{
"path": "RULES.md",
"chars": 4833,
"preview": "# Policy rule configuration format\n\nThe TLS policy file is a `json` file which conforms to the following specification. "
},
{
"path": "USAGE.md",
"chars": 3051,
"preview": "# STARTTLS Policy List Usage Guidelines\n\nFor information about configuration of receiving mailservers and addition of a "
},
{
"path": "VALIDATION.md",
"chars": 6146,
"preview": "# STARTTLS Policy List Validation\n\nFor information about configuration of sending mailservers and using the list to vali"
},
{
"path": "code_legacy/PostfixConfigGenerator.py",
"chars": 18243,
"preview": "#!/usr/bin/env python\n\nimport logging\nimport sys\nimport string\nimport subprocess\nimport os, os.path\n\n\nlogger = logging.g"
},
{
"path": "code_legacy/PostfixLogSummary.py",
"chars": 5310,
"preview": "#!/usr/bin/env python\nimport argparse\nimport collections\nimport os\nimport re\nimport sys\nimport time\n\nimport Config\n\nTIME"
},
{
"path": "code_legacy/TestPostfixConfigGenerator.py",
"chars": 2571,
"preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nfrom __future__ import absolute_import\nfrom __future__ import division\nfr"
},
{
"path": "policy.json",
"chars": 121029,
"preview": "{\n \"timestamp\": \"2020-05-20T10:25:12.710034-07:00\",\n \"expires\": \"2020-06-03T10:25:12.710055-07:00\",\n \"version\": \"0.1\""
},
{
"path": "policy.json.asc",
"chars": 520,
"preview": "-----BEGIN PGP SIGNATURE-----\n\niQFMBAABCgA2FiEELDGd5HBmwgDf3E1rhCrqQMW81uEFAl7FZ/gYHHN0YXJ0dGxz\nLXBvbGljeUBlZmYub3JnAAoJ"
},
{
"path": "schema/policy-0.1.schema.json",
"chars": 5678,
"preview": "{\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"$id\": \"https://raw.githubusercontent.com/EFForg/starttl"
},
{
"path": "scripts/starttls-policy.cron.d",
"chars": 165,
"preview": "SHELL=/bin/sh\nPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\n\n0 */12 * * * root perl -e \"sleep int(ra"
},
{
"path": "scripts/update_and_verify.sh",
"chars": 960,
"preview": "#!/bin/sh\n\n# Depends on wget and gpgv\n# Since this tries to modify an /etc/ directory, should be\n# run with escalated pe"
},
{
"path": "scripts/verify.sh",
"chars": 3604,
"preview": "#!/bin/sh\n\n# Depends on gpgv\n# Arguments:\n# verify.sh <directory of old policy> <directory of new policy>\n# Verifies s"
},
{
"path": "share/golden-domains.txt",
"chars": 334,
"preview": "163.com\naol.com\nbigpond.com\ncomcast.net\ncraigslist.org\nfacebook.com\ngmail.com\ngmx.de\nhotmail.com\nicloud.com\nlive.com\nmac"
},
{
"path": "share/google-starttls-domains.csv",
"chars": 345462,
"preview": "Address Suffix,Hostname Suffix,Direction,UN M.49 Region Code,Region Name,Fraction Encrypted\n0101.co.jp,0101.co.jp,inboun"
},
{
"path": "test_rules/bigger_test_config.json",
"chars": 439,
"preview": "{\n \"version\": \"0.1\",\n \"author\": \"Electronic Frontier Foundation https://eff.org\",\n \"expires\": \"2015-08-01T12:00:00+08"
},
{
"path": "test_rules/config.json",
"chars": 315,
"preview": "{\n \"version\": \"0.1\",\n \"author\": \"Electronic Frontier Foundation\",\n \"expires\": 1404677353,\n \"timestamp\": 1401"
},
{
"path": "tests/policy_test.py",
"chars": 968,
"preview": "#!/usr/bin/env python\n\nimport unittest\nimport os\nimport json\n\nfrom jsonschema import validate\n\nROOT_DIR, _ = os.path.spl"
},
{
"path": "tests/test-requirements.txt",
"chars": 18,
"preview": "jsonschema>=3.0.0\n"
},
{
"path": "tests/validate_signature.sh",
"chars": 568,
"preview": "#!/bin/sh\n\n# Arguments:\n# ./validate_signature.sh <path-to-policy.json> <path-to-policy.json.asc>\n\nset -e\n\nJSON_FILE=\"po"
},
{
"path": "tools/CheckSTARTTLS.py",
"chars": 6628,
"preview": "#!/usr/bin/env python\nimport sys\nimport os\nimport errno\nimport smtplib\nimport socket\nimport subprocess\nimport re\nimport "
},
{
"path": "tools/ProcessGoogleSTARTTLSDomains.py",
"chars": 1240,
"preview": "#!/usr/bin/env python\n\"\"\"\nProcess Google's TLS delivery data from\nhttps://www.google.com/transparencyreport/saferemail/d"
}
]
About this extraction
This page contains the full source code of the EFForg/starttls-everywhere GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 27 files (544.4 KB), approximately 185.9k tokens, and a symbol index with 48 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.