И снова вспомню времена древние, староглиняные: когда-то настройка сети в UNIX-like OS была делом, требующим сложных технических знаний. Нужно было зайти в консоль под правами рутовыми, да указать вручную адрес IP для интерфейса сетевого. Примерно так:

ifconfig eth0 add inet 192.168.1.10 netmask 255.255.255.0 up

Или, ежели админ сети сподобился, да настроил сервер DHCP - то так:

ifconfig eth0 up

dhclient eth0

Да еще не забыть указать адрес сервера DNS:

echo "nameserver 8.8.8.8" > /etc/resolv.conf

А ежели надобность была чтобы оно при перезагрузке сохранялось - то записать эти заклинания в файл типа /etc/rc.local на память долгую.

Теперь-то другое дело: воткнул шнурок в разъем - сеть и появилась, как по щучьему велению.
И даже WiFi - нажал мышкой на иконку, выбрал название сети, ввел пароль - она и подключилась.
Красота, лепота какая! Но есть нюанс...

За всю эту красоту отвечает теперь NetworkManager (я про Ubuntu и подобные). Он стартует при запуске компьютера, отслеживает подключения, управляет ими. Да и с /etc/resolv.conf все не так просто, теперь этим управляет другой демон, перехватывая обращения к DNS.

Всёэто хорошо пока вы не выходите за рамки предустановленного и настроенного десктопа, в смысле, программной среды.
Но стоит что‑то поменять — и оказывается, что теперь некуда тыкать мышкой, потому что иконки нет. А нет ее потому что апплет, который за нее отвечает, не рассчитан на другую среду, или «не удается подключиться к DBus», или оно как бы работает — но почему‑то не так как ожидается.

И как бы есть даже интерфейс командной строки nmcli, который взаимодействует с NetworkManager, но с ним тоже всё не так просто, потому что вся эта довольно сложная система теперь работает в нештатном режиме.

Однако, всё это по‑прежнему можно легко настроить вручную, и даже автоматизировать, без использования сложных программных пакетов.
(отдельно отмечу, что не стоит пытаться объять необъятное и писать свой собственный NetworkManager)

Итак, подключаемся вручную.
Первым делом отключим NetworkManager чтобы он не мешал:

systemctl stop NetworkManager

systemctl disable NetworkManager

Что касается обычных сетевых интерфейсов - тут мало что изменилось, разве что вместо ifconfig теперь модно использовать ip:

ip link set eth0 up

ip addr add 192.168.1.10 dev eth0

А для работы с WiFi используются другие инструменты (iwconfig или iw):

iwconfig

lo no wireless extensions.

wlp2s0 IEEE 802.11 ESSID:off/any

Mode:Managed Access Point: Not-Associated Tx-Power=22 dBm

Retry short limit:7 RTS thr:off Fragment thr:off

Power Management:on

В данном случае найдены два интерфейса, локальный без поддержки WiFi и wlp2s0
Убедимся, что он поднят и попробуем поискать сети:

ip link set wlp2s0 up

iwlist wlp2s0 scan | grep ESSID

Получаем список доступных сетей. Скорее всего ваша сеть использует для защиты WPA/WPA2, другие в наше время экзотика, поэтому понадобится wpa_supplicant.
Для того чтобы работать с сетью нужно прописать для него конфигурационный файл, примерно с таким содержанием:

network={
  ssid="[network ssid]"
  psk="[the passphrase]"
  priority=1
}

Вообще говоря, в одном файле можно держать настройки для разных сетей, но если не хочется потом сюрпризов с неожиданными переключениями - лучше ограничиться одной, и просто менять ее или используемые конфиги при необходимости.
Запускаем сам wpa_supplicant и dhclient:

wpa_supplicant -B -i wlp2s0 -c /etc/wpa_supplicant/wpa_supplicant_XXXX.conf

dhclient wlp2s0

В типовом случае этого будет достаточно. Есл всё было правильно - компьютер подключится к сети и получит адрес.

Но это совсем вручную, то есть через консоль, с правкой файлов. Для стационарного компьютера пойдет, для ноутбука не очень, поэтому можно набросать скрипт настройки.

Для создания графического интерфейса за основу взята довольно старинная парочка tcl/tk, в отличии от более современных вариантов не требовательная к ресурсам, к тому же прекрасно интегрирующаяся в обычные shell-скрипты. Если вдруг этих пакетов не установлено - всегда можно их добавить, там всего-то пара мегабайт:

apt install tcl tk

Чтобы не писать свой NetworkManager - ограничимся простым скриптом, который делает вон то же самое что написано выше, только информацию от пользователя получает через окошки.

#!/bin/bash

