Как назначить статическое имя хоста на машине Linux
Статическое имя хоста — это постоянно настроенная, удобочитаемая метка, присвоенная системе Linux, которая сохраняется после перезагрузки и не перезаписывается сетевыми службами, такими как DHCP. В отличие от временного имени хоста — которое может динамически устанавливаться сетевым демоном и сбрасываться при следующей загрузке — статическое имя хоста хранится на диске и остаётся авторитетным независимо от того, как машина получает свой IP-адрес.
Это различие имеет огромное значение в производственных средах. Когда вы запускаете VPS или выделенный сервер, стабильное имя хоста является основой для записей SSH known-hosts, альтернативных имён субъектов TLS-сертификатов, идентификаторов syslog, меток целевых объектов Prometheus и имён участников Kerberos. Имя хоста, которое незаметно меняется после обновления DHCP, может одновременно нарушить работу всего перечисленного.
Что именно представляет собой имя хоста Linux?
Linux отслеживает три различных класса имён хостов, каждый из которых служит своей цели:
| Тип имени хоста | Место хранения | Область применения | Сохраняется после перезагрузки |
|---|---|---|---|
| Статическое | /etc/hostname | Постоянный идентификатор системы | Да |
| Временное | Только среда выполнения ядра | Временное, устанавливается NTP/DHCP | Нет |
| Отображаемое | /etc/machine-info | Отображаемое имя в UTF-8 (пробелы допустимы) | Да |
Статическое имя хоста — это то, что вы настраиваете намеренно. Временное имя хоста — это то, что ядро использует в данный момент — обычно идентично статическому, если только его не переопределил DHCP-сервер или systemd-timesyncd. Отображаемое имя хоста носит исключительно косметический характер (например, "Alex's Web Server") и никогда не используется в DNS или SSH.
Допустимые статические имена хостов соответствуют правилам RFC 1123: только строчные буквы, цифры и дефисы; никаких символов подчёркивания; никаких ведущих или завершающих дефисов; максимум 63 символа на метку; максимум 253 символа в целом для полностью квалифицированного доменного имени (FQDN).
Проверка текущего имени хоста
Прежде чем вносить какие-либо изменения, проверьте текущее состояние всех трёх типов имён хостов:
hostnamectlПример вывода в системе на базе systemd:
Static hostname: old-server-name
Pretty hostname: Old Server Name
Transient hostname: dhcp-assigned-name
Icon name: computer-server
Chassis: server
Machine ID: a1b2c3d4e5f6...
Boot ID: 9f8e7d6c5b4a...
Operating System: Ubuntu 22.04.3 LTS
Kernel: Linux 5.15.0-91-generic
Architecture: x86-64Если временное имя хоста отличается от статического имени хоста, ваш DHCP-клиент переопределяет статическое значение — эта проблема рассматривается в разделе об обеспечении постоянства ниже.
Для систем без hostnamectl используйте:
hostname
cat /etc/hostname
uname -nМетод 1: Использование hostnamectl (дистрибутивы на базе systemd)
Этот метод применим к Ubuntu 16.04+, Debian 8+, CentOS 7+, RHEL 7+, Fedora 15+, AlmaLinux, Rocky Linux и любому дистрибутиву, использующему systemd в качестве PID 1.
Шаг 1: Установите статическое имя хоста
sudo hostnamectl set-hostname new-static-hostnamehostnamectl записывает значение в /etc/hostname, вызывает системный вызов sethostname(2) для немедленного обновления работающего ядра и уведомляет systemd-hostnamed — всё это атомарно. Перезагрузка не требуется.
Чтобы одновременно установить все три типа имён хостов:
sudo hostnamectl set-hostname "new-static-hostname" --static
sudo hostnamectl set-hostname "New Static Hostname" --pretty
sudo hostnamectl set-hostname "new-static-hostname" --transientШаг 2: Проверьте изменение
hostnamectlУбедитесь, что в поле Static hostname отображается новое значение. Также проверьте, что ядро его подхватило:
hostnameШаг 3: Обновите /etc/hosts
hostnamectl не обновляет /etc/hosts автоматически. Если не обновить этот файл, sudo будет выдавать предупреждение unable to resolve host, приложения, вызывающие gethostbyname() для локального имени хоста, будут работать некорректно, а службы на базе Java (Elasticsearch, Kafka) могут не запуститься.
sudo nano /etc/hostsФайл должен содержать как минимум:
127.0.0.1 localhost
127.0.1.1 new-static-hostname.yourdomain.com new-static-hostnameВторая строка использует 127.0.1.1 (а не 127.0.0.1) для собственного имени хоста машины в системах семейства Debian, что позволяет избежать конфликтов, когда у машины нет статического IP-адреса. В системах семейства RHEL и на машинах с фиксированным IP используйте вместо этого фактический основной IP-адрес:
192.168.1.50 new-static-hostname.yourdomain.com new-static-hostnameЕсли вы управляете VPS с cPanel, инструмент смены имени хоста cPanel обрабатывает /etc/hosts автоматически, однако вам всё равно следует вручную проверить результат.
Метод 2: Ручное редактирование /etc/hostname (дистрибутивы без systemd)
Этот метод применим к более старым выпускам Debian/Ubuntu, использующим SysVinit или Upstart, Alpine Linux, Gentoo с OpenRC, Void Linux и встраиваемым системам.
Шаг 1: Отредактируйте /etc/hostname
sudo nano /etc/hostnameФайл должен содержать ровно одну строку — короткое имя хоста без завершающих пробелов или символов перевода строки, кроме стандартного терминатора строки:
new-static-hostnameШаг 2: Обновите /etc/hosts
sudo nano /etc/hostsПрименяйте то же сопоставление, что описано в Методе 1.
Шаг 3: Примените изменение без перезагрузки
Немедленно уведомите работающее ядро о новом имени хоста:
sudo hostname new-static-hostnameВ системах, где systemd-hostnamed доступен даже без полного внедрения systemd:
sudo systemctl restart systemd-hostnamedВ чистых системах SysVinit приведённой выше команды hostname достаточно. Изменение вступает в силу для всех новых процессов; в существующих оболочках по-прежнему будет отображаться старое приглашение командной строки, пока вы не откроете новый сеанс терминала или не выполните:
exec bashМетод 3: Переопределение через cloud-init (критически важно для облачных экземпляров VPS)
Это наиболее часто упускаемый из виду сценарий. На облачных платформах — включая большинство провайдеров VPS — cloud-init запускается при каждой загрузке и сбрасывает имя хоста на то, которое возвращает API метаданных экземпляра. Ваше изменение в /etc/hostname будет незаметно перезаписано при следующей перезагрузке.
Чтобы статическое имя хоста сохранялось после работы cloud-init, отредактируйте /etc/cloud/cloud.cfg:
sudo nano /etc/cloud/cloud.cfgНайдите или добавьте следующую директиву:
preserve_hostname: trueЛибо создайте файл переопределения, чтобы не изменять конфигурацию, управляемую пакетным менеджером:
sudo mkdir -p /etc/cloud/cloud.cfg.d/
sudo tee /etc/cloud/cloud.cfg.d/99_hostname.cfg > /dev/null <<EOF
preserve_hostname: true
EOFПосле этого изменения cloud-init больше не будет изменять имя хоста при последующих загрузках.
Предотвращение переопределения статического имени хоста через DHCP
Даже без cloud-init DHCP-клиент может перезаписать временное имя хоста. Способ устранения зависит от того, какой DHCP-клиент использует ваш дистрибутив.
Для dhclient (устаревший вариант Debian/Ubuntu)
Отредактируйте /etc/dhcp/dhclient.conf:
sudo nano /etc/dhcp/dhclient.confДобавьте или измените:
send host-name "new-static-hostname";
supersede host-name "new-static-hostname";Директива supersede гарантирует, что клиент будет игнорировать любое имя хоста, предложенное DHCP-сервером.
Для systemd-networkd с systemd-resolved
Отредактируйте или создайте файл .network в /etc/systemd/network/:
[DHCP]
SendHostname=yes
UseHostname=noUseHostname=no предотвращает перезапись статического имени хоста именем, предложенным DHCP.
Для NetworkManager (большинство настольных и современных серверных дистрибутивов)
sudo nmcli con modify "connection-name" ipv4.dhcp-hostname "new-static-hostname"
sudo nmcli con modify "connection-name" ipv4.dhcp-send-hostname yesЧтобы полностью запретить NetworkManager принимать имя хоста от DHCP, добавьте в /etc/NetworkManager/NetworkManager.conf:
[main]
hostname-mode=noneРаспространение имени хоста: что ещё необходимо обновить
Установки имени хоста в ОС необходимо, но недостаточно в сетевой среде. Обратите внимание на следующие зависимые системы:
- Прямые и обратные записи DNS: Обновите запись A и запись PTR в вашей DNS-зоне. Без соответствующей записи PTR многие почтовые серверы будут отклонять исходящую электронную почту, а некоторые инструменты безопасности будут помечать хост как подозрительный.
- SSL/TLS-сертификаты: Если ваше имя хоста является частью CN или SAN сертификата, вам потребуется новый сертификат. SSL-сертификаты, привязанные к старому имени хоста, будут вызывать ошибки проверки.
- Регистрация домена и распространение DNS: Если имя хоста соответствует публичному FQDN, обновите DNS-запись у вашего регистратора доменов и учтите время распространения на основе TTL.
- Агенты мониторинга: Экспортёр узлов Prometheus, Datadog, Zabbix и аналогичные агенты используют имя хоста в качестве метки. После смены имени хоста исторические метрики могут отображаться под другим идентификатором хоста.
/etc/ssh/ssh_known_hosts: Кластерные файлы known-hosts, ссылающиеся на старое имя хоста, необходимо обновить.- Конфигурационные файлы приложений: Любое жёстко заданное имя хоста в конфигурациях приложений, строках подключения JDBC или объявленных слушателях брокеров сообщений необходимо обновить.
Сравнение методов настройки имени хоста
| Метод | Совместимость с дистрибутивами | Требует перезагрузки | Обрабатывает cloud-init | Атомарное обновление |
|---|---|---|---|---|
hostnamectl set-hostname | Дистрибутивы с systemd | Нет | Нет (требуется preserve_hostname) | Да |
Ручное редактирование /etc/hostname | Все дистрибутивы | Нет (с командой hostname) | Нет | Нет |
preserve_hostname cloud-init | Облачные экземпляры | Нет | Да | Н/П |
Конфигурация DHCP-клиента (supersede) | Все дистрибутивы | Нет | Нет | Нет |
nmcli NetworkManager | Системы под управлением NM | Нет | Нет | Да |
Реальные граничные случаи и подводные камни
Подводный камень 1: Цикл предупреждений sudo. Если вы установили имя хоста, но забыли обновить /etc/hosts, каждый вызов sudo будет выводить sudo: unable to resolve host new-static-hostname. Это не критично, но добавляет задержку к каждой привилегированной команде и засоряет журналы.
Подводный камень 2: Службы Java отказываются запускаться. InetAddress.getLocalHost() Java разрешает имя хоста через gethostbyname(). Если имя хоста отсутствует в /etc/hosts или не разрешается через DNS, такие службы, как Elasticsearch, Kafka и Cassandra, выбрасывают UnknownHostException при запуске.
Подводный камень 3: Имя хоста с символами подчёркивания. Несмотря на широкое неформальное использование, символы подчёркивания в именах хостов нарушают RFC 952 и RFC 1123. Некоторые DNS-резолверы, библиотеки TLS и компоненты Kubernetes будут отклонять их или обрабатывать некорректно. Всегда используйте дефисы.
Подводный камень 4: FQDN и короткое имя хоста. hostnamectl хранит только короткое имя хоста (например, web01). FQDN (например, web01.example.com) формируется путём объединения короткого имени хоста со списком поиска доменов в /etc/resolv.conf или /etc/systemd/resolved.conf. Установите Domains=example.com в resolved.conf или search example.com в resolv.conf, чтобы hostname --fqdn возвращал корректное значение.
Подводный камень 5: Изоляция контейнеров и пространств имён. Внутри контейнера Docker или пространства имён LXC команда hostnamectl может завершиться ошибкой Failed to connect to bus: No such file or directory, поскольку systemd-hostnamed не запущен. Используйте hostname new-name напрямую или задайте имя хоста при создании контейнера с помощью docker run --hostname или ключа hostname: в docker-compose.yml.
Практический контрольный список
Используйте этот контрольный список до и после каждой смены имени хоста в производственной среде:
- Убедитесь, что новое имя хоста соответствует RFC 1123 (строчные буквы, только дефисы, максимум 63 символа на метку)
- Выполните
hostnamectlдо внесения изменений и сохраните вывод для целей аудита - Установите статическое имя хоста с помощью
hostnamectl set-hostnameили путём редактирования/etc/hostname - Обновите
/etc/hosts, указав короткое имя хоста и FQDN в одной строке - Если система является облачным экземпляром, установите
preserve_hostname: trueв конфигурации cloud-init - Если активен DHCP, настройте DHCP-клиент на игнорирование имён хостов, предлагаемых сервером
- Обновите записи DNS A и PTR
- Перевыпустите или обновите все TLS-сертификаты, ссылающиеся на старое имя хоста
- Перезапустите службы, зависящие от имени хоста (syslog, агенты мониторинга, Java-приложения)
- Откройте новый сеанс оболочки и убедитесь, что
hostname,hostname --fqdnиhostnamectlвозвращают согласованные значения - Проверьте
/var/log/syslogилиjournalctl -bна наличие ошибок после изменения, связанных со старым именем хоста
Часто задаваемые вопросы
Требует ли hostnamectl set-hostname перезагрузки для вступления в силу?
Нет. hostnamectl немедленно вызывает системный вызов sethostname(2), обновляя работающее ядро в режиме реального времени. Изменение также записывается в /etc/hostname для обеспечения постоянства. Новые процессы и новые сеансы оболочки увидят обновлённое имя хоста без какой-либо перезагрузки.
Почему моё имя хоста сбрасывается после каждой перезагрузки на облачном VPS?
Почти наверняка его перезаписывает cloud-init. Добавьте preserve_hostname: true в /etc/cloud/cloud.cfg или создайте файл переопределения по пути /etc/cloud/cloud.cfg.d/99_hostname.cfg с той же директивой. Это наиболее распространённая причина сброса имени хоста на облачных машинах.
В чём разница между 127.0.0.1 и 127.0.1.1 в /etc/hosts?
127.0.0.1 — это стандартный адрес обратной петли, сопоставленный с localhost. В дистрибутивах семейства Debian 127.0.1.1 используется как дополнительный адрес обратной петли специально для собственного имени хоста машины, что позволяет избежать конфликтов, когда у машины нет статического IP-адреса. В системах семейства RHEL и на машинах с фиксированным IP используйте вместо этого фактический основной IP-адрес для сопоставления имени хоста.
Можно ли использовать символ подчёркивания в имени хоста Linux?
Технически ОС его примет, но делать этого не следует. Символы подчёркивания нарушают RFC 952 и RFC 1123. Они вызывают сбои при разрешении DNS (BIND по умолчанию их отклоняет), проверке TLS-сертификатов и именовании узлов Kubernetes. Используйте исключительно дефисы.
Как убедиться, что имя хоста полностью согласовано на всех уровнях системы?
Выполните следующую последовательность команд и убедитесь, что все выводы совпадают:
hostname
hostname --fqdn
hostnamectl --static
cat /etc/hostname
systemd-resolve --status | grep "Current hostname"Если какая-либо из этих команд возвращает отличающееся значение, один из уровней — cloud-init, DHCP-клиент или NetworkManager — по-прежнему переопределяет статическую настройку.
