Домены на русском, китайском, арабском и других языках работают в DNS благодаря Punycode: алгоритм превращает интернационализированные имена (IDN) в ASCII-строку, с которой умеют работать классические DNS и большинство сетевых утилит.
Что такое Punycode
Punycode – способ кодирования Unicode-меток домена в набор символов LDH (латиница, цифры, дефис). DNS исторически рассчитан на ASCII, поэтому кириллица или иероглифы «как есть» в зоне не живут: их кодируют, а клиенты (браузер, библиотека IDNA) показывают пользователю привычный вид.
Пример: пример.рф в ASCII-форме выглядит как xn--e1afmkfd.xn--p1ai. Префикс xn-- (ACE-префикс) помечает, что метка закодирована через Punycode в рамках IDNA.
Зачем это нужно
- Совместимость с DNS. Серверы, резолверы и старые клиенты видят только ASCII. Punycode даёт единый wire-формат без смены протокола DNS.
- Интернационализация. Можно регистрировать и использовать имена на родном языке, сохраняя глобальную маршрутизацию имён.
- Удобство для людей. В интерфейсе показывается IDN, а в логах, сертификатах, WHOIS и CLI часто видна xn-- форма – обе относятся к одному имени.
Как это устроено
Каждая метка имени (кусок между точками) обрабатывается отдельно. Символы вне базового ASCII кодируются; результат получает префикс xn--. Точка-разделитель меток остаётся точкой. Полное имя собирается из закодированных меток.
- Исходное имя:
пример.рф - После IDNA/Punycode:
xn--e1afmkfd.xn--p1ai - Именно эту строку обычно отправляют в DNS-запросах A/AAAA/MX и т.д.
Стандарты: Punycode описан в RFC 3492, применение к доменам – в IDNA (RFC 5890-5891 и связанные). Для практики достаточно помнить: UI = Unicode, DNS wire = ASCII с xn--.
Как конвертировать
Быстрый вариант в браузере – конвертер Punycode на этом сайте: вставили домен, получили ASCII-форму и обратно.
В Python удобна библиотека idna:
import idna
domain = "пример.рф"
punycode_domain = idna.encode(domain).decode("utf-8")
print(punycode_domain) # xn--e1afmkfd.xn--p1ai
# обратно
print(idna.decode(punycode_domain))
В shell, если есть подходящие утилиты (зависит от пакетов):
# пример через Python one-liner
python3 -c 'import idna; print(idna.encode("пример.рф").decode())'
В DNS-записях, Certbot/Let’s Encrypt, nginx server_name и почтовых конфигах надёжнее явно указывать xn-- форму или то, что ожидает конкретный софт (многие современные стеки принимают Unicode и кодируют сами).
Фишинг и похожие символы
У Punycode/IDN есть обратная сторона: гомографы. Кириллическая «а» и латинская «a» в шрифте выглядят одинаково, а в DNS это разные кодовые точки и разные имена. Так собирают поддельные домены под известные бренды.
Браузеры частично смягчают риск: при подозрительных смешениях алфавитов в адресной строке показывают Punycode (xn--…), а не «красивый» Unicode. Это не отменяет привычку проверять ссылки, сертификат и источник перехода.
Краткий итог
Punycode – транспортный слой для IDN: люди видят родной алфавит, инфраструктура DNS работает с ASCII. Для админов полезно уметь читать xn-- в логах, WHOIS и сертификатах и при необходимости конвертировать имена. Для пользователей – помнить про гомографный фишинг и не доверять только «похожести» адреса.