# окно ввода пароля
ask_pass() {

getpwd="
package require Tk

# настройки окна
wm title . \"$1\"
wm geometry . +300+50
wm protocol . WM_DELETE_WINDOW { exit }

# сообщение и строка ввода со звездочками
label .label -text \"$1:\" -padx 10 -pady 10
pack .label -side top
entry .entry -width 30 -show * -textvariable userInput
pack .entry -side top -padx 10 -pady 5
set userInput \"\"

# функция при нажатии на кнопку
proc onOk {} {
    global userInput
    puts stdout \$userInput
    exit
}

# создание кнопки и размещение ее в окне
button .okButton -text \"OK\" -command onOk -padx 10 -pady 5
pack .okButton -side top -padx 10 -pady 10

# ожидание ввода
vwait userInput
"
  echo "$getpwd" | wish
}

# окно сообщения
message() {

str="
package require Tk

# настройки окна
wm title . \"$1\"
wm geometry . +300+50
wm minsize . 300x150
wm protocol . WM_DELETE_WINDOW { exit }

# сообщение 
label .label -text \"$1\" -padx 10 -pady 30
pack .label -side top

# функция при нажатии на кнопку
proc onOk {} {
    exit
}

# создание кнопки и размещение ее в окне
button .okButton -text \"OK\" -command onOk -padx 10 -pady 5
pack .okButton -side top -padx 10 -pady 5

"
  echo "$str" | wish
}

# проверяем, скрипт запускается от имени суперпользователя или нет
if [[ $EUID -ne 0 ]]; then

  # проверяем, делалось ли sudo
  sudo -n true > /dev/null 2>&1
  if [ $? -ne 0 ] ; then
    passwd=`ask_pass "User password"`

    if [ ! -n "$passwd" ] ; then
      message "No password!"
      exit 1
    fi

    echo $passwd | sudo -S true > /dev/null 2>&1
    if [ $? -ne 0 ] ; then
      message "Incorrect password!"
      exit 2
    fi
  fi
fi

# получаем список интерфейсов с поддержкой WiFi
interfaces=$(iwconfig 2>/dev/null | awk '/IEEE/ {print $1 "=" $4}')
if [[ -z "$interfaces" ]]; then
  echo "No WiFi found" >&2
  exit 3
fi

# создаем временный файл для списка интерфейсов и AP
temp_file=$(mktemp)
trap "rm -f $temp_file" EXIT

for iface in $interfaces; do
  echo "$iface" >> "$temp_file"
done

iface=''

# вывод окна списка интерфейсов
select_iface() {

getiface="
package require Tk
wm title . \"Select interface\"
wm geometry . +300+50
wm protocol . WM_DELETE_WINDOW { exit }

label .l1 -text \"Select interface\"
pack .l1 -padx 10 -pady 5

listbox .list1 -width 50 -height 3
pack .list1 -padx 10 -pady 5

# загружаем данные из временного файла
set fd [open \"$temp_file\" r]
set lines [split [read \$fd] \"\\n\"]
close \$fd

foreach line \$lines {
  if {[regexp {(\\w+)=ESSID:([\"\\w]+)} \$line match iface essid]} {
    .list1 insert end \"\$iface (\$essid)\"
  }
}

# кнопка выбора интерфейса
button .ok -text \"Select interface\" -command {
  set selection [.list1 get [.list1 curselection]]
  if {[regexp {(\\w+) } \$selection match iface]} {
    set selected_iface \$iface
    puts stdout \"\$selected_iface\"
    exit
  }
}
pack .ok -padx 10 -pady 5

set selected_iface \"\"

vwait selected_iface

"

  echo "$getiface" | wish

}

# выбираем интерфейс
iface=`select_iface`

# вывод окна списка сетей
select_network() {

getnet="
package require Tk
wm title . \"Select network\"
wm geometry . +300+50
wm protocol . WM_DELETE_WINDOW { exit }

label .l1 -text \"Select network\"
pack .l1 -padx 10 -pady 5

listbox .list -width 50 -height 20
pack .list -padx 10 -pady 5

# Загружаем данные из временного файла
set fd [open \"$temp_file\" r]
set lines [split [read \$fd] \"\\n\"]
close \$fd

foreach line \$lines {
  if {[regexp {(\\w+)} \$line match essid]} {
    .list insert end \"\$essid\"
  }
}

button .ok -text \"Select\" -command {
  set selection [.list get [.list curselection]]
  set selected_net \$selection
  puts stdout \"\$selected_net\"
  exit
}

pack .ok -padx 10 -pady 5

set selected_net \"\"

vwait selected_net

"

  echo "$getnet" | wish

}

# функция для сканирования сетей
scan_networks() {
  sudo ip link set $1 up
  echo -n "" > "$temp_file"
  echo "Scan..."
  sudo iwlist $1 scan | grep -E 'ESSID|Signal level' | awk -F: '{print $2}' | sort | uniq >> "$temp_file"
}

# если интерфейс выбран - сканируем сети и выбираем из найденных
if [ -n "$iface" ] ; then

  scan_networks $iface

  net=`select_network`

  if [ -n "$net" ] ; then
    key=`ask_pass "WiFi password"`
    if [ -n "$key" ] ; then

      # Создаем конфигурацию для wpa_supplicant
      conf="
update_config=1

network={
    ssid=\"$net\"
    psk=\"$key\"
}
"
      sudo mkdir -p /etc/wpa_supplicant
      file=/etc/wpa_supplicant/wpa_supplicant_$iface.conf

      # шаманство с созданием файла
      sudo touch $file
      sudo chmod 666 $file
      sudo echo "$conf" > $file
      sudo chmod 644 $file

      # перезапускаем wpa_supplicant
      pid=`ps ax| grep "wpa_supplicant" | grep -v grep | grep "$iface" | awk '{print $1}'`
      if [ "x$pid" != "x" ]; then
        sudo kill $pid
      fi

      pid=`ps ax| grep "dhclient $iface" | grep -v grep | awk '{print $1}'`
      if [ "x$pid" != "x" ]; then
        sudo kill $pid
      fi

      sudo wpa_supplicant -B -i "$iface" -c /etc/wpa_supplicant/wpa_supplicant_$iface.conf


      # запрашиваем IP-адрес через DHCP
      sudo dhclient "$iface"

      msg=`ip addr show dev $iface | grep inet | awk '{print $1 " " $2 }'`
      message "$msg"

    else
      message "No WiFi password!"
    fi
  else
    message "No network selected!"
  fi
else
  message "No interface selected!"
fi

exit
#=====================================================

Скрипт проверяет, под кем он запущен, если под обычным пользователем — запрашивает пароль для sudo, затем получает список интерфейсов с WiFi (их может быть несколько), после выбора сканирует доступные сети, предлагает выбрать, потом формирует конфиг для данного интерфейса и запускает wpa_supplicant. Если все прошло хорошо — показывает IP‑адреса на этом интерфейсе.

Для того чтобы не запускать всё это каждый раз после перезагрузки — есть другой скрипт, который должен запускаться от рута при старте системы:

#!/bin/sh

for i in /etc/wpa_supplicant/wpa_supplicant_*.conf; do
  iface=`echo $i | sed -nE "s/^.*wpa_supplicant_(.+)\.conf/\1/p"`
  if [ -n "$iface" ] ; then
    ip link set $iface up
    wpa_supplicant -B -i "$iface" -c /etc/wpa_supplicant/wpa_supplicant_$iface.conf
    dhclient "$iface"
  fi
done

Проверяет наличие сохраненных конфигов и запускает wpa_supplicant с ними.

Комментарии (6)


  1. errcon
    04.01.2025 19:21

    В те времена 8.8.8.8 не существовало ;-)


    1. JBFW Автор
      04.01.2025 19:21

      ну это уже детали реализации )


  1. winorun
    04.01.2025 19:21

    если есть python 2 есть wicd. Особенно актуально на старых системах.

    есть еще iwd. Довольно удобный консольный интерфейс.

    ну а если ноутбук стационарный, а в качестве ос debian или аналоги wifi можно настроить в /etc/network/interface


    1. JBFW Автор
      04.01.2025 19:21

      Да, знаю wicd.

      Вот после того как он отказался работать - и пришлось такое накалякать. Отказался, потому что там какие-то проблемы между python 2 и python 3....


  1. okhsunrog
    04.01.2025 19:21

    А можете пояснить в каком же "нештатном" режиме начинает работать NetworkManager без графического интерфейса? Всё с ним прекрасно, и настраивать через nmcli сеть намного проще и быстрее, чем городить вот это всё вышеописанное. Я понимаю, когда нужно использовать iwd, ip, wpa_supplicant, пользуюсь при необходимости, но если уж у меня запущен NetworkManager - я его не буду специально выключать, чтобы настроить через более низкоуровневые интерфейсы сеть.


    1. JBFW Автор
      04.01.2025 19:21

      Не выключайте, конечно. Работает - не трогай! (с)

      А в нештатном это в таком, когда вместо того чтобы "посмотри что есть - подключись сюда" нужно колдовать с командами.

      Эта штука очень хороша именно тогда, когда тыкаешь мышью в специальную иконку. Он забирает на себя всю низкоуровневую работу и делает это сам.

      Но если уж сам туда залез - зачем нужен посредник, систему команд которого нужно дополнительно изучать, вместо того чтобы сделать самому?

      Что быстрее, написать четыре заклинания iwconfig, scan, wpa_supplicant, dhclient или изучить особенности управления NM через mncli? Зачем, чтобы что?

      Или писать самому оболочку интерфейса работы через nmcli? Так уже есть хорошая, просто тут она не работает