-
-
Notifications
You must be signed in to change notification settings - Fork 940
Check SPF/DKIM/DMARC record on dns like MX records #3083
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Thanks for submitting this pull request. bors try Note: if this build fails, read this. |
tryBuild succeeded: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi. Thanks for your contribution.
I was thinking about doing the checks asynchronously (by having a "spinner" image and requesting the check via src="" returning a good or bad image), but this is a good start.
I didn't run in yet, but I think the regex should be changed.
If we do this asynchronously, I will explicitly check all dns entries as well as auto-configuration entries. And check methods could return states like |
Sorry for the delay. At first I thought the simplest way to implement this would be a route to check dns entries like Alex |
Thanks for submitting this pull request. bors try Note: if this build fails, read this. |
tryBuild succeeded: |
Pull request has been modified.
Done via async image loading. Please check the routes for images and css changes |
bors try |
🔒 Permission denied Existing reviewers: click here to make Riscue a reviewer |
@ghostwheel42 Hey alex bors stuck, could you please force for retry and review new commits |
bors try |
tryBuild failed: |
@ghostwheel42 Hey alex fixed a bug, please retry |
bors try |
tryBuild succeeded: |
Hey Alex @ghostwheel42 it is done actually, what should i do next? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @Riscue and sorry for being quiet for so long.
I think this is a good start at checking if the DNS config is like the one proposed.
Of course it is not a 100% check as some mx tools do and it will probably yield false-positives and false negatives, but the people using their own records should know what they are doing (for example when using "include:" in the spf records).
I would move the routes below the 'details' path, so instead of '/domain/<domain_name>/check/mx' I would use '/domain/details/<domain_name>/check/mx'.
This will allow to strip the '../../domain/' and '../../alternative/' from the templates.
@nextgens Do you think we need to do some kind of caching or rate limiting on the check routes to avoid abuse by doing lots of dns queries?
I think after the changes are done we could start testing this in the master branch.
""" checks if DMARC record for domain points to mailu host """ | ||
try: | ||
return any( | ||
rset.to_text().startswith('"v=DMARC1;') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rset.to_text().startswith('"v=DMARC1;') | |
rset.to_text().strip('"').split(';')[0].strip() == 'v=DMARC1' |
This is more robust - also use this for the report check, as there do not need to be any other tags defined.
app_config_domain = app.config['DOMAIN'] | ||
try: | ||
return any( | ||
rset.to_text().startswith('"v=DMARC1;') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rset.to_text().startswith('"v=DMARC1;') | |
rset.to_text().strip('"').split(';')[0].strip() == 'v=DMARC1' |
""" checks if DMARC record for domain points to mailu host """ | ||
try: | ||
return any( | ||
rset.to_text().startswith('"v=DMARC1;') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rset.to_text().startswith('"v=DMARC1;') | |
rset.to_text().strip('"').split(';')[0].strip() == 'v=DMARC1' |
app_config_domain = app.config['DOMAIN'] | ||
try: | ||
return any( | ||
rset.to_text().startswith('"v=DMARC1;') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rset.to_text().startswith('"v=DMARC1;') | |
rset.to_text().strip('"').split(';')[0].strip() == 'v=DMARC1' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ghostwheel42 I'm not worried about it. DNS has a built-in cache mechanism with TTL, this will go no further than the local resolver.
What needs to be checked is how timeouts are handled. Browsers only allow so many parallel connections... if we block awaiting for a DNS reply for several items on the same page, we may exceed the limit. It may be better to timeout earlier and return some "unknown" png faster... refreshing the page (which could also be done automatically) would then display the right results
try: | ||
hostnames = app.config['HOSTNAMES'].replace(',', '|') | ||
return any( | ||
re.search(f'^"v=spf1 mx a:({hostnames}) [?+-~]all"$', rset.to_text()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[?+-~]
without escapes and without marking the string as a regexp pattern? -
will break for sure
try: | ||
hostnames = app.config['HOSTNAMES'].replace(',', '|') | ||
return any( | ||
re.search(f'^"v=spf1 mx a:({hostnames}) [?+-~]all"$', rset.to_text()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
return False | ||
|
||
|
||
def check_spf(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's avoid code duplication please, make those methods static or something
What type of PR?
Enhancement
What does this PR do?
Checks TXT records for SPF, DKIM, DMARC same as MX record checker