Сквозное подключение к Интернету в Linux

Android-телефоны HTC обладают полезной функцией, позволяющей подключать аппарат к сети Интернет посредством USB-соединения с компьютером. Данная функция прямо противоположна подключению компьютера через телефон, поэтому и называется соответственно — «Reverse USB-Tethering», а в терминах HTC — «Сквозное подключение к Интернету» (Internet Pass-Through).

На стороне компьютера данная возможность реализуется посредством программы HTC Sync, которая существует только для Windows. Поэтому пользователи Linux плачут горькими слезами. (Плачут не потому, что  не могут подключиться — WiFi-то никто не отменял, а потому, что их, как всегда, обошли вниманием).

Попробуем решить эту проблему. Что мы для этого имеем:

  • HTC Incredible S (root не обязателен)
  • Компьютер с Ubuntu 12.04
  • Кабель микро-USB

Подключаем телефон и в настройках подключения указываем режим «Сквозное подключение к Интернету»

$ dmesg | tail
[86229.199886] rndis_host 2-1.3:1.0: usb0:
  register 'rndis_host' at usb-0000:00:1d.0-1.3,
  RNDIS device, e6:04:a5:f5:19:50
[86239.962643] usb0: no IPv6 routers present

Здесь мы видим, что было подключено новое USB-устройство, ему сопоставлен драйвер rndis_host, и в итоге данное устройство зарегистрировано как usb0.

Есть все основания считать, что это — сетевая карта.

Смотрим:

$ ifconfig usb0
usb0 Link encap:Ethernet HWaddr e6:04:a5:f5:19:50 
 inet addr:192.168.99.204 Bcast:192.168.99.255 Mask:255.255.255.0
 inet6 addr: fe80::e404:a5ff:fef5:1950/64 Scope:Link
 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
 RX packets:19 errors:0 dropped:0 overruns:0 frame:0
 TX packets:50 errors:0 dropped:0 overruns:0 carrier:0
 collisions:0 txqueuelen:1000 
 RX bytes:1843 (1.8 KB) TX bytes:15274 (15.2 KB)

Да, так и есть. Еще и NetworkManager показывает, что появилось новое соединение. При этом оказывается, что у нового сетевого адаптера уже есть IP-адрес!

Понять, как такое могло произойти, нам поможет Wireshark:

По логу видно, что на стороне телефона, оказывается, живет DHCP-сервер. В результате сетевой адаптер usb0 на компьютере получает адрес, который ему выдает телефон.

Дальше — уже примерно понятно, что нужно делать. Будем настраивать NAT. В нашем случае это делается тремя командами (нужны права суперпользователя):

# Включаем форвардинг IP-пакетов в ядре
echo 1 > /proc/sys/net/ipv4/ip_forward

# Разрешаем форвардинг пакетов, приходящих с интерфейса usb0 на eth0
iptables -A FORWARD -i usb0 -o eth0 -j ACCEPT

# Включаем NAT для адресов, уходящих с интерфейса eth0 наружу
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

После этого все, казалось, бы должно работать, однако это не так — соединение с компьютером вроде бы есть, но «интернет не
работает». Да еще и минут через пять отключается . Опять вооружаемся wireshark’ом:

Тут мы видим, что для разрешения имени сайта в IP-адрес телефон рассчитывает найти DNS-сервер на сетевом адаптере usb0, адрес которого он, естественно, знает. Однако там его нет. DNS-сервер в контексте Linux — это, как правило, bind, великий и ужасный. Но, к счастью, есть способ проще — использовать форвардинг DNS-запросов. И в Ubuntu 12.04 этот способ уже штатно применяется NetworkManager’ом, который в качестве DNS-сервера использует dnsmasq, слушающий 127.0.0.1 в /etc/resolv.conf. А уже dnsmasq перенаправляет запросы на внешние DNS-серверы.

Проблема неработоспособности телефонного соединения как раз и заключается в том, что dnsmasq слушает только localhost. Но ничто не мешает запустить еще один экземпляр dnsmasq с теми же настройками, что и у основного экземпляра, но уже на нужном нам интерфейсе:

$ sudo /usr/sbin/dnsmasq --no-resolv --no-hosts \
 --bind-interfaces --pid-file=/var/run/htcusbtether.pid \
 --listen-address="192.168.99.204" --cache-size=0 \
  --proxy-dnssec --conf-file=/var/run/nm-dns-dnsmasq.conf

192.168.99.107 — это IP-адрес интерфейса usb0.

Автоматизация

Для автоматизации (как минимум) можно использовать два способа:

  • Менеджер устройств udev позволяет писать собственные правила и выполнять произвольные скрипты при изменении состава оборудования
  • NetworkManager также позволяет выполнять произвольные скрипты при изменении статуса сетевых устройств.

После экспериментов я выбрал второй путь, результатом которого стал пакет htcusbtether_0.1_any.deb, содержащий скрипт и его конфигурационный файл, в котором можно настроить имена адаптеров, если они отличаются от рассматриваемых в данной статье.

Примечания

Работоспособность тестировалась также на HDC Desire HD.

В рамках данной статьи не рассматривается случай, когда компьютер должен использовать прокси-сервер для доступа в Интернет. Это тема для отдельного исследования.

Ну и, традиционное:

Данное инструкция и ПО является неофициальным, нестабильным и непроверенным. Все действия по запуску Вы осуществляете на свой страх и риск. Автор не несет ответственности за возможный вред, причиненный во время экспериментов.

  • Andrey

    Добро. Спасибо за статью.
    У меня нет файла  /var/run/nm-dns-dnsmasq.confИ он не создаётся во время подключения что это за файл? Что в нём?

    • loquens

      Это конфигурационный файл dnsmasq, создаваться должен автоматически NetworkManager’ом. Какая версия Ubuntu используется?

      • Andrey

         oneric 11.10

        • loquens

          Надо будет на досуге посмотреть, как там работает NM

  • Andrey

    В общем dnsmasq уже запущен виртуализацией kvm (для поддержки VE).
    Нужно его перезапустить добавив IP полученный с от dhcp сервера android устройства. Соотвественно ничего не порушив. Вот что нагуглил, но пока не работает: http://neuronafugada.wordpress.com/2012/04/09/htc-reverse-tethering-on-linux-without-root/

    • loquens

      Странно, у меня dnsmasq был запущен NetworkManager’ом. И вполне достаточно оказалось запустить на другом интерфейсе (телефонном) еще один экземпляр.
      А что показывает команда ps ax | grep dnsmasq?

  • скрипт не завелся на elementary os beta2 luna (precise) с htc one xl (((

    может выложить его на launchpad чтобы все постестили, баги написали и поправили/отладили коллективно?

    понятно, что там полторы строки, но это востредовано и будет полезно всем )

    • loquens

      К сожалению, в свежей прошивке уже нет «Сквозного подключения к Интернет», так что, кажется, это уже не актуально. 🙁

  • shahverdy

    Can you please provide this post is English?