суббота, 20 октября 2012 г.

Подключение к Internet через Android в Ubuntu

Собственно, при подключении к Ubuntu Android телефона в режиме Internet модема соединение и так работает «из коробки». Если автоматическое соединение вас устраивает дальше можно не читать. Меня интересовал случай, когда требуется тонкая настройка соединения, например, указание дополнительных маршрутов или согласованная работа нескольких проводных соединений.

Network Manager позволяет настроить ручное соединение и привязать его к сетевому интерфейсу телефона. Сделать это не сложно, однако, проблема в том, что привязка осуществляется только по MAC адресу, а мой телефон меняет этот адрес при каждой перезагрузке. Способ обхода этой особенности оказался несколько неочевидным, поэтому публикую его здесь, может кому-то пригодится.

Первым делом, необходимо в Network Manager создать и настроить системное сетевое соединение для телефона (для определенности, далее предполагается, что имя соединения ANDORID). После чего необходимо найти файл с настройками созданного соединения (его придется менять скриптом при подключении телефона). В Network Manager 0.8 и выше, файл находится по адресу:

/etc/NetworkManager/system-connections/ANDROID

Далее надо выяснить какой-нибудь идентификатор телефона, он используется в скриптах, чтобы отличать подключение телефона от подключение других устройств. В принципе, подойдет любой идентификатор доступный udev. Я использовал серийный номер. Его проще всего выяснить, запустив следующую команду, и подключив телефон к компьютеру:

udevadm monitor --env | grep ID_SERIAL_SHORT

Теперь можно заняться подготовкой скриптов. Сначала создается скрипт, который будет обновлять MAC адрес в описании соединения, если тот изменился с последнего подключения:

cat >/tmp/69-update-phone-mac.sh <<EOF
#!/bin/sh

PATH=/usr/bin:/bin
export PATH

NM_CONN_BASE=/etc/NetworkManager/system-connections/
NM_CONN_NAME=ANDROID
NM_CONN_FILE=\$NM_CONN_BASE/\$NM_CONN_NAME
NM_OUTP_FILE="\$NM_CONN_FILE"

if [ -n "\$1" ]; then
  DEV_NAME="\`basename \$1\`"
  MAC_ADDRESS="\`cat /sys/\$1/address\`"
  OLD_MACADDR="\`cat \$NM_CONN_FILE | grep mac-address | cut -d= -f2 | tr 'ABCDEF' 'abcdef'\`"

  if [ -n "\$MAC_ADDRESS" -a "\$MAC_ADDRESS" != "\$OLD_MACADDR" ]; then
    nmcli dev disconnect iface \$DEV_NAME >/dev/null
    BUF=\`cat \$NM_CONN_FILE | sed "s/^\\\\(mac-address\\\\)=.*\\$/\\\\1=\$MAC_ADDRESS/"\`
    echo "\$BUF" > "\$NM_OUTP_FILE"
    sleep 1 # Give NM some time to update configuration and avoid race conditions
    nmcli con up id \$NM_CONN_NAME >/dev/null
  fi
fi
EOF
sudo install -m 755 -o root -g root -p -t /etc/udev/rules.d/ /tmp/69-update-phone-mac.sh

Наконец можно создавать правило udev, которое будет вызывать скрипт при подключении устройства (в правило надо подставить серийный номер телефона, см. выше):

sudo sh -c \
'echo SUBSYSTEM==\"net\" ATTRS{serial}==\"***\" RUN+=\"/etc/udev/rules.d/69-update-phone-mac.sh %p\" \
> /etc/udev/rules.d/69-update-phone-mac.rules'

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

UPD: Малость с запозданием обнаружил в списке рассылки еще один вариант решения проблемы. Вместо исправления настроек Network Manager, предлагается зафиксировать MAC адрес сетевого устройства с помощью правила udev

ACTION=="add",KERNEL=="usb0", RUN+="ip link set usb0 address xx:xx:xx:xx:xx:xx"

Сам не пробовал, пока и так работает, в теории настроек меньше и должно работать надежнее.

2 комментария:

  1. Малость много всего,но постараюсь воплотить в жизнь.Спасибо

    ОтветитьУдалить
  2. Насколько я не разбираюсь во всем этом, и раньше мы звали мастера на дом, но вы настолько все четко расписали) можно сделать все самому.

    ОтветитьУдалить