2012-11-29

как можно ограничить число устройств у абонента?

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

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

2. следующий шаг - использование аутентификации.
например - 802.1x или PPPoE/PPTP доступ в сеть.
решение - выполнять аутентификацию на роутере и с него же поднимать туннель.
не проблема для абонента.

3. тяжелая артиллерия - фильтрация по TTL :)
вешать на клиента список доступа, принимающие пакеты ровно с TTL=128(венда) или TTL=64(unix/linux/macos).
здесь все становится немного сложнее.
не все роутеры умеют такое бороть, но если роутер использует прошивку на линуксе (dd-wrt/openwrt/и т.д.), то там все решается предельно просто:
iptables -t mangle -A POSTROUTING -o -j TTL --ttl-set 128
большинство прошивок могут такую команду добавить а автозапуск.

4. сверх-тяжелая артелерия и приз зрительских симпатий - УСТАНОВКА TTL!
роутер провайдера на все пакеты идующие в сторону клиента ставит TTL=1.
если абонент подключил маршрутизатор, то он при пересылке пакета внутрь на проводную ил беспроводную либо даже виртуальную сеть уменшает TTL на единицу, и тут - упс, TTL=0, пакет нужно отбросить и отправить TTL exceeded!
на линуксе (dd-wrt/openwrt/и т.д.) все решается предельно просто, как и в прошлом варианте, только теперь на трафик полученный на wan интерфейсе:
iptables -t mangle -A PREROUTING -i -j TTL --ttl-set 128
большинство прошивок могут такую команду добавить а автозапуск.

если вы можете список дополнить - буду благодарен :)

2012-11-06

управление тачпадом из коммандной строки

У меня забавная проблема с отключением тачпада в убунте.
Конечно же оно не работает :)
Но на самом деле проблема не в том что кнопка отключения не работает. Она-то как раз в норме. Вот проверка xev'ом:
KeyPress event, serial 40, synthetic NO, window 0x4600001,
    root 0xd8, subw 0x0, time 26256081, (598,673), root:(601,696),
    state 0x0, keycode 199 (keysym 0x1008ffa9, XF86TouchpadToggle), same_screen YES,
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False

KeyRelease event, serial 40, synthetic NO, window 0x4600001,
    root 0xd8, subw 0x0, time 26256156, (598,673), root:(601,696),
    state 0x0, keycode 199 (keysym 0x1008ffa9, XF86TouchpadToggle), same_screen YES,
    XLookupString gives 0 bytes:
    XFilterEvent returns: False
Проблема в том что у меня оказывается нет тачпада:
#  xinput
⎡ Virtual core pointer                          id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ PS/2 Generic Mouse                        id=12   [slave  pointer  (2)]
⎣ Virtual core keyboard                         id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Video Bus                                 id=7    [slave  keyboard (3)]
    ↳ Power Button                              id=8    [slave  keyboard (3)]
    ↳ Sleep Button                              id=9    [slave  keyboard (3)]
    ↳ Laptop_Integrated_Webcam_HD               id=10   [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=11   [slave  keyboard (3)]
    ↳ Dell WMI hotkeys                          id=13   [slave  keyboard (3)]
Вот та хрень PS/2 Generic Mouse и есть мой тачпад :(
Модель ALPS воткнутая долбаным делом не существует, и дров на нее не бывает, как и прокрутки и малтитача.

Но вопрос по отключению, и здесь все просто: xinput enable 12 и xinput disable 12 (12 это айди из вывода xinput).

Но это не интересно, нужно написать скрипт touchpad-toggle!
#!/bin/bash
TOUCHPAD=12
if [[ $(xinput list ${TOUCHPAD} | grep "This device is") =~ disabled ]]; then
        echo "Enabling touchpad"
        xinput enable ${TOUCHPAD}
else
        echo "Disabling touchpad"
        xinput disable ${TOUCHPAD}
fi
Теперь можно было бы попробовать повесить этот скрипт на кнопку XF86TouchpadToggle но, к сожалению, КДЕ не позволяет именно на эту кнопку вешать скрипты :(

А вас раздражает когда ноут просыпается от открытия крышки?

Лично меня - да.
Я обычно предпочитаю его открыть поставить в дальний угол стола, подключить все мониторы, сетевой кабель, usb-хаб, и только потом нажать кнопку power.
Но - не судьба. Под убунтой он просыпается от открытия крышки :(

Не беда! Это можно полечить.
Разгадка этой проблемы в /proc/acpi/wakeup:
# cat /proc/acpi/wakeup
Device  S-state   Status   Sysfs node
P0P1      S4    *disabled 
EHC1      S4    *enabled   pci:0000:00:1d.0
EHC2      S4    *enabled   pci:0000:00:1a.0
XHC       S4    *enabled   pci:0000:00:14.0
RP01      S4    *disabled  pci:0000:00:1c.0
PXSX      S4    *disabled  pci:0000:01:00.0
RP05      S4    *disabled  pci:0000:00:1c.4
PXSX      S4    *disabled  pci:0000:02:00.0
RP06      S4    *disabled 
PXSX      S4    *disabled 
PEG0      S4    *disabled 
LID0      S3    *enabled  
Это список устройств которые могут будить систему из разных уровней сна(S3=suspend to ram, S4=hibernate to disk), и то разрешено им это делать или нет(enabled/disabled).
Что за pci устройства можно проверить относительно просто:
# lspci -s  0000:00:1d.0
00:1d.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB Enhanced Host Controller #1 (rev 04)
Но меня интересует последняя строка - LID0.
Отключить - просто:
echo -n LID0 > /proc/acpi/wakeup
cat  /proc/acpi/wakeup
Device  S-state   Status   Sysfs node
P0P1      S4    *disabled 
EHC1      S4    *enabled   pci:0000:00:1d.0
EHC2      S4    *enabled   pci:0000:00:1a.0
XHC       S4    *enabled   pci:0000:00:14.0
RP01      S4    *disabled  pci:0000:00:1c.0
PXSX      S4    *disabled  pci:0000:01:00.0
RP05      S4    *disabled  pci:0000:00:1c.4
PXSX      S4    *disabled  pci:0000:02:00.0
RP06      S4    *disabled 
PXSX      S4    *disabled 
PEG0      S4    *disabled 
LID0      S3    *disabled 
 Осталось сделать это умолчанием. Можно это положить где-то в /etc/pm/sleep.d, что б оно применялось при выходе из сна(на случай если потеряется например при хибернейте), или в /etc/rc.local.

P.S. Сначала написал пост, потом нагуглил точно такой же :)
P.P.S. Осталась только одна маааленькая проблемака. Это не работает :(

И вновь про криворуких программистов

Есть еще одна милая проблема которая не дает мне спокойно жить.
Она состоит в том что мониторов у меня не два, а ТРИ.
Но. На самом деле, видеокарта одновременно может аппаратно обрабатывать ровно столько мониторов, сколько в ней есть CRTC, которых в большинстве случаев два.
Потому я использую два внешних(подключенных к VGA и HDMI), а третий - дисплей ноута отключаю.
Но. Люди Творящие Добро сделали так, что X-сервер автомагически при запуске пытается включить ВСЕ мониторы. И это заканчивается либо Тремя Черными Экранами Не Реагирующими Ни На Что, либо (если повезет), консолью с сообщением
[drm:drm_crtc_helper_set_config] *ERROR* failed to set mode on [CRTC:7]
Решение - отключить механически один из мониторов, затем с телефона зайти по ssh на ноут, и сделать /etc/init.d/?dm restart
Круто, правда? Чистый юзабилити, мать его так...

Вчера не мог себя заставить занятся делом, и потратил на траблшутинг этой херни два часа.
Идея простая: написать кусок конфига X-сервера, в котором запретить включать любые мониторы кроме встроеного (для начала хотя бы так, дальше буду думать как удобнее).

Проблема первая: Ведь теперь нет xorg.conf! где X-сервер хранит свой конфиг???
Все очень просто -
mkdir -p /etc/X11/xorg.conf.d
^mkdir^cd^
vim 10-monitor.conf
Section "Monitor"
        Identifier "LVDS1"
        Option "Primary" "true"
        Option "Enable" "true"
EndSection

Section "Monitor"
        Identifier "HDMI1"
        Option "Enable" "false"
EndSection

Section "Monitor"
        Identifier "VGA1"
        Option "Enable" "false"
EndSection
Думаете заработало? Хрен!

1) для привязки мониторам к видеовыходам нужно добавить настройку видеокарты:
Section "Device"
        Identifier "vcard"
        Driver     "intel"
        Option "Monitor-LVDS1" "LVDS1"
        Option "Monitor-VGA1" "VGA1"
        Option "Monitor-HDMI1" "HDMI1"
        Option "Monitor-DP1" "DP1"
EndSection
2) Опция Enable, несмотря на то что описана в документации, оказывается не работает! И нет, NOTABUG!!!
Ок, добавляем кроме Enable false еще и Disable true.
работает? Конечно же НЕТ!

Не смотря на то что теперь конфиг правильный (проверяем по логам иксов):
 (II) intel(0): Output LVDS1 enabled by config file
 (II) intel(0): Output VGA1 disabled by config file
 (II) intel(0): Output HDMI1 disabled by config file
Проблема на месте, и дальше в логе мы видим:
 (WW) intel(0): Option "Primary" is not used
 (WW) intel(0): Option "Enable" is not used
Т.е. интеловский драйвер просто ложит болт на опцию Enable?

3) Есть еще мега-опция "Ignore" "true"
Но если ее повесить на выход, он становится полностью недоступным, т.е. даже исчезает из xrandr.
Но это плюс, ведь xrandr мне еще светит неведомого зверя под именем DP1, повод исправить! Добавляю в 10-monitor.conf
Section "Monitor"
        Identifier "DP1"
        Option "Ignore" "true"
EndSection
Итог: проблема осталась на месте. Я ненавижу разработчиков Xorg. Я ненавижу разработчиков Intel. При включении ноута надо не забыть отключить внешние мониторы :(

Еще один камень в сторону криворуких программеров

Еще одна веселая проблема.
Проявляется во многих "кросс-платфоменных" ява-приложениях, но больнее всего меня поразила в такой штуке как NX.
Мне приходится постоянно с ним работать в удаленных лабах.
Вот так он должен выглядеть:
В конфигурации терминальной сессии для удобства вшито разрешение 1024х768, это удобно, его хватает (разрешение можно поменять на сервере лаб, и оно опять таки вшивается в настройки сессии NX).
Все бы супер, но, все работает нормально только если у меня подключен один монитор. Как только мониторов два, картинка становится такой:
Как вам такое?
Вы можете подумать что у меня два огромных 40" монитора, но фиг там! Это окошко по ширине "почти" помещается на два монитора!
И долбаный NX плюет с колокольни на то что в сессию вшито разрешение экрана(при одном мониторе эти опции работают идеально):

И внутри терминальной сессии сменить разрешение невозможно.

Решение нашел здесь
Написать библиотеку подменяющую функции Xinerama возвращающие размер дисплея и перезагрузить ее с помощью LD_PRELOAD!!!
ОФИГЕТЬ

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

Теперь воркараунд.
1) скрипт nestify, запускающий одну программу под Xephyr:
#!/bin/bash
RESOLUTION="1024x768"
while [[ $1 =~ - ]]; do
        case $1 in
                -r)
                        RESOLUTION=$2
                        shift 2
                        ;;
        esac
done
for i in `seq 30`; do
        [[ -a /tmp/.X$i-lock ]] && continue
        Xephyr -ac -screen ${RESOLUTION} -br :$i > /tmp/xephyr.$PID.out 2>&1 &
        export DISPLAY=:$i
        sleep 1
        exec $*
        exit
done
Большая часть скрипта - грязный хак перебирающий свободные десктопы что б можно было запустить одновременно несколько таких сессий.
2) скрипт-оболочка для nxclient:
#!/bin/bash
nestify -r "1024x768" /usr/NX/bin/nxclient $*

Теперь вместо порнографии со второго скриншота у меня получается такая картинка:
Есть конечно недостатки: пока не придумал как изменить заголовок окна на более информативный, но намеки нашел здесь, но патчить и пересобирать ради этого не готов :(

P.S. За моральную и техническую помощь спасибо Илье :)