вторник, 13 декабря 2011 г.

Установка DD-WRT на Linksys E3000 (прошивка 17990 mega)

Собственно, по началу ничего не предвещает проблем, но -как оказалось - это поначалу...
На входе имеем Linksys E3000 с уже установленной прошивкой (прошивка была старая 14???, но можно было ставить и на родную Linksys-овскую).



К роутеру подключен WD Elements 2.5''. Разбит на 4 партиции: jffs (2Gb) (ext-3), swap (256Mb) (linux-solaris swap), mnt (293Gb) (ext-3), opt (2Gb) (ext-3). Тип разбивки не готов сказать - либо dos, либо - что скорее всего - linux-овый.
Прошивка взяда с ftp-ddwrt ресурса и устанавливалась в два этапа: сначала 17990_NEWD-2_K2.6_mini-e3000.bin, после чего делался rest (30/30/30) и далее - устанавливался dd-wrt.v24-17990_NEWD-2_K2.6_mega-nv60k.bin (тоже с reset после него).


Проблема номер раз: смонтировать JFFS
. Старая версия dd-wrt у меня монтировала первую партицию и всё было пучком. Новая - сначала монтирует первую как ext-3, а затем - по необъяснимым пока причинам - третью в ту же точку монтирования, но уже как ext-2 при том, что размечено всё под ext-3. Причём вторичное монтирование происходит уже после выполнения скриптов Startup и FireWall.
В комментах к прошивке DD-WRT 17967 было сказано, что имена партиций теперь поддерживаются в uppercase формате. Естественно - попробовал переименовать jffs в JFFS, плюс переформатировать её в ext2. Всё равно в некий момент времени происходило монтирование третьей партиции поверх первой. Я сделал ещё 2 предположения - что у меня не DOS разбивка, а Linux и что моя текущая разбивка отличается от новых "веяний", описанных на сайте dd-wrt, где JFFS стоит 3-ей.

Поскольку при подключении через роутер или VMWare Fusion скорость переноса данных ну ооочень маленькая, а ставить на iMac линукс или искать Ext-3 драйвера под Fuse мне не хотелось, то я принял решение забить на automount и сделать всё в manual режиме. Итак: первый шаг: отключаем automount на диск.
Далее - необходимо смонтировать данный диск. Для этого используем секцию Administration/Commands/Startup. Поскольку диск у нас не смонтирован, то взять файл скрипта неоткуда, а в данной секции можно лишь разместить набор шеловских команд. Поступаем следующим образом: командой echo создаём скрипт /tmp/mt, ставим ему атрибут исполнения и запускаем. Ну и далее - запускаем скрипт с нашего смонтированного диска: /jffs/etc/init.d/local.start, который уже выполняет все действия по настройке и запуску остальных процессов. Вот текст данного набора команд:
echo '#!/bin/sh'>/tmp/mt
echo insmod usb_storage>>/tmp/mt
echo insmod mbcache>>/tmp/mt
echo insmod jbd>>/tmp/mt
echo insmod ext2>>/tmp/mt
echo insmod ext3>>/tmp/mt
echo prt=\'sda1\'>>/tmp/mt
echo n=1>>/tmp/mt
echo 'while [ $n -lt 90 ] ; do'>>/tmp/mt
echo ' if [ -z "$p" ] ; then'>>/tmp/mt
echo ' p=`grep "$prt" /proc/partitions | awk '\''{print $4}'\'\`>>/tmp/mt
echo ' else'>>/tmp/mt
echo ' grep -q "/dev/discs/disc0/part1" /proc/mounts && break'>>/tmp/mt
echo ' mount -t ext2 -o noatime /dev/discs/disc0/part1 /jffs'>>/tmp/mt
echo ' fi'>>/tmp/mt
echo ' let n+=1'>>/tmp/mt
echo ' sleep 1'>>/tmp/mt
echo done>>/tmp/mt
chmod a+x /tmp/mt
/tmp/mt
/jffs/etc/init.d/local.start

Для наглядности ниже привожу текст получившегося скрипта /tmp/mt:
#!/bin/sh
insmod usb_storage # Загружаем модули
insmod mbcache
insmod jbd
insmod ext2
insmod ext3
prt='sda1' # Это наш диск в процессах
n=1 # Это счётчик итераций
while [ $n -lt 90 ] ; do # Пытаемся замаунтить полторы минуты
if [ -z "$p" ] ; then # Если диск не найден драйверами
p=`grep "$prt" /proc/partitions | awk '{print $4}'` # Проверяем нет ли уже
else # Если диск найден - монтируем, а если смонтирован - выходим из цикла
grep -q "/dev/discs/disc0/part1" /proc/mounts && break
mount -t ext2 -o noatime /dev/discs/disc0/part1 /jffs
fi
let n+=1
sleep 1 # Ждём секунду
done
Проблема номер два: не всё хорошо с ключами на SSH.
Собственно - при подключении по ssh после reboot роутера было озвучено клиентом, что сертификат хоста поменялся и клиент отказывается соединяться в связи с утерей доверия. Анализ показал, что  в nvram не содержатся rsa ключи. Собственно - в этом форуме подобная тема обсасывалась, но в моем случае workaround не прошёл - ключ rsa для хоста все-равно не создавался. Тогда я пошёл иным путём - я создал свои собственные ключи, разместил их на jffs и в скрипте local.start просто останавливаю ssh, копирую новые ключи и запускаю ssh с новыми параметрами (замечу - с ключиком длиной 4096 ssh сессия открывается около 6-8 секунд так что если нет терпения - делайте ключик покороче).

dropbear.sh:

#!/bin/sh
case "$1" in
start)
rm /tmp/root/.ssh/ssh_host_rsa_key # Удаляем старые ключи
rm /tmp/root/.ssh/ssh_host_dss_key
cp /jffs/root/.ssh/dropbear_dss_host_key /tmp/root/.ssh/dropbear_dss_host_key # Копируем новые ключи
cp /jffs/root/.ssh/dropbear_rsa_host_key /tmp/root/.ssh/dropbear_rsa_host_key
dropbear -b /tmp/loginprompt -r /tmp/root/.ssh/dropbear_rsa_host_key -d /tmp/root/.ssh/dropbear_dss_host_key -p 22  -a # Запускаем dropbear с новыми ключами
;;
stop)
killall dropbear # Прибиваем dropbear процессы
n=1
while [ $n -lt 30 ] ; do # Ожидаем пока есть dropbear процессы, но не более 30 секунд 
p=`ps | grep "dropbear" | grep "ssh_host_rsa_key" | grep -v "grep" | awk '{print $5}'`
if [ -z "$p" ] ; then
break;
fi
let
n+=1
sleep # Спим секунду
done
;;
esac
фрагмент local.start:
#!/bin/sh
/jffs/etc/init.d/dropbear.sh stop # Останавливаем демона ssh
mount -t ext3 -o noatime /dev/discs/disc0/part4 /opt # Монтируем /opt
/jffs/etc/init.d/dropbear.sh start # Запускаем демона ssh
...

Ну и на последок:
Если у вас запущен transmission на порту 53024, то в скрипт для firewall нужно добавить строчку:
iptables -I INPUT -p tcp --dport 53024 -j ACCEPT
Если вам надоело, что ваш ssh долбят DDoS-ом или подбором пароля с какого-то (в моем случае тайваньского) сайта :), можно добавить что-то вроде :
iptables -I INPUT 2 -p tcp -s 219.87.138.0/24 --dport 22 -j DROP
Удачи...

5 комментариев:

  1. Тут мне пришло несколько вопросов по почте касательно проблем с ssh сессиями. Общая суть - создаётся tunnel с ssh, который прокидывает порты в обратную сторону. Если пропадает connect, то сессия на стороне"клиента" при восстановлении соединения получае отлуп. Причина отлупа - порты заняты процессом dropbear, который не отвалился при разрыве соединения.
    Я - грешным делом - надеялся на параметр KeepAlive (-K), который выключен по умолчанию (имеет значение 0), но ожидания не оправдались - KeepAlive пакеты на клиента либо не посылаются, либо не так учитываются... В итоге я остановился на след. конфигурации - KeepAlive (-K) я оставил в 30 сек., а Interval (-I) поставил в 120. Итого - если нет активности 120 секунд соединение рвется и сразу на стороне клиента начинаются попытки восстановления соединения. Поскольку порты по разрыву в результате idle освободились в результате завершения процесса dropbear, то восстановление произойдёт без ошибки. Итого - каждые 120 секунд в случае отсутствия активности будет reconect, но сие - IMHO - не смертельно. Зато это решит поставленную задачу. Если бы KeepAlive доходил до моей клинтской сессии и правильно там обрабатывался, то каждые 30 секунд возникал бы тик активности и idle не рвал бы сессию, но мой клиент этого не поддерживает, ну и фиг с ним - главное, что цель по reconnect при первом же восстановлении канала достигнута, т.е. канал самореанимируется.
    Итого - я поправил строчку в dropvear.sh до следующей:
    dropbear -b /tmp/loginprompt -r /tmp/root/.ssh/dropbear_rsa_host_key -d /tmp/root/.ssh/dropbear_dss_host_key -p 22 -a -K 30 -I 120

    ОтветитьУдалить
  2. Да! Чтобы вас не раздражало, что ваше клиентское соединение умирает через 2 минуты отсутствия активности - просто поставьте KeepAlive на клиенте в "достаточную" величину. Я, например, на puTTY поставил в 30 сек и забыл про разрыв по non-active timeout...

    ОтветитьУдалить
    Ответы
    1. Андрей,здравствуйте! У меня вопрос не совсем по теме, точнее по теме после перепрошивки. прошился на 18024, девайс e3000. Написал все успешно, ушел в перезагруз и убился. теперь мигает диод питания и все. даже когда подключаю проводом к буку, не светится диод локалки. пробовал и сброс. Хоть ты тресни. Есть может у вас соображения по этому поводу?
      Очень буду ждать вашего ответа

      Удалить
  3. Андрей,здравствуйте! У меня вопрос не совсем по теме, точнее по теме после перепрошивки. прошился на 18024, девайс e3000. Написал все успешно, ушел в перезагруз и убился. теперь мигает диод питания и все. даже когда подключаю проводом к буку, не светится диод локалки. пробовал и сброс. Хоть ты тресни. Есть может у вас соображения по этому поводу?
    Очень буду ждать вашего ответа

    ОтветитьУдалить
    Ответы
    1. Извините за задержку - не заметил сообщения, а нотификации не было.
      По Вашей проблеме вряд ли что-то подскажу. Я не сталкивался с проблемой после некорректной перепрошивки. Чисто теоретически - если ничего не сожжено - должно всё восстанавливаться. Попробуйте пройтись по ссылке:
      http://www.dd-wrt.com/wiki/index.php/Recover_from_a_Bad_Flash

      Удалить