mirror of
https://github.com/nicolabs/gandi-spf-flatten.git
synced 2026-05-21 12:13:02 +02:00
Added -E option to preserve the domain name in the final SPF record
This commit is contained in:
parent
786b4fe8f9
commit
afe76e2bea
31
README.md
31
README.md
|
|
@ -16,11 +16,38 @@ Other useful resources on SPF :
|
||||||
- [SPF Record Syntax](https://dmarcian.com/spf-syntax-table/)
|
- [SPF Record Syntax](https://dmarcian.com/spf-syntax-table/)
|
||||||
- [Can I have a TXT or SPF record longer than 255 characters?](https://kb.isc.org/docs/aa-00356)
|
- [Can I have a TXT or SPF record longer than 255 characters?](https://kb.isc.org/docs/aa-00356)
|
||||||
|
|
||||||
|
## Current manual
|
||||||
|
|
||||||
|
usage: gandi-flatten-spf.py [-h] -d DOMAIN [DOMAIN ...] -e EMAIL_PROVIDERS [EMAIL_PROVIDERS ...] -E EMAIL_PROVIDERS_AS_IS [EMAIL_PROVIDERS_AS_IS ...] [-k API_KEY] [-r DNS [DNS ...]] [-l LOG_LEVEL]
|
||||||
|
[-L LOAD] [-K]
|
||||||
|
|
||||||
|
Flatten SPF records using Gandi's Live DNS API
|
||||||
|
|
||||||
|
options:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
-d DOMAIN [DOMAIN ...], --domain DOMAIN [DOMAIN ...]
|
||||||
|
Domains you own from which to update the TXT record for SPF
|
||||||
|
-e EMAIL_PROVIDERS [EMAIL_PROVIDERS ...], --email-providers EMAIL_PROVIDERS [EMAIL_PROVIDERS ...]
|
||||||
|
E-mail providers' SPF domains to add to the TXT record AFTER CONVERSION to a list of IP addresses
|
||||||
|
-E EMAIL_PROVIDERS_AS_IS [EMAIL_PROVIDERS_AS_IS ...], --email-providers-as-is EMAIL_PROVIDERS_AS_IS [EMAIL_PROVIDERS_AS_IS ...]
|
||||||
|
E-mail providers' SPF domains to add to the TXT record AS-IS (no IP conversion)
|
||||||
|
-k API_KEY, --api-key API_KEY
|
||||||
|
Your Gandi API key (otherwise looks for the 'GANDI_APIKEY' environment variable)
|
||||||
|
-r DNS [DNS ...], --dns DNS [DNS ...]
|
||||||
|
DNS servers to use to resolve into IP addresses
|
||||||
|
-l LOG_LEVEL, --log-level LOG_LEVEL
|
||||||
|
Log level
|
||||||
|
-L LOAD, --load LOAD A JSON file to load the result from Gandi's API instead of calling the API
|
||||||
|
-K, --dry-run Dry-run mode (will not change the records, only print)
|
||||||
|
|
||||||
|
The `-E` option was added because some providers only check that their domain appears in the DNS entries, not the corresponding IP (wrongly, in my opinion), so you can preserve the domains in the final TXT record.
|
||||||
|
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
python gandi-flatten-spf.py -d mydomain.com -e _spf.mailfence.com _spf.google.com _spf.mail.yahoo.com _mailcust.gandi.net _spf.protonmail.ch -l DEBUG
|
python gandi-flatten-spf.py -d mydomain.com -e _spf.google.com _spf.mail.yahoo.com _mailcust.gandi.net _spf.protonmail.ch -E _spf.mailfence.com -l DEBUG
|
||||||
|
|
||||||
Run without arguments to show the full syntax (including how to pass your Gandi API key).
|
Run without arguments to show the full syntax for your version (including how to pass your Gandi API key).
|
||||||
|
|
||||||
Put in a *cron job* to run on a regular basis and check if there was any change in the IP addresses of the email providers.
|
Put in a *cron job* to run on a regular basis and check if there was any change in the IP addresses of the email providers.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -48,23 +48,27 @@ def spf2ips(records, domain, resolvers):
|
||||||
"""
|
"""
|
||||||
Builds a valid TXT record for SPF by resolving DNS into IP addresses
|
Builds a valid TXT record for SPF by resolving DNS into IP addresses
|
||||||
|
|
||||||
_emailProviders: list of SPF domains of the email providers you want to add to SPF
|
_emailProvidersToIp: list of SPF domains to convert to a list of IPs (of the email providers you want to add to SPF)
|
||||||
|
_emailProvidersToInclude: : list of SPF domains NOT to convert to IP
|
||||||
_nameServers: list of DNS you want to use to resolve domains into IP addresses
|
_nameServers: list of DNS you want to use to resolve domains into IP addresses
|
||||||
|
|
||||||
Returns the TXT record as a string
|
Returns the TXT record as a string
|
||||||
"""
|
"""
|
||||||
def createFlatSpfRecord( _emailProviders, _nameServers ):
|
def createFlatSpfRecord( _emailProvidersToIp, _emailProvidersToInclude, _nameServers ):
|
||||||
|
|
||||||
dnsResolver = resolver.Resolver()
|
dnsResolver = resolver.Resolver()
|
||||||
dnsResolver.nameservers = _nameServers
|
dnsResolver.nameservers = _nameServers
|
||||||
|
|
||||||
ips = []
|
parts = []
|
||||||
for emailProvider in _emailProviders:
|
|
||||||
|
|
||||||
ips = ips + spf2ips({emailProvider: 'txt'}, emailProvider, dnsResolver)
|
for emailProvider in _emailProvidersToIp:
|
||||||
|
parts = parts + spf2ips({emailProvider: 'txt'}, emailProvider, dnsResolver)
|
||||||
|
|
||||||
logging.debug("Flattened IPs : %s",ips)
|
for emailProvider in _emailProvidersToInclude:
|
||||||
return SPF_TEMPLATE.format( includes=" ".join(ips) )
|
parts = parts + ["include:" + emailProvider]
|
||||||
|
|
||||||
|
logging.debug("Flattened IPs : %s",parts)
|
||||||
|
return SPF_TEMPLATE.format( includes=" ".join(parts) )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -187,8 +191,9 @@ def updateDns( _domain, _apikey, _txtRecords, _dryRun=False ):
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Flatten SPF records using Gandi's Live DNS API")
|
parser = argparse.ArgumentParser(description="Flatten SPF records using Gandi's Live DNS API")
|
||||||
parser.add_argument('-d', '--domain', nargs='+', required=True, help="Domains you own from which to update the TXT record for SPF")
|
parser.add_argument('-d', '--domain', nargs='+', required=True, help="Domains you own from which to update the TXT record for SPF")
|
||||||
parser.add_argument('-e', '--email-providers', nargs='+', required=True, help="E-mail providers' SPF domains to add to the TXT record")
|
parser.add_argument('-e', '--email-providers', nargs='+', required=True, help="E-mail providers' SPF domains to add to the TXT record AFTER CONVERSION to a list of IP addresses")
|
||||||
parser.add_argument('-k', '--apikey', help="Your Gandi API key (otherwise looks for the 'GANDI-APIKEY' environment variable)")
|
parser.add_argument('-E', '--email-providers-as-is', nargs='+', required=True, help="E-mail providers' SPF domains to add to the TXT record AS-IS (no IP conversion)")
|
||||||
|
parser.add_argument('-k', '--api-key', help="Your Gandi API key (otherwise looks for the 'GANDI_APIKEY' environment variable)")
|
||||||
parser.add_argument('-r', '--dns', default=DEFAULT_DNS, nargs='+', help="DNS servers to use to resolve into IP addresses")
|
parser.add_argument('-r', '--dns', default=DEFAULT_DNS, nargs='+', help="DNS servers to use to resolve into IP addresses")
|
||||||
parser.add_argument('-l', '--log-level', default=DEFAULT_LOGLEVEL, help="Log level")
|
parser.add_argument('-l', '--log-level', default=DEFAULT_LOGLEVEL, help="Log level")
|
||||||
parser.add_argument('-L', '--load', help="A JSON file to load the result from Gandi's API instead of calling the API")
|
parser.add_argument('-L', '--load', help="A JSON file to load the result from Gandi's API instead of calling the API")
|
||||||
|
|
@ -199,14 +204,14 @@ logging.basicConfig(level=logging.getLevelName(args.log_level))
|
||||||
|
|
||||||
logging.debug(repr(args))
|
logging.debug(repr(args))
|
||||||
|
|
||||||
if args.apikey:
|
if args.api_key:
|
||||||
apikey = args.apikey
|
apikey = args.api_key
|
||||||
else :
|
else :
|
||||||
apikey = os.environ['GANDI_APIKEY']
|
apikey = os.environ['GANDI_APIKEY']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
flatSpf = createFlatSpfRecord(args.email_providers,args.dns)
|
flatSpf = createFlatSpfRecord(args.email_providers,args.email_providers_as_is,args.dns)
|
||||||
for domain in args.domain:
|
for domain in args.domain:
|
||||||
if args.load:
|
if args.load:
|
||||||
txts = file_getTxtRecords(args.load)
|
txts = file_getTxtRecords(args.load)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue