RDP Monster

Как узнать IP-адрес в Linux: ip addr, hostname -I, curl

Как узнать IP-адрес в Linux: ip addr, hostname -I, curl

Как узнать IP-адрес в Linux с помощью ip addr

На вопрос «какой у меня IP-адрес» в любом современном дистрибутиве Linux отвечает команда ip из пакета iproute2. Она входит в поставку каждого крупного дистрибутива, работает без root и является тем, что остальные команды из этого руководства оборачивают или чем они были заменены. Базовая форма выводит все интерфейсы со всеми их адресами:

ip addr show
ip a            # same thing, shorter

На сервере с одной сетевой картой вывод выглядит так (строки со сроком жизни valid_lft опущены):

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
    inet 203.0.113.25/24 brd 203.0.113.255 scope global eth0
    inet6 2001:db8:1::25/64 scope global
    inet6 fe80::5054:ff:fe12:3456/64 scope link

Как это читать:

  • Имя интерфейса. lo обозначает петлевой интерфейс, всегда 127.0.0.1, доступный только с самой машины. Реальная карта здесь обозначена как eth0; при предсказуемых именах интерфейсов она называется ens3, enp0s3 или eno1, а беспроводные карты начинаются с wl.
  • inet обозначает адрес IPv4, а inet6 обозначает IPv6. Суффикс /24 задаёт длину префикса в нотации CIDR, современную запись маски подсети 255.255.255.0.
  • scope global означает маршрутизируемый за пределы этого хоста; scope link (строка fe80::) действителен только в подключённом сегменте сети; scope host означает loopback.
  • state UP вместе с LOWER_UP означает, что интерфейс включён и есть линк. state DOWN или NO-CARRIER обычно объясняют, почему у интерфейса вообще нет адреса.

Полезные варианты:

ip -4 addr                  # IPv4 only
ip -6 addr                  # IPv6 only
ip -br -4 addr              # one line per interface
ip -4 addr show dev eth0    # a single interface

Краткая форма (-br) даёт самый быстрый способ узнать IP-адрес в Linux, когда интерфейсов несколько, что обычно и бывает на VPS с Docker:

$ ip -br -4 addr
lo               UNKNOWN        127.0.0.1/8
eth0             UP             203.0.113.25/24
docker0          DOWN           172.17.0.1/16

hostname -I: только адреса

Когда нужны только адреса, hostname -I (заглавная I) выводит все настроенные адреса в одну строку через пробел, исключая loopback и link-local IPv6:

$ hostname -I
203.0.113.25 2001:db8:1::25

Две оговорки. Строчная hostname -i работает иначе: она резолвит имя машины через /etc/hosts и DNS, что в Debian и Ubuntu обычно даёт 127.0.1.1. И hostname -I выводит адреса без гарантированного порядка, включая виртуальные мосты вроде docker0, поэтому hostname -I | awk '{print $1}' служит удобным сокращением для человека, а не надёжным «основным IP» для скриптов. Опция не входит в POSIX: в Debian, Ubuntu, Fedora и RHEL она есть, а в минимальных образах на базе BusyBox, таких как Alpine, может отсутствовать.

ifconfig, nmcli и networkctl

ifconfig (устарел, net-tools)

ifconfig показывают старые руководства. Команда относится к net-tools, который уже много лет считается устаревшим в пользу iproute2 и больше не входит в стандартную установку актуальных выпусков Ubuntu, Debian и Fedora/RHEL. Если она возвращает command not found, перейдите на ip или установите пакет:

sudo apt install net-tools     # Debian / Ubuntu
sudo dnf install net-tools     # Fedora / RHEL / Rocky / Alma
$ ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 203.0.113.25  netmask 255.255.255.0  broadcast 203.0.113.255
        inet6 fe80::5054:ff:fe12:3456  prefixlen 64  scopeid 0x20<link>

Вывод читаемый, но с существенным ограничением: ifconfig показывает только один адрес IPv4 на интерфейс. Дополнительные адреса, добавленные через ip addr add, что часто встречается на VPS с несколькими публичными IP, для него невидимы.

nmcli и networkctl

Настольные системы и серверы семейства Fedora/RHEL управляют сетью через NetworkManager; Ubuntu Server использует netplan поверх systemd-networkd, и многие образы VPS следуют той же модели. У каждого варианта есть свой инструмент статуса, показывающий адрес, шлюз и DNS одним блоком:

nmcli device show eth0
nmcli -g IP4.ADDRESS device show eth0     # NetworkManager: just the address field
networkctl status eth0                    # systemd-networkd

Флаг -g (--get-values) выводит чистое значение одного поля, включая длину префикса, что удобно для скриптов. Если вы не уверены, какой стек используется на машине или даже какой это дистрибутив и выпуск, сначала определите версию ОС из командной строки; от ответа зависит, какой инструмент доступен.

Как узнать публичный IP-адрес через curl

Всё вышеописанное показывает адрес, настроенный на интерфейсе. На большинстве VPS публичный IPv4 назначается прямо на интерфейс, так что это же видит и интернет. Дома, в офисе или в некоторых облаках интерфейс несёт частный адрес из диапазонов RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16), а маршрутизатор или NAT 1:1 транслирует его на выходе. Надёжно увидеть публичную сторону можно, только спросив внешний сервис:

curl -4 icanhazip.com
curl -4 ifconfig.me/ip
curl -4 https://api.ipify.org
curl -6 icanhazip.com          # public IPv6, if the host has one

Флаги -4 и -6 принудительно задают семейство адресов, что важно на dual-stack хостах: без них curl может предпочесть IPv6 и вернуть неожиданный адрес. Сервис icanhazip.com с 2021 года обслуживается Cloudflare и возвращает простой текст. Читайте ответ как «адрес, с которого уходит мой трафик»: за VPN или прокси это адрес выходного узла, а не вашего провайдера.

IPv6: глобальный против link-local

Почти на каждом интерфейсе Linux есть хотя бы одна строка inet6, и её часто принимают за публичный адрес IPv6. Строка, начинающаяся с fe80:: и помеченная scope link, обозначает link-local: такой адрес автоматически генерирует каждый интерфейс, он действителен только в подключённой сети и никогда не доступен из интернета. Публичный адрес IPv6 помечен scope global и начинается с 2 или 3, поскольку пространство global unicast занимает 2000::/3.

ip -6 addr show scope global
ip -6 route show default

Если первая команда ничего не выводит, у машины нет маршрутизируемого IPv6 и curl -6 завершится ошибкой. Дополнительные глобальные адреса с пометкой temporary на десктопе появляются из-за privacy extensions; на серверах их отключают, чтобы адрес оставался стабильным для DNS и правил файрвола.

Шлюз по умолчанию, маршрут и DNS

Сам по себе адрес не говорит, может ли машина куда-то достучаться. Об этом говорит таблица маршрутизации, и ip route (короткая форма ip r) выводит её:

$ ip route
default via 203.0.113.1 dev eth0 proto static
203.0.113.0/24 dev eth0 proto kernel scope link src 203.0.113.25

Строка default via задаёт шлюз по умолчанию, маршрутизатор, который использует каждый пакет, когда не подходит более точный маршрут. Вторая строка была добавлена ядром при настройке адреса; её поле src содержит адрес, который хост предпочитает как источник в этой сети. Самый полезный приём строится на этом: спросите у ядра, какой адрес оно использовало бы для конкретного назначения.

$ ip route get 1.1.1.1
1.1.1.1 via 203.0.113.1 dev eth0 src 203.0.113.25 uid 1000
    cache

Это значение src по определению является исходящим адресом машины в сторону интернета, какими бы ни были интерфейсы, мосты или туннели. Что до DNS, /etc/resolv.conf по-прежнему то место, куда стоит смотреть, но в системах с systemd-resolved (Ubuntu начиная с 18.04, свежие Fedora) там только локальная заглушка 127.0.0.53; реальные вышестоящие резолверы показывает resolvectl status или поля IP4.DNS в nmcli device show на хостах с NetworkManager.

Скрипты: записать IP-адрес в переменную

Интерактивный вывод рассчитан на человека; скрипту нужен один адрес и ничего лишнего. Эти приёмы работают надёжно, от самого простого к самому устойчивому:

# One interface, IPv4, prefix length stripped
IP=$(ip -4 -o addr show dev eth0 | awk '{print $4}' | cut -d/ -f1)

# Robust: the source address used to reach the internet
IP=$(ip route get 1.1.1.1 | awk '{for (i=1; i<=NF; i++) if ($i == "src") {print $(i+1); exit}}')

# Same thing with JSON output and jq
IP=$(ip -j route get 1.1.1.1 | jq -r '.[0].prefsrc')

# Public IP, with a timeout so the script never hangs offline
PUBLIC_IP=$(curl -4 -s --max-time 5 https://icanhazip.com)

Флаг -o заставляет ip печатать по одному адресу на строку, что сохраняет позиции полей для awk; добавьте head -n 1, если на интерфейсе несколько адресов IPv4. Флаг -j переключает ip на вывод JSON, и jq затем выбирает поля по имени. Предпочитайте эту форму во всём, что запускается более чем на одной машине: имена интерфейсов различаются от хоста к хосту, а имена полей не различаются.

КомандаЧто показываетКогда использовать
ip addr / ip -br -4 addrВсе интерфейсы, все адреса, состояниеПовседневная работа, полная картина
hostname -IВсе адреса в одну строкуБыстрый взгляд
ip route get 1.1.1.1Адрес-источник для выхода в интернетСкрипты, хосты с несколькими интерфейсами
ifconfigОдин IPv4 на интерфейс (устарело)Старые системы, старые руководства
curl -4 icanhazip.comПубличный IPv4 так, как его видит интернетNAT, VPN, проверка адреса VPS

Что меняется на VPS

На VPS с выделенным IPv4 команды ip -4 addr, hostname -I и curl -4 icanhazip.com должны возвращать один и тот же адрес, потому что публичный IP настроен прямо на интерфейсе без NAT посередине. Если они расходятся, значит в пути что-то есть: NAT на стороне провайдера, забытый VPN-клиент или мост Docker, занявший первую позицию в hostname -I.

Когда адрес подтверждён, проверьте две вещи. Во-первых, вопрос о том, действительно ли он доступен и на каких портах, отличается от вопроса, настроен ли он: проверьте открытые порты на своём сервере Linux изнутри через ss -tulpn и снаружи через nmap. Во-вторых, обратный DNS. Запросите запись PTR для своего адреса:

dig -x 203.0.113.25 +short

Свежий VPS обычно отвечает обобщённым именем провайдера или вообще ничем. Если сервер отправляет почту или предоставляет любой публичный сервис, задайте имя хоста и обратный DNS так, чтобы они совпадали; исходящую почту, в частности, регулярно отклоняют, когда запись PTR и имя в HELO не совпадают.

Быстрее всего эти команды доходят до автоматизма на сервере, адрес которого принадлежит только вам и не меняется. Linux VPS от rdp.monster поставляется с выделенным IPv4, полным root-доступом, выделенными CPU и RAM, безлимитным трафиком (fair-use) и без KYC, с оплатой в криптовалюте, от $8.99 в месяц. Сервер выходит в онлайн примерно через 10 секунд после подтверждения платежа, так что до первой команды ip -br -4 addr на нём остаётся всего мгновение.

Часто задаваемые вопросы

Почему hostname -I показывает несколько IP-адресов?

Она перечисляет все настроенные адреса на всех интерфейсах, включая виртуальные мосты.
hostname -I выводит все адреса на всех интерфейсах, кроме loopback и link-local IPv6, поэтому машина с Docker, libvirt, VPN-клиентом или второй сетевой картой показывает сразу несколько. docker0 добавляет 172.17.0.1, virbr0 обычно 192.168.122.1, а dual-stack хост добавляет свой глобальный адрес IPv6. Порядок не гарантирован. Когда нужен адрес, с которого действительно уходит трафик, выполните ip route get 1.1.1.1 и прочитайте поле src.

Почему ifconfig выдаёт command not found в Ubuntu?

ifconfig относится к net-tools, который современные дистрибутивы больше не ставят по умолчанию.
Команда ifconfig входит в пакет net-tools, устаревший в пользу iproute2 и отсутствующий в стандартной установке актуальных выпусков Ubuntu, Debian и Fedora/RHEL. Заменой служит ip addr, которая доступна везде. Если скрипт или старая привычка действительно требуют её, установите пакет командой sudo apt install net-tools или sudo dnf install net-tools, помня, что ifconfig показывает лишь один IPv4 на интерфейс и скрывает дополнительные адреса, добавленные через ip addr add.

Почему hostname -i возвращает 127.0.1.1?

Строчная -i резолвит имя хоста через /etc/hosts, где системы на базе Debian сопоставляют его с 127.0.1.1.
hostname -i вообще не смотрит на сеть: она резолвит имя хоста так же, как это сделало бы любое приложение, через /etc/hosts, а затем DNS. Установщики Debian и Ubuntu добавляют строку, сопоставляющую имя хоста с 127.0.1.1, чтобы машина могла разрешить собственное имя без сети; именно эта строка и возвращается. Используйте форму с заглавной I, hostname -I, которая читает реальные адреса интерфейсов, или ip -4 addr для полной картины.

Как узнать IP-адреса других устройств в моей сети?

Прочитайте таблицу соседей через ip neigh или просканируйте подсеть с помощью nmap -sn.
Устройства, с которыми машина недавно обменивалась пакетами, находятся в кэше ARP/соседей, который показывает ip neigh show (или arp -a, если установлен net-tools). Для полной картины выполните ping-сканирование подсети: nmap -sn 192.168.1.0/24 перечислит все отвечающие хосты, с именами, если их даёт обратный DNS. Подставьте свою сеть, которую можно узнать из маршрута scope link в выводе ip route. На VPS это редко бывает полезно, а сканирование соседних адресов может нарушать условия вашего провайдера.

Adrien Roche, Редактор по инфраструктуре и хостингу

Системный инженер с более чем 10-летним опытом эксплуатации парков Windows Server и Linux. Адриен ведёт документацию по инфраструктуре rdp.monster и пишет наши руководства по RDP, VPS-хостингу, администрированию серверов, сетям и инструментам приватности.

Регистрация в программе для реселлеров

Ваши данные

Если у вас есть вопросы, напишите нам, нажав сюда !
Имя и фамилия(Обязательно)
Укажите ваш email: у вас должен быть аккаунт на dashboard.rdp.monster !

Ваша компания

Укажите адрес вашего сайта, если он у вас есть
Кратко опишите, как планируете продавать наши услуги клиентам. Например, через общение на форумах.

Мы используем файлы cookie!

Мы используем файлы cookie, чтобы сделать сайт удобнее, показывать персонализированную рекламу и контент и анализировать трафик. Нажимая «Принять», вы соглашаетесь на использование файлов cookie.