И снова вспомню времена древние, староглиняные: когда-то настройка сети в 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)
winorun
04.01.2025 19:21если есть python 2 есть wicd. Особенно актуально на старых системах.
есть еще iwd. Довольно удобный консольный интерфейс.
ну а если ноутбук стационарный, а в качестве ос debian или аналоги wifi можно настроить в /etc/network/interface
JBFW Автор
04.01.2025 19:21Да, знаю wicd.
Вот после того как он отказался работать - и пришлось такое накалякать. Отказался, потому что там какие-то проблемы между python 2 и python 3....
okhsunrog
04.01.2025 19:21А можете пояснить в каком же "нештатном" режиме начинает работать NetworkManager без графического интерфейса? Всё с ним прекрасно, и настраивать через nmcli сеть намного проще и быстрее, чем городить вот это всё вышеописанное. Я понимаю, когда нужно использовать iwd, ip, wpa_supplicant, пользуюсь при необходимости, но если уж у меня запущен NetworkManager - я его не буду специально выключать, чтобы настроить через более низкоуровневые интерфейсы сеть.
JBFW Автор
04.01.2025 19:21Не выключайте, конечно. Работает - не трогай! (с)
А в нештатном это в таком, когда вместо того чтобы "посмотри что есть - подключись сюда" нужно колдовать с командами.
Эта штука очень хороша именно тогда, когда тыкаешь мышью в специальную иконку. Он забирает на себя всю низкоуровневую работу и делает это сам.
Но если уж сам туда залез - зачем нужен посредник, систему команд которого нужно дополнительно изучать, вместо того чтобы сделать самому?
Что быстрее, написать четыре заклинания iwconfig, scan, wpa_supplicant, dhclient или изучить особенности управления NM через mncli? Зачем, чтобы что?
Или писать самому оболочку интерфейса работы через nmcli? Так уже есть хорошая, просто тут она не работает
errcon
В те времена 8.8.8.8 не существовало ;-)
JBFW Автор
ну это уже детали реализации )