diff --git a/mo/users.py b/mo/users.py
index b57c6e0557861c16c31f7ac9afb63089d2d94aeb..e765fe2f5366c20d0b778c54568b8aea8b9c44e1 100644
--- a/mo/users.py
+++ b/mo/users.py
@@ -3,6 +3,8 @@
 import bcrypt
 import datetime
 import dateutil.tz
+import dns.exception
+import dns.resolver
 import email.errors
 import email.headerregistry
 import re
@@ -246,7 +248,44 @@ def find_or_create_participation(user: db.User, contest: db.Contest, place: Opti
     return pion, is_new
 
 
-def normalize_email(addr: str) -> str:
+def email_is_fake(addr: str) -> bool:
+    return addr.endswith('@nomail') or addr.endswith('@test')
+
+
+bad_domains = {
+    'gmail.cz',
+}
+
+
+def email_check_domain(domain: str):
+    # Některé domény rovnou odmítáme
+    if domain in bad_domains:
+        logger.info(f'DNS: Doména <{domain}> na blacklistu')
+        raise mo.CheckError('Doména {domain} nepřijímá poštu')
+
+    for record in ['MX', 'A', 'AAAA']:
+        try:
+            dns.resolver.resolve(domain, record, lifetime=2, search=False)
+        except dns.exception.Timeout:
+            # Kontrola je konzervativní, při timeoutu adresu raději schválíme
+            logger.info(f'DNS: Timeout při kontrole domény <{domain}>')
+            return
+        except dns.resolver.NoAnswer:
+            logger.debug(f'DNS: Doména <{domain}> neobsahuje {record}')
+        except dns.resolver.NXDOMAIN:
+            logger.info(f'DNS: Doména <{domain}> neexistuje')
+            raise mo.CheckError('Adresa obsahuje neexistující doménu {domain}')
+        except dns.exception.DNSException as e:
+            logger.warn(f'DNS: Záznam <{domain}>/{record} nejde resolvovat: {e}')
+            return
+        logger.debug(f'DNS: Doména <{domain}> OK')
+        return
+
+    logger.info(f'DNS: Doména <{domain}> nepřijímá poštu')
+    raise mo.CheckError('Doména {domain} nepřijímá poštu')
+
+
+def normalize_email(addr: str, check_existence: bool = False) -> str:
     if not re.fullmatch(r'.+@.+', addr):
         raise mo.CheckError('V e-mailové adrese chybí zavináč')
 
@@ -263,10 +302,16 @@ def normalize_email(addr: str) -> str:
     try:
         # Tady úmyslně používáme knihovnu jen ke kontrole a ne k normalizaci,
         # protože nechceme riskovat, že se normalizovaný tvar časem změní.
-        email.headerregistry.Address(addr_spec=addr)
+        addr_obj = email.headerregistry.Address(addr_spec=addr)
     except (email.errors.HeaderParseError, ValueError):
         raise mo.CheckError('Chybná syntaxe mailové adresy')
 
+    if addr_obj.display_name != "":
+        raise mo.CheckError('Chybná syntaxe mailové adresy')
+
+    if check_existence and not email_is_fake(addr):
+        email_check_domain(addr_obj.domain)
+
     # XXX: Striktně vzato, tohle není korektní, protože některé domény mohou
     # mít case-sensitive levou stranu adresy. Ale i na nich se prakticky nevyskytují
     # levé strany s velkými písmeny, zatímco uživatelé při psaní adres běžně velká