Обновление своего плагина для Firefox

Преамбула

В прошлом году писал заметку Делаем свое расширение для Firefox (копия), теперь краткая инструкция, как его обновить, если внесены изменения.

Загрузка обновления на сайт дополнений

1. Правим код, не забываем изменить номер версии в manifest.json, добавляем нужные файлы, упаковываем в ZIP-архив, переименовываем файл в *.xpi

2. Идем на https://addons.mozilla.org/ru/developers, жмем большую кнопку Отправить или управлять расширениями, логинимся.

3. Жмем в верхнем меню Мои дополнения, проваливаемся сюда:

.

Жмем Новая версия.

4. Загружаем файл дополнения кнопкой Выбрать файл…

У меня проверка прошла с первого раза.

5. Далее попадаем сюда:

Нас спрашивают, не использовали ли мы обфускаторы кода. Мы не использовали, если была использована библиотека jquery-?.?.?.min.js, чей код ужат, чтоб занимал меньше места — ничего страшного, Мозилла автоматом определяет, что используется известная версия библиотеки. Жмем Продолжить, попадаем на страничку, где можно ввести описание изменений (видно всем пользователям) и комментарий для проверяющих.

Одобрение, видимо из-за небольших изменений в дополнении, пришло практически моментально, похоже, в автоматическом режиме.

Записать вывод awk в несколько переменных bash

Или как раскидать результат работы awk по нескольким переменным.

Преамбула

Предположим, у нас есть некоторая таблица в виде файла CSV с набором полей, например таких Login,FullName,Phone,Room,WorkTime и разделителем полей , (запятая):

verb666,Misha Verbitsky,+415314499922,42,11:00-16:00
ktvs421,Vasiliy Kotov,+415314499966,77a,00:00-06:00
dkldn89,Dmitry Kaledin,+415314499949,65b,22:00-00:00
vfurry1,Veniamin Furman,+415314499900,99,12:20-19:25
tpunk56,Tolik Punkoff,+415314499911,59,00:00-11:00

Нужно вытащить из нее некоторые данные, и далее как-либо обработать. Вытащить данные можно с помощью awk, используя оператор print, но возникает вопрос, как передать данные обратно в bash.

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

awk и eval

В bash есть встроенная команда eval, преобразующая переданную ей строку в команду или набор команд оболочки, и запускающая ее на выполнение. Этим и воспользуемся.

1. Организуем цикл, в котором будем производить обработку данных:

IFS_=$IFS
IFS=$'\n'
for TMPSTRING in $(cat "demotable.txt")
do
#тут будет код
done
IFS=$IFS_

Перед циклом я подправил переменную $IFS содержащую глобальные разделители, в нее, в частности, «смотрят» операторы циклов, чтобы определить, где начинается следующий элемент. По умолчанию переменная $IFS содержит пробел, табуляцию и перевод строки, но поскольку у нас есть данные с пробелом, то это не подходит, цикл будет работать неверно. Потому сохраняем старое значение во временную переменную, устанавливаем новое значение в перевод строки (\n). После цикла возвращаем значение на место.
В цикле организуем разбор данных:

echo "$TMPSTRING"|awk -F "," '{print "LOGIN=" $1; print "FULLNAME=" $2
print "PHONE=" $3; print "ROOM=" $4; print "WORKTIME=" $5 }'

Если запустить скрипт сейчас, то он выведет следующее:

LOGIN=verb666
FULLNAME=Misha Verbitsky
PHONE=+415314499922
ROOM=42
WORKTIME=11:00-16:00

Т.е. уже похоже на присваивание значений переменным bash, но есть проблема. Если мы сейчас скормим вывод awk eval‘у, то получим ошибку, например такую:

./awk2vars01: line 8: Verbitsky: command not found

А если бы и не получили, то в переменных могла бы оказаться всякая ерунда, строки необходимо экранировать кавычками.

awk print и вывод кавычки

Кавычки для оператора print awk являются служебными символами, в двойные кавычки берутся строковые литералы, т.е. те строки, которые нужно вывести без изменений, как например, "LOGIN=" в коде выше, а в одинарные — вся программа awk. Экранирование (\" или \') в операторе print приведет к ошибке.

Решение — завести внутреннюю переменную awk, содержащую кавычку, и печатать ее в нужном месте:

echo "$TMPSTRING"|sed -e 's~'\''~~g'|awk -F "," '{print "LOGIN=" sq $1 sq; 
    print "FULLNAME=" sq $2 sq; print "PHONE=" sq $3 sq; print"ROOM=" sq $4 sq;
    print "WORKTIME=" sq $5 sq}' sq="'"

Поскольку данные строки далее будут переданы в eval и обработаны как команды оболочки, то необходимо позаботиться о безопасности, и использовать только одинарные кавычки, а также удалять одинарные кавычки из входных строк, при передаче их awk:

Об опасности использования eval в bash-скриптах. Копия

Вывод:

LOGIN='verb666'
FULLNAME='Misha Verbitsky'
PHONE='+415314499922'
ROOM='42'

Теперь можно обернуть все это в eval, чтобы раскидать результат работы awk по переменным.

eval $(echo "$TMPSTRING"|sed -e 's~'\''~~g'|awk -F "," '{print "LOGIN=" sq $1 sq; 
    print "FULLNAME=" sq $2 sq; print "PHONE=" sq $3 sq;
    print"ROOM=" sq $4 sq;
    print "WORKTIME=" sq $5 sq}' sq="'")

В демо-скрипте я просто вывожу данные на консоль, в реальном скрипте, что понятно, можно делать обработку данных в переменных bash.

echo "Login: $LOGIN"
echo "Full name: $FULLNAME"
echo "Phone: $PHONE"
echo "Room: $ROOM"
echo "Work time: $WORKTIME"

Вывод:

Login: verb666
Full name: Misha Verbitsky
Phone: +415314499922
Room: 42
Work time: 11:00-16:00
...

Скрипты полностью можно посмотреть на GitHub

Немного об оптимизации

Установка и настройка I2P в Slackware Linux

Преамбула

I2P это такая скрытая пиринговая сеть, подробнее можно узнать в Википедии или на официальном сайте. В отличии от TOR, она обеспечивает не анонимный доступ в Интернет, а доступ к собственным ресурсам (сайтам, файлообменникам и т.д.), скрытым из обычной сети. Гейты в «большой» Интернет в ней есть, но они кривые, косые и пользоваться ими не рекомендуется. Расскажу, как ее установить и настроить на Slackware, заодно разрешив пользователям из локальной сети также получать к ней доступ.

Установка Java

Клиент сети написан на Java, потому ее надо сначала установить. На официальном сайте есть рекомендации о необходимой версии:
Java Runtime Version 7 or higher. (Oracle, OpenJDK, or IcedTea Java Version 7 or 8 recommended.
Сама установка довольно проста:
1. Идем, например сюда
2. Скачиваем jdk-8u162-i586-2gds.txz
3. Устанавливаем стандартным образом:

installpkg jdk-8u162-i586-2gds.txz

4. Добавляем в автозагрузку (если вы не сделали отдельного скрипта для запуска сервера, то /etc/rc.d/rc.local) пути к java:

echo "Add JAVA paths..."
export JAVA_HOME=/usr/lib/java
export MANPATH="${MANPATH}:${JAVA_HOME}/man"
export PATH="${PATH}:${JAVA_HOME}/bin:${JAVA_HOME}/jre/bin"

5. Перезагружаем машину.
6. Вводим в консоли команду java без параметров. Если все было сделано правильно, то вы должны увидеть вывод краткой справки по параметрам java.

Создание пользователя для I2P

Понятно, что операции с пользователями надо делать под root или с sudo.

1. Создаем отдельную группу для I2P:

groupadd i2pgrp

2. Создаем интерактивного (пока, потом мы вырубим ему всю интерактивность) пользователя, например i2psrv:

useradd -g i2pgrp -m -d /home/i2psrv -s /bin/bash i2psrv

где:
-g i2pgrp — группа пользователя (i2pgrp)
-m — создать домашний каталог
-d /home/i2psrv — путь к домашнему каталогу (/home/i2psrv)
-s /bin/bash — установить пользователю оболочку, в данном случае фиктивную (/bin/bash)
i2psrv — имя пользователя

3. Задаем ему пароль:

passwd i2psrv

В интерактивном режиме повторяем пароль 2 раза, о сложности можно не беспокоиться — все равно потом отключим.

Установка

1. Скачиваем установщик для Linux с официального сайта
2. Копируем в директорию пользователя (/home/i2psrv) и меняем владельца файла:

chown i2psrv:i2pgrp i2pinstall_0.9.44.jar

3. Логинимся под новым пользователем.
4. Запускаем установку (через консоль):

java -jar i2pinstall_0.9.44.jar -console

5. Приводят возможность выбрать язык:

Select your language
0 [x] eng
1 [ ] bra
2 [ ] cat
3 [ ] ces
...

Оставляем английский (нажимая ENTER).

6. Далее предлагают продолжить установку:
Нажимаем 1 [ENTER]

7. Опять лицензия и всякая хрень:
Нажимаем 1 [ENTER]

8. Выбор пути для установки. Поскольку устанавливаем в каталоге нового пользователя, пусть так и делает — нажимаем [ENTER]

9. Далее нажимаем O и [ENTER] (в прошлых версиях было меньше гемора и подтверждений, а сейчас словно анкету в ментовку работать заполняешь 🙂

10. Еще раз предлагают подтвердить, что все ОК (1 и [ENTER])
11. Наконец, тебе говорят, что все ОК:

====================
Installation started
Framework: 5.1.3-84aaf (IzPack)
Platform: linux,version=4.4.14-smp,arch=x86,symbolicName=null,javaVersion=1.8.0_232
[ Starting to unpack ]
[ Processing package: Base (1/1) ]
[ Unpacking finished ]
Installation finished
On most systems, I2P can be started with:

/home/i2psrv/i2p/i2prouter start

If I2P does not start, please try:

/home/i2psrv/i2p/runplain.sh

12. Тебе говорят, что все совсем ОК:

Installation was successful
Application installed on /home/i2psrv/i2p
[ Writing the uninstaller data ... ]
[ Console installation done ]

Расшаривание I2P-сервисов в локальной сети.

Если вы намерены использовать I2P только на локальном компьютере, этот шаг можно пропустить.

1. Идем в файл /home/i2psrv/i2p/i2ptunnel.config, предварительно его куда-нибудь скопировав, и меняем в нем все 127.0.0.1 на адрес нашего компьютера в локальной сети (например на 192.168.0.20, см. адрес вашего компьютера), таким образом все сервисы I2P будут доступны с любой машины в локальной сети.
2. В том же файле смотрим порты, если где-то у нас какой-то порт для чего-то занят, например на том же порту уже висит HTTP или TOR-proxy, смело меняем порт.

Переключение пользователя

I2P — порядочный сервис, и сам умеет переключать пользователя, под которым запускается. Некоторые даже рекомендуют завести двух пользователей, одного для запуска, другого для установки I2P, но мы, ради экономии времени, делать этого не будем — и запуск и установка будут под одним пользователем. Тем не менее, необходимо отредактировать скрипт i2prouter/home/ip2srv/i2p):

1. Ищем строку, содержащую RUN_AS_USER=
2. Раскомментируем ее (удаляем # в начале строки).
3. Дописываем после знака = имя пользователя (в этом примере «i2psrv").

Расшаривание Web-консоли

Отслеживание статуса соединения с сетью I2P, ошибки и основные настройки доступны через Web-интерфейс, который запускается на локальной машине на порту 7657, но если физического доступа к той машине, на которой установлен I2P нет (или лень), то можно управлять ей и с любого компьютера локальной сети.

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

Заходим в clients.config (/home/i2psrv/i2p), предварительно сделав бэкап.
И опять меняем 127.0.0.1 на 192.168.0.20, т.е. меняем адрес машины, по которому должна появиться консоль.
Далее меняем clientApp.4.startOnLoad=true на clientApp.4.startOnLoad=false, т.к. на сервере нет смысла открывать панель управления после старта I2P.

Дальнейшая настройка под катом

Проверка

Переходим по адресу http://i2p-projekt.i2p

I2P довольно медленная сеть и работает с некоторыми перебоями, так что если вместо сайта вы увидите надпись «Сайт недоступен. Возможно, сайт отключен, сеть перегружена или ваш маршрутизатор недостаточно интегрирован с другими пирами. Вы можете повторить операцию.«, то действительно, скорее всего, операцию нужно повторить.

Отключаем интерактив пользователю i2psrv

На самом деле интерактивный доступ к системе для пользователя i2psrv был нужен только на этапе установки сервиса I2P, и я оставлял его до конца настройки на случай, если I2P понадобится переустановить. Теперь консоль пользователю i2psrv более не нужна. Отключаем:

Редактируем (под root‘ом) файл /etc/passwd.
Находим в этом файле строку, начинающуюся с имени пользователя (i2psrv) и в конце строки меняем /bin/bash на /bin/false.
Сохраняем файл.

Что дальше?

Остались нераскрытыми темы подписок (как добавлять I2P-сайты неизвестные вашему маршрутизатору I2P), интересные I2P-сайты, другие сервисы I2P, кроме WWW. Может быть когда-нибудь вернусь к этому вопросу, а пока рекомендую детально ознакомиться с документацией на сайте https://geti2p.net/, http://i2p-projekt.i2p и в консоли I2P.

Установка Linux и шифрование ее и всего содержимого жесткого диска. Часть IV

Этап #19
Восстановление системы на зашифрованный диск. Форматирование разделов

Сначала, как и на этапе 18, необходимо получить доступ к зашифрованному жесткому диску
tcplay --map=cryp_sdb --device=/dev/sdb --keyfile=/path/to/key/file

Далее, с помощью утилиты kpartx, доступ к разделам на жестком диске
kpartx -av /dev/mapper/cryp_sdb

где:
Опция a – подключить разделы, содержащиеся на зашифрованном устройстве
Опция v – отобразить, какие разделы были подключены.
/dev/mapper/cryp_sdb – подключенный с помощью tcplay зашифрованный диск.

Далее форматируем разделы. Главный:
mkfs –t ext2 /dev/mapper/cryp_sdb1
Дополнительный:
mkfs –t ext2 /dev/mapper/cryp_sdb5
И раздел подкачки:
mkswap /dev/mapper/cryp_sdb6

Отключаем подключенные разделы:
kpartx –dv /dev/mapper/cryp_sdb

Отключаем зашифрованный жесткий диск:
tcplay --unmap=cryp_sdb
Перезагружаемся обратно в консоль тестового initrd

Этап #20
Восстановление системы на зашифрованный диск. Восстановление файлов из ранее созданных бэкапов.

Как и в предыдущем этапе, сначала получаем доступ к зашифрованному жесткому диску:
tcplay --map=cryp_sdb --device=/dev/sdb --keyfile=/path/to/key/file

И его разделам:
kpartx -av /dev/mapper/cryp_sdb

Предположим, что бэкапы системы были сохранены на первый FAT32 раздел флешки sda1 и находятся по следующим путям:
/mnt/sdb1/bak/system.tar.gz и /mnt/sdb1/bak/home.tar.gz

Создаем точку монтирования для флешки (если не создана):
mkdir /mnt/sdb1
И монтируем ее (если не примонтирована)
mount –t vfat /dev/sdb1 /mnt/sdb1

Создаем точки монтирования для разделов жесткого диска:
mkdir /mnt/sda1
mkdir /mnt/sda5

Внимание! Точки монтирования для жестких дисков должны называться также, как назывались при создании бэкапов!

Монтируем разделы:
mount –t ext2 /dev/mapper/cryp_sdb1 /mnt/sda1
mount –t ext2 /dev/mapper/cryp_sdb5 /mnt/sda5

Распаковываем архивы:

tar –xvf /mnt/sda1/bak/home.tar.gz –C /
tar –xvf /mnt/sda1/bak/system.tar.gz –C /

где:
Опция x – распаковать архив
Опция v – отображать имена распаковываемых файлов
Опция f – архив находится в файле (а не направлен со STDIN)
/mnt/sda1/bak/home.tar.gz – путь к файлу архива
–C – указывает, в какой каталог распаковать архив (сам каталог указывается через пробел, и в данном случае это корень, т.е. / ).

Скопируем заранее исправленные fstab и mtab, предположим, они были сохранены в первый раздел загрузочной флешки, в каталог tabs и данный раздел смонтирован:

cp /mnt/sdb1/tabs/fstab /mnt/sda1/etc/fstab
cp /mnt/sdb1/tabs/fstab /mnt/sda1/etc/mtab

После копирования файлов отмонтируем разделы:
umount /mnt/sda1
umount /mnt/sda5

Отключаем подключенные разделы:
kpartx –dv /dev/mapper/cryp_sdb

Отключаем зашифрованный жесткий диск:
tcplay --unmap=cryp_sdb
Перезагружаемся уже с рабочим initrd.

Поздравляю! Если система успешно загрузилась с рабочим initrd, значит, задача выполнена!
После успешной загрузки можно подправить конфиг GRUB, так, чтоб сразу загружалась система с рабочим initrd.

Скачать мануал целиком в PDF

Установка Linux и шифрование ее и всего содержимого жесткого диска. Часть III

Этап #16
Подготовка конфигурационных файлов и рабочего initrd

На этом этапе первым делом определимся, под каким именем мы будем обращаться к нашему зашифрованному жесткому диску. Это имя будет использоваться в команде map утилиты tcplay. Для примера здесь и далее я буду использовать имя cryp_sdb.
Далее необходимо скопировать в отдельный каталог на загрузочной флешке (для примера пусть будет cfg) файлы /etc/fstab и /etc/mtab из основной ОС и отредактировать их, заменив /dev/sdaX на /dev/mapper/cryp_sdbX. Где X – номер конкретного раздела на жестком диске.
Далее под катом

Установка Linux и шифрование ее и всего содержимого жесткого диска. Часть II

Этап #11.
Добавление tcplay в образ initrd.

Для этого создаем какой-нибудь временный каталог и распаковываем туда из пакета (tc-play-2.0-i486-1.tgz в моем случае) полученного на этапе 8 файлы (дальнейшие пути внутри пакета)
usr/lib/libtcplay.so.2.0
usr/sbin/tcplay
Я просто воспользовался mc, зашел им в архив и нужное скопировал клавишей F5 в /tmp/tc-play, mc сам вызвал архиватор и распаковал все за меня.
Далее, выходим из архива и копируем во временный каталог (ну чтоб все нужные файлы были в одном месте и мы не запутались) файл
/lib/libdevmapper.so.1.02 (если при создании initrd, вы пользовались опцией –L, то эта библиотека уже на месте)
Теперь из временного каталога (да, можно было и сразу) скопируем файлы
libtcplay.so.2.0
libdevmapper.so.1.02
в /boot/initrd-tree/lib
(каталог библиотек файловой системы initrd)
а файл
tcplay
в /boot/initrd-tree/bin

Также tcplay во время своей работы, а конкретно подключения зашифрованных разделов вызывает из каталога /usr/sbin программу dmsetup. Соответственно, необходимо положить dmsetup в /boot/initrd-tree/usr/sbin

Чтобы dmsetup работал правильно, ему необходим каталог /dev/mapper, его тоже надо создать
mkdir /boot/initrd-tree/dev/mapper

Далее выходим из каталога initrd-tree, удаляем из директории /boot ранее созданный initrd.gz и запускаем mkinitrd без параметров, далее примонтируем нашу загрузочную флешку, заменяем файл /mnt/sda2/absolute/initrd.gz на пересозданный initrd.gz, перезагружаем компьютер и выбираем созданный на этапе 8 пункт для тестирования initrd.gz

Если все сделано правильно, то в конце загрузки будет выведено сообщение «Hello, world!» и приглашение оболочки, в котором мы введем команду tcplay. Программа должна выдать краткую справку по своим параметрам. После чего вводим команду exit и загружаемся в основную ОС.

Этап #12.
Генерация ключа для шифрования.

Для генерации ключа можно взять данные из /dev/urandom.
Если было несколько перезагрузок основной ОС и ОС некоторое время работала, то это должно быть довольно надежно. Хотя при написании данной статьи я и сомневался в этом, но мои сомнения были развеяны более опытными специалистами 🙂
Можно также воспользоваться генератором ключевых файлов, входящим в комплект Windows или Linux-версии Truecrypt, в таком случае следует использовать версию 7.1a, последнюю на момент закрытия проекта Truecrypt, скачать каковую можно, например отсюда.

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

Вот команда для генерации ключа с помощью /dev/random – стандартного устройства для получения псевдослучайных последовательностей
dd if=/dev/random of=/путь/к/файлу/имя_файла bs=1 count=256

Команда dd подробно описана, например, здесь

Далее под катом

Установка Linux и шифрование ее и всего содержимого жесткого диска.

Нам понадобятся:
1. Дистрибьютив Linux. Я здесь и далее использовал Slackware 14.2
2. Live CD Linux, я использовал Puppy Rus Slacko,

Идея в том, чтоб наша ОС и данные находились на надежно зашифрованных разделах, на жестком диске внешне не должно быть никакой разбивки, а система загружалась без ввода парольной фразы или ключа.
Как это можно реализовать
Загрузчик системы и ключ доступа будут храниться на небольшом(<50Mb) разделе флешки, при включении загрузчик разблокирует доступ к шифрованному винту, загружает ядро, далее происходит обычная загрузка системы.

Я не стал использовать LVM, а вместо LUKS выбрал клон truecrypt’а — tcplay

Этап #1. Разбиение диска на разделы

Итак, первым делом создаем нужные разделы на диске. Я сделал это в графической оболочке Puppy Rus с помощью имеющегося на диске gparted, но ничего не мешает вам сделать это с помощью другой программы.

Этап #2.
Подготовка загрузочной флешки.

Действуем как в вышеупомянутой статье – разбиваем флешку на 2 раздела, первый большой и видимый из Windows и других ОС, второй маленький – с загрузчиком операционной системы и ключами, отформатированный в Ext2. В статье рекомендуется сделать его приблизительно 50 Мб, и для загрузчика GRUB, ядра, хранения начальных настроек этого хватит. Я же сделал второй раздел побольше (1Гб) и перенес на него дополнительно Live дистрибутив Puppy Linux (чтоб в процессе настроек не грузиться с CD или другой флэшки).

Этап #3.
Установка загрузчика GRUB

Необходимо извлечь загрузочные флешки с которых ставили ОС, и/или с которых загружали Puppy Slacko, если таковые были использованы, и вставить нашу размеченную подготовленную загрузочную флешку.

Я воспользовался графической утилитой установки GRUB c LiveCD Puppy Slacko, доступ к которой можно получить из главного меню Puppy Slacko (оно по-умолчанию там же где и «Пуск» у Windows) «Система» — «Настройка загрузчика GRUB»
1. В первом диалоговом окне выбираем способ установки simple
2. Во втором предлагается выбрать разрешение экрана при загрузке, я выбрал standart, ибо для Slackware потом все равно необходимо перенастроить параметры разрешения экрана при загрузке в конфиге GRUB.
3. В следующем окне необходимо указать местоположение директории boot, это второй раздел нашей флешки, который у меня называется sdb2, соответственно указывается устройство /dev/sdb2
4. В следующем окне выбираем запись загрузчика в MBR
5. В следующем окне вводим устройство, в MBR которого будет записан загрузчик, в данном случае это наша флешка, которая обозначена как /dev/sdb (у меня)

Продолжение под катом

Поздравляю! Мы загрузились с помощью образа initrd до загрузки основной ОС.
Для продолжения загрузки надо ввести exit и нажать enter. Управление будет передано программе init из основной ОС и основная ОС загрузится.

Домашний сервер на базе Slackware Linux

Давно хотел собрать в кучу заметки про то, как можно организовать домашний сервер (или сервер для малого офиса) на базе Slackware Linux с VPN, I2P, Tor, файл-помойкой на локальном FTP, возможностью установки с сервера ПО и операционных систем, а возможно и с внутренними Web-сайтами, чатами и что там еще надо в зависимости от ваших задач. А еще и с полным шифрованием жесткого(-их) дисков.

Это пост-оглавление. Тут буду копить внутренние ссылки на заметки, относящиеся к организации сервера. Нумерация и последовательность также может меняться, т.к. я пишу как придется, а в содержании буду по мере накопления материала сортировать как надо.

Что примерно надо построить на начальном этапе. Сервер в локальной сети, позволяющий клиентам выходить в Интернет, как минимум через два различных IP (VPN и IP основного провайдера), поддерживающий локальный FTP и/или Samba (файловое хранилище), поддерживающий проходную ноду Tor и I2P-роутер, а также обеспечивающий локальным клиентам доcтуп в сети Tor и I2P.

Ремарка про железо. На самом деле, чем круче, тем круче, но изначально все делалось на старом Celeron с 500 Гб HDD и 512 Мб ОП, сейчас все вертится на Dual Core Intel Celeron E3200 (2400МГц) с гигабайтом встроенной памяти и встроенным видео, тоже не самая новая машина, но получше. А вообще хочу, чтоб оно на PIII-700 заработало. Сетевая карта одна (расскажу, как из одной реальной виртуальных наделать).

Оглавление

Установка Linux и шифрование жесткого диска:
Часть I Копия
Часть II Копия
Часть III Копия
Часть IV Копия
Пример конфига GRUB для загрузки сервера Копия
Эта часть целиком в PDF

Начальная настройка сети Копия
Network namespaces или несколько виртуальных сетевых карт (интерфейсов) с разными IP на одной машине. Копия
Настройка файерволла (IPTABLES) Копия

Локальный FTP Копия
Нода TOR Копия
Настройка доступа к I2P Копия
PXE (установка и запуск различных ОС со своего сервера на локальных машинах) Копия

Локальный прокси-сервер:
Запускающий скрипт Копия
Инструкция по установке Копия
Изменения в конфигурации последней версии Копия

Делаем свое расширение для Firefox. Содержание.

Делаем свое расширение для Firefox. Часть I. В которой мы все подготавливаем.
Делаем свое расширение для Firefox. Часть II. В которой работаем с пользовательскими настройками аддона.
Делаем свое расширение для Firefox. Часть III. Работа с запросами.
Делаем свое расширение для Firefox. Часть IV. Background, сборка, публикация.

Копия на lj.rossia.org:

Делаем свое расширение для Firefox. Часть I. В которой мы все подготавливаем.
Делаем свое расширение для Firefox. Часть II. В которой работаем с пользовательскими настройками аддона.
Делаем свое расширение для Firefox. Часть III. Работа с запросами.
Делаем свое расширение для Firefox. Часть IV. Background, сборка, публикация.

Страничка расширения на tolik-punkoff.com
Страничка расширения на lj.rossia.org

Делаем свое расширение для Firefox. Часть IV. Background, сборка, публикация.

Делаем background

Теперь делаем специальный модуль ip_background.js, который будет выполнять всю работу нашего аддона, во время работы браузера.

Создаем файл ip_background.js и копируем из файла ip_popup.js все содержимое, кроме строк с addEventListener, т.к. слушатели событий в background будут другие. Функцию doRequest пока оставим в покое, ей займемся чуть позже.

Из функции onGot(item) удаляем строку document.getElementById("script").value = curAddr;, т.к. никаких текстовых полей в бэкграунде нет и не предвидится, менять элементы нам тут не надо.

Еще я переименовал функцию bodyLoad в listinerRun, она у нас будет одна, на все три обрабатываемых события.

В целом, логика работы остается такой же, как и во всплывающей странице, только вместо заполнения элементов нам нужно будет менять картинку на кнопке и ее же всплывающую подсказку.

Так, начало положена, у нас есть «болванка» нашего background-скрипта, сохраняем ее и модифицируем manifest.json

Модификация manifest.json

В manifest.json следует добавить секцию "background", где перечислить в массиве "scripts" скрипты, запускаемые браузером во время работы нашего расширения. Понадобятся два скрипта, собственно ip_background.js и библиотека JQuery jquery-3.4.1.min.js:

"background": {
    "scripts": [
      "jquery-3.4.1.min.js",
      "ip_background.js"
    ]
  }

Новый manifest.json на PasteBin

Далее под катом

Дополнительно

Внешний скрипт на PHP, который можно использовать, как замену api.myip.com (копия)
На GitHub

Скачать

Страница дополнения на mozilla.org
Исходники на GitHub
Скачать подписанный xpi с GitHub
Этот мануал в PDF + весь код в одном архиве:
С Mega.nz
С Google.Drive

Предыдущая часть
Содержание

Делаем свое расширение для Firefox. Часть III. Работа с запросами.

Работа с запросами

До того, как мы будем выполнять запросы к внешним ресурсам, надо внести изменения в manifest.json, дав соответствующее разрешение "<all_urls>" в permissions.
Все разрешения для нашего аддона:

"permissions": [
    "activeTab",
    "tabs",
    "storage",
    "<all_urls>"
  ]

Внимание! Если разрешение "<all_urls>" не дать, то при попытке обращения к внешнему ресурсу произойдет ошибка:

Запрос из постороннего источника заблокирован: Политика одного источника запрещает чтение удаленного ресурса на https://api.myip.com/. (Причина: отсутствует заголовок CORS «Access-Control-Allow-Origin»).

Почему-то ссылка на пояснение к ошибке на сайте Мозиллы ведет не совсем на то, что нужно, а в поиске, тоже неизвестно почему, информация о том, что нужно просто дать разрешение "<all_urls>" в manifest.json не всплывает. Сам еле догадался, практически методом научного тыка устранил данный глюк.

Небольшое отступление от программирования

После долгого ковыряния в отладке и интернете я решил немного отдохнуть, и дополнить дизайн расширения.

Фактически, у запроса есть три состояния:

— запрос выполняется
— запрос выполнен успешно
— запрос завершен с ошибкой

Обо всем этом можно и нужно сообщать пользователю, и симпатичнее всего это сделать, меняя иконку. Нарисовал и сохранил в каталог flags.

— запрос выполняется (1working.png)

— запрос завершен с ошибкой (2error.png)

— если запрос выполнен успешно, то будем показывать флаг страны, как и планировалось изначально. Но, на всякий случай, можно предусмотреть ситуацию, когда страну определить не удалось (с api.myip.com это вряд ли случится, но с другим скриптом, выдающим данные в том же формате может быть).

— страна неизвестна (3unknow.png)

Подключение JQuery

GET-запрос к сайту оказалось проще всего сделать с помощью библиотеки JQuery.
Скачиваем библиотеку и сохраняем ее в каталог с ip_popup.html. В самом ip_popup.html подключаем ее (перед скриптом ip_popup.js):

<script src="jquery-3.4.1.min.js"></script>

Далее под катом

Предыдущая часть
Продолжение

Делаем свое расширение для Firefox. Часть II. В которой работаем с пользовательскими настройками аддона.

Сохранение настроек

function saveSettings()
{
	var scriptAddr = document.getElementById("script").value;
	scriptAddr = scriptAddr.trim();
	
	if (scriptAddr != "")
	{
		if (window.confirm('Save script address ' + 
                    scriptAddr + '? Are you sure?'))
		{
			browser.storage.local.set({
				server_settings: {script_addr: scriptAddr}
			});
			window.alert('Settings saved!');
		}
		else
		{
			document.getElementById("script").value = curAddr;
		}
	}
}

Что тут делается:

1. Сначала в переменную scriptAddr записывается значение текстового поля с id=script, т.е. того поля, куда можно ввести адрес скрипта.
2. Функцией trim() обрезаем начальные и конечные пробелы, вдруг их пользователь навводит.
3. Если scriptAddr не пустая строка, то запрашиваем у пользователя подтверждение сохранения функцией window.confirm() Функция выведет на экран окошко с текстом, заданным в качестве ее аргумента и кнопками «Да» и «Нет». Если нажата «Да», функция вернет true, если «Нет» — false.

Подробности: «Взаимодействие: alert, prompt, confirm»

4. Если отвечено да, то пользуемся API Firefox’а, а именно функцией browser.storage.local.set(object), которой, в данном случае, передается объект, содержащий объект server_settings, содержащий единственный параметр script_addr. Значение script_addr устанавливаем из переменной scriptAddr. Далее сообщаем пользователю, что настройки сохранены (window.alert('Settings saved!');)

Подробности и примеры работы с локальным хранилищем: StorageArea.get()

5. Если было отвечено «Нет», то восстанавливаем значение текстового поля:

document.getElementById("script").value = curAddr;

В конце js-файла, после всех функций, подключаем обработчик события (слушатель) для события «click» кнопки с id == save:

document.getElementById("save").addEventListener("click", saveSettings);

Внимание! Функции addEventListener имя функции-обработчика передается без круглых скобок

document.getElementById("save").addEventListener("click", saveSettings()); //неправильно

Если добавить скобки, то код функции saveSettings просто однократно выполнится, когда дойдет очередь до addEventListener

Да, ошибка детская, но искать потом концы довольно муторно.

Далее под катом

Начало
Продолжение

Делаем свое расширение для Firefox. Часть I. В которой мы все подготавливаем.

Преамбула

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

IP и страну будем получать с https://api.myip.com/, который выдает нужную информацию в виде JSON:

{"ip":"162.247.73.193","country":"United States","cc":"US"}

Подготовка структуры каталогов.

Создадим где-нибудь в удобном месте каталог, например, deoip, он будет корневым каталогом нашего плагина, а в нем 2 подкаталога icons и flags

Иконки и флаги стран.

Плагину требуется как минимум одна иконка 48×48 для отображения в менеджере дополнений, и желательна еще одна 96×96 пикселей. В Мозиловском примере говорится, что можно сделать иконку в формате SVG, но я не стал экспериментировать и сделал две PNG-шки.

Флаги стран, которые будут отображаться на кнопке панели, должны иметь размер 32×32 пикселя, а имена файлов соответствовать двухбуквенному ISO-коду страны. Я использовал готовые иконки из коллекций плюс еще одну иконку по умолчанию (0none.png).

manifest.json

manifest.json — это главный файл расширения, содержащий основные опции плагина.

Пока он выглядит так:

{
  "manifest_version": 2,
  "name": "External IP GeoIP",
  "description": "Display you external IP and IP country",
  "version": "0.0.1",
  "icons": {
    "48": "icons/48.png",
    "96": "icons/96.png"
  },
  "browser_action": {
    "default_icon": "flags/0none.png",
    "default_title": "External IP GeoIP"
  },
  "permissions": [
    "activeTab",
    "tabs",
    "storage"
  ]
}

Сначала идут обязательные опции manifest_version и name — имя расширения, далее дополнительные, но желательные description и version, соответственно, краткое описание и версия. В секции icons указываются пути к иконкам для менеджера дополнений (все пути должны быть относительными, относительно, собственно manifest.json). В секции browser_action описывается кнопка на панели браузера и привязанные к ней действия, пока действий у нас никаких (потом добавим выплывающее меню), а задача просто отобразить кнопку на панели. Поэтому добавляем опцию default_icon — путь к иконке по умолчанию, и всплывающую подсказку default_title (появится, если к кнопке подвести указатель мыши).
Далее интересная секция permissions. Это разрешения для нашего плагина. Я уже примерно прикинул какие разрешения нам понадобятся: доступ к вкладкам (tabs), к активной вкладке (activeTab) и хранилищу, которое используется для сохранения настроек плагина (storage).

Подготовка Firefox к тестированию плагина

Особая подготовка не требуется, но я рекомендую все-таки сделать отдельный пустой тестовый профиль. Набираем в адресной строке about:profiles, жмем Enter, попадаем на страницу профилей, создаем отдельный профиль test и жмем «Запустить еще один браузер с этим профилем»

Первый запуск

В браузере с новым профилем набираем в адресной строке about:debugging, слева выбираем «Этот Firefox«, и жмем кнопку «Загрузить временное дополнение» и выбираем наш manifest.json. Теперь идем в меню «Инструменты —> Дополнения» или набираем в адресной строке about:addons, и если все сделано правильно, то видим наше дополнение в списке дополнений, а если откроем просто пустую вкладку, то увидим и кнопку.


Делаем всплывающую панель

Продолжение

Простая инструкция по установке Tinyproxy

Небольшое введение

Tinyproxy это такой маленький http/https прокси-сервер, на мой взгляд, очень простой в использовании и конфигурировании, вполне подходящий для несложных задач пропускания http(s) трафика. Например в офисе или дома. Лично я использую его, чтоб можно было посещать статистику и личный кабинет собственного провайдера в обход VPN.

Конфигурация network namespace.

Если у вас есть специальный network namespace для прокси, перед установкой сервера настраиваем его (добавляем нужные файлы hosts и resolv.conf, как это описано здесь Копия)

Рестартируем систему (или сетевой менеджер/демон, тут уж зависит от вашей ОС).

Устанавливаем tinyproxy

Для Sclackware можно скачать пакет с исходниками с помощью sbopkg, взять готовый и откомпилированный здесь (Для Slackware 12-14.2), или собрать из исходников на GitHub и готовый пакет установить с помощью installpkg.

Создаем пользователя и группу

1. Создаем группу для proxy-сервера, например proxy:

groupadd proxy

2. Создаем отдельного пользователя для запуска прокси-сервера:
Можно сделать это с помощью скрипта-обертки adduser над программой useradd.
— На первый вопрос вводим имя пользователя, например, provproxy.
— Далее пропускаем (нажимаем enter)
— В ответ на initial group, вводим имя ранее созданной группы для прокси-сервера, в данном случае proxy (в вашем — ту группу, которую создали вы).
— Далее, на вопрос о дополнительных группах, нельзя устанавливать что-либо, нажимаем Enter
— Home directory нужна, там будет лежать PID-файл, логи (если нужно) и конфигурационный файл. По умолчанию директория совпадает с именем пользователя и располагается в подкаталоге /home.
— Shell должна быть установлена строго в /bin/false, поскольку это не интерактивный пользователь. Если скрипт ответил вам: - Warning: /bin/false is not in /etc/shells (potential problem using FTP)
Do you wish to change the shell ? (Y/n)

То отвечаем n, а потом в /etc/shells добавляем строчку
/bin/false
— Expiry date пропускаем (Enter)
— Далее пропускаем всю User Information
— На вопрос о пароле придумываем что-нибудь чтоб прошло.
Далее правим /etc/shadow, находим строчку с именем пользователя и удаляем все, что между первым и вторым двоеточием. Было:
provproxy:$5$S8/tp/ap2wF/K$qaYnfHuR8opsWO0WwTaXCjiHjmge7mWuH5WwEd5Kn70:17888:0:99
Стало: provproxy::17888:0:99
Права на каталог надо установить в 700 (полный доступ для пользователя provproxy):
chmod 700 /home/provproxy

Можно не пользоваться интерактивным скриптом, а сделать все с помощью базовых команд:
1. Добавить пользователя
useradd -g proxy -d /home/provproxy -s /bin/false provproxy

где:
-g proxy группа пользователя (ранее созданная proxy)
-d /home/provproxy домашний каталог пользователя
-s /bin/false — оболочка для пользователя. Обычно здесь прописывается /bin/sh, /bin/bash для интерактивных пользователей, или /bin/false для неинтерактивных, что нам и надо в данном случае.
Строчка /bin/false должна быть в файле /etc/shells — если ее нет, дописать.

2. Создаем домашний каталог:
mkdir /home/provproxy
3. Меняем владельца каталога на пользователя provproxy
chown provproxy:proxy /home/provproxy
4. Меняем права доступа на каталог:
chmod 700 /home/provproxy

Инициализационный скрипт tinyproxy

Был подробно описан в этой заметке: Запускающий скрипт для tinyproxy Копия

Сам скрипт:
— На PasteBin
На GitHub
Скачать с Mega.nz

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

PID-файл: в скрипте необходимо правильно указать путь к PID-файлу, но об этом поговорим ниже. У меня PID-файл создается в домашнем каталоге пользователя provproxy. Местоположение PID-файла задается в этой строке скрипта. Если надо, не забудьте исправить на свое значение:

PIDFILE="/home/provproxy/tinyproxy.pid"

Команда запуска прокси-сервера:
По умолчанию там просто указан путь к исполняемому файлу tinyproxy:

TINYPROXYCMD="/usr/sbin/tinyproxy"

Но я хочу эту команду немного подправить.

Запуск сервера при старте системы.

При старте системы все обычно запускается от root‘а, а нам не надо совершенно, чтоб под root‘ом крутились всякие там сервера. Не зря же мы отдельного пользователя делали. Дополняем команду:

TINYPROXYCMD="sudo -u provproxy /usr/sbin/tinyproxy"

В таком виде, скрипт, запускаемый при старте из-под root‘а вызовет tinyproxy от имени нужного нам пользователя. Справедливости ради, надо заметить, что tinyproxy, как любой уважающий себя сервер, умеет сам себе понижать права до определенного пользователя, указанного в файле конфигурации. Но на этом остановимся ниже. На мой взгляд, одно другому не мешает, зато так виднее и жестко задано, от какого пользователя стартовать.

Альтернативный файл конфигурации.

По умолчанию tinyproxy ищет свой файл конфигурации в /etc/tinyproxy.conf, но можно задать альтернативный, в домашнем каталоге пользователя. Делается это путем добавления ключа и пути к файлу. Объединю этот вариант с предыдущим:

TINYPROXYCMD="sudo -u provproxy /usr/sbin/tinyproxy -c /home/provproxy/tinyproxy.conf"

Альтернативный конфигурационный файл в домашнем каталоге.

Раз уж началось с альтернативного файла конфигурации, так давайте его сделаем (от root). Копируем файл /etc/tinyproxy.conf в /home/provproxy/tinyproxy.conf

cp /etc/tinyproxy.conf /home/provproxy/tinyproxy.conf

Далее устанавливаем ему владельца (можно перейти в директорию /home/provproxy перед этим, я перешел — пути будут неполные):

chown provproxy:proxy tinyproxy.conf

И права — пользователю provproxy на tinyproxy.conf нужны права только на чтение, ничего он не пишет в конфигурационный файл, и тем более не пытается исполнить.

chmod 400 tinyproxy.conf

Конфигурирование.

Открываем файл от root‘а и настраиваем параметры прокси-сервера.

Подробно описывается конфингурационный файл

Проверка

Прописываем нужный адрес прокси в браузере:

Проверяем соединение:

Вот тут не показывается, что используется прокси, потому что прокси настроен верно — с отключением via и других заголовков, передающих IP-адрес.

Источники

Tinyproxy, краткая инструкция

Неверный IMEI после прошивки Philips Xenium v 377 и его восстановление.

Принесли означенный телефон, выдающий ошибку «Неверный IMEI» и не видящий ни одной сим-карты. По *#06# также выдается сообщение о неверных IMEI. Восстановил через инженерное меню, по инструкции. Делаю заметку на случай, если вдруг еще понадобится, а оригинал инструкции сгинет.

Сначала надо попасть в инженерное меню:

*#*#3646633#*#*

Далее переходим на вкладку Connectivity и выбираем пункт CDS Information

Далее переходим в пункт Radio Information

Далее выбрать Phone (там их будет два, для первой сим-карты и второй)

Для Phone 1 надо ввести команду AT+[ПРОБЕЛ]EGMR=1,7,”ваш имей”
Нажать кнопочку SEND AT COMMAND

Вместо «ваш имей», таки да, IMEI. Они под крышкой на наклейке, приклеенной на металл корпуса.
Если забыть пробел, то чуда может не получиться, произойдет ошибка This command is not allowed in UserBuild

Перезагружаем устройство, проверяем наличие IMEI #1 по *#06#, повторяем операцию для второго слота, с той только разницей, что выбираем Phone 2 и вводим другую команду: AT+[ПРОБЕЛ]EGMR=1,10,”ваш имей”

Оригинал инструкции
Картинки утащены оттуда же, надеюсь, автор не обидится.

Форма обратной связи для WordPress, без плагина. Защита от спама и полевые испытания ASCII-каптчи

Или еще раз возвращаясь к напечатанному. Сегодня поговорим о защите от спама.
В первоначально описанном способе копия был баг (промотайте в конец), из-за которого можно было легко и непринужденно загадить ящик получателя спамом, да еще и в автоматическом режиме. Отправить картинки, вирусы, или загадить чужой ящик не получится, но вот закидать «Войной и миром» ящик владельца сайта вполне таки да.
Чтобы уменьшить такую вероятность, добавим в скрипт отправки почты каптчу. Поскольку скрипт, отправляющий почту (mail.php) к компонентам WordPress не относится, то каптчу придется изобретать свою. Лично мне это оказалось даже хорошо, т.к. совсем недавно я писал о создании ASCII-каптчи, копия, и мне прямо-таки жгло показать ее работу в реальном проекте, а не только в учебных примерах. Посему ее и используем для защиты от спама.

Постановка задачи

Переписать скрипт mail.php так, чтобы он смог использовать ASCII-каптчу.

Краткое описание процесса

1. Пользователь в форме обратной связи, вводит сообщение.

2. По нажатию кнопки «Отправить» сообщение передается скрипту mail.php
3. Если сообщение было отправлено из формы, то скрипт генерирует каптчу, HTML-страницу, содержащую параметры сообщения (имя, текст, электронный адрес пользователя), ASCII-изображение каптчи, поле для ввода кода, элементы управления (кнопки) с помощью которых пользователь может ввести код, обновить код подтверждения, отправить код и сообщение.
4. Скрипт также должен обработать возможные ошибки. Если они есть, пользователю выводится соответствующее сообщение и страница с формой ввода сообщения открывается вновь.
5. Если каптча введена неверно, пользователю демонстрируется сообщение об ошибке ввода каптчи, и дается возможность повторить ввод каптчи. Информация в сообщении сохраняется.
6. Если код введен верно и другие ошибки отсутствуют, сообщение передается на заранее указанный в скрипте e-mail.
Далее подробное описание скрипта

А ТЕПЕРЬ, ВНИМАНИЕ, ВОПРОС
Обход этой каптчи:

Реализация не совсем промышленная. Мне хочется, чтобы вы подумали, над тем, как данный способ защиты обойти. Можете воспользоваться своим методом и попытаться заспамить мне почтовый ящик. Кто заспамит — получит минус два вопроса на зачете.
Можно спамить просто так, но желательно, с описанием способа. Я знаю 5.

Комментарии на lj.rossia.org будут открыты для всех, можно анонимно предлагать, как способы обхода, так и способы защиты. Стирать не буду ничего, кроме флуда, спама и личных оскорблений.

Для самых ленивых, кто не удосужился все прочесть. Инструкция по установке.

Форма обратной связи для WordPress, без плагина здесь или здесь

Все делается так же, с той лишь разницей, что обновленный архив скачиваете по ссылке ниже, и не забываете закачать captcha.php в директорию темы, вместе с mail.php.

Ссылки

Смотреть код скрипта на PasteBin
Скачать все одним архивом
Тесты и куски кода

Заметка в PDF

Страница со списком тегов (или рубрик) WordPress

Если перейти в блоге WordPress по ссылке на любой тег, то попадем на страничку, содержащую анонсы постов по данному тегу, адрес странички будет примерно такой:

http://tolik-punkoff.com/tag/manuals/

Где manuals — собственно, выбранный тег, а tag — префикс для URL-адреса меток, который можно настроить в консоли WordPress в разделе Настройки — Постоянные ссылки.

Идея такого формата адреса достаточно очевидна, убираешь из строки адреса выбранный тег и попадаешь в список всех тегов, как например это сделано в ЖЖ или LJR

Вообще-то в профессиональной теме WordPress это дело должно бы работать из коробки, потому что вообще-то плохо, если раздел сайта, который логически существовать должен, не существует. И так думаю не я один, а как выяснилось из логов, и роботы. Правда это оказался робот какого-то мелкого поисковика, не Google или Яндекса, но все равно неприятно.
Так вот, если тема не сильно профессиональная, или разработчик забыл о такой мелочи, то посетитель сайта попадет по такой ссылке на страницу 404.

Исправляем досадную неприятность.

Читать далее…

Скачать заметку в формате PDF

Настройка XDMCP, удаленного подключения к рабочему столу Linux

Не так давно я затрагивал вопрос настройки X11 Forwarding [Копия], что позволяет через ssh запускать отдельные графические приложения на удаленной Linux-машине (сервере). Теперь буду настраивать удаленный доступ к рабочему столу через XDMCP.
XDMCP внешне похож на RDP в Windows, т.е. при подключении пользователю будет предложено ввести логин и пароль в окне входа в систему и на экране отобразится удаленный рабочий стол. Фактически, на удаленной машине в памяти висит Display Manager (GDM, XDM и т.д.) и слушает 177 порт UDP, если от X-сервера с другой машины поступает запрос, Display Manager начинает с ним общаться, принимать оттуда изображение, а туда передавать координаты мыши и нажатия с клавиатуры, рисует окошко входа в систему. Если пользователь предоставил корректные данные для входа в систему, то он сможет работать с удаленным рабочим столом.

Внимание! Не все Display Manager’ы поддерживают работу по протоколу XDMCP. Точно поддерживают XDM, GDM, KDM и LightDM [3], так что проверьте в первую очередь, какой у вас Display Manager, и может ли он работать по XDMCP. Например, на одной из машин, к которой требовался доступ по XDMCP пришлось вместо LXDM ставить GDM.
Внимание! Протокол XDMCP довольно слабо защищен, так что его не рекомендуется использовать через Интернет без дополнительного шифрования. У нас, например, сделан доступ через VPN.

Настройка файервола

Первым делом необходимо открыть на файерволе нужные порты. Обязательно для входящих соединений открывается порт UDP 177. Если соединение планируется из Windows, то необходимо также открыть порты TCP 6000-6005 в обоих направлениях (входящие и исходящие соединения). Для соединения из Gnome вроде как надо открыть также в обоих направлениях порты TCP 16001 и 35091 [2]. На практике я проверял только подключение из Windows.
Команды для настройки файервола:

# XDMCP
echo "Open 177 port UDP (XDMCP) for Avallon AG clients..."
iptables -A INPUT -s x.x.x.x/yy -p udp --dport 177 -j ACCEPT
iptables -A OUTPUT -s x.x.x.x/yy -p udp --sport 177 -j ACCEPT

echo "Open 6000:6005 ports (Windows XDMCP) in both directions for AAG clients..."
iptables -A INPUT -s x.x.x.x/yy -p tcp -m multiport --dports 6000:6005 -j ACCEPT
iptables -A OUTPUT -s x.x.x.x/yy -p tcp -m multiport --sports 6000:6005 -j ACCEPT

iptables -A INPUT -s x.x.x.x/yy -p tcp -m multiport --sports 6000:6005 -j ACCEPT
iptables -A OUTPUT -s x.x.x.x/yy -p tcp -m multiport --dports 6000:6005 -j ACCEPT

Вместо x.x.x.x/yy надо подставить адрес компьютера с которого будем связываться с компьютером под Linux, или маску подсети.

Настройка Display Manager’а

У меня был GDM, поэтому приведу его как основной, остальные дам для справки.
Необходимо найти файл custom.conf, в источниках написано, что лежать он должен по адресу /etc/gdm/custom.conf, но на самом деле это зависит от дистрибьютива. В моем случае файл находился здесь: /etc/X11/gdm/custom.conf

В файле, который выглядит, как обычный INI-файл необходимо найти секцию [xdmcp] и вписать туда следующие параметры:

Enable=true
Port=177

Как видите, можно задать альтернативный порт для XDMCP.

Настройка других DM:
Под катом

Внимание! Стоит заметить, что в некоторых случаях конфигурационные файлы могут располагаться в других местах. Если их нет по указанным путям, можно воспользоваться поиском файлов в том же mc

Настройка подключения в Windows

Понадобится уже упомянутый в заметке про X11-Forwarding Xming.
Запускаем XLaunch и устанавливаем конфигурацию.

В первом окне выбираем один из режимов «одного окна», например One window, иначе не даст создать XDMCP сессию, и указываем номер дисплея 0 (обычно 0, если вы специально ничего не переопределяли на сервере, подробнее см. документацию по используемому Display Manager’у):

Описание настройки с иллюстрациями под катом

Если все сделано правильно

То при запуске Xming (через мастер XLaunch или с нужными параметрами) мы увидим окно авторизации в системе:


По клику доступно полноразмерное изображение

Если авторизация удалась, то мы увидим рабочий стол удаленного компьютера.


По клику доступно полноразмерное изображение

Сохранение и использование настроек соединения

Чтобы каждый раз не вписывать и не выбирать вручную все параметры в мастере XLaunch, можно воспользоваться двумя способами:

1. Как ранее говорилось, сохранить конфигурацию в файл *.xlaunch (например xdmcp.xlaunch) и запускать мастер XLaunch, указывая ему с помощью ключа -load файл конфигурации. Мастер XLaunch запустится, но все поля в окнах будут уже предварительно заполнены. Это удобно, если нужно соединяться по XDMCP с несколькими серверами, различающимися только, например, IP-адресом. Можно создать ярлык, в свойствах которого указать параметры к запуску XLaunch:

"C:\Program Files\Xming\XLaunch.exe" -load xdmcp.xlaunch

2. Создать ярлык Xming с нужными параметрами:

"C:\Program Files\Xming\Xming.exe" :0 -clipboard -query 10.10.3.24 -dpi 96

Естественно, вместо 10.10.3.24 нужно подставить свой адрес удаленной машины с XDMCP, а число после -dpi выбрать под свои глаза и монитор.

Источники

1. Удаленный доступ по XDMCP (удаленное подключение к рабочему столу)
2.What Ports Need to be Opened for XDMCP
3.Xdmcp

Копия заметки в PDF

Удаленная перезагрузка сервера под управлением Linux. Перезагрузка Linux без ввода пароля.

На самом деле делалось не для совсем сервера, но тем не менее. Стоит, в общем, на одном заводике в одной из стран СНГ аппарат по переработке пластиковых отходов в пластиковые полезности, управляет им комп с Linux на борту, а компом из будочки рядом управляет оператор с рабочего места с обыкновенной виндой. Комп с Линуксом надо иногда перезагружать, отключать, а в штатном ПО аппарата эту возможность почему-то не встроили. Раньше оператором был довольно умный парень, которому и root-пароль можно было доверить, и ssh, но он уволился, напоследок создав два батника примерно такого содержания:
plink -ssh -P 22 -l root -pw rutoviiparol 192.168.0.40 reboot
plink -ssh -P 22 -l root -pw rutoviiparol 192.168.0.40 poweroff

Бардак сущий, под root ходить для перезагрузки никуда не годится, да еще и хранить рутовый пароль в открытом виде. Можно, конечно, было бы подправить батник, сделав вход под юзерской учеткой, но sudo было криво настроено и все равно оператору бы пришлось для перезагрузки вводить пароль.

Решение

Завести на сервере отдельных пользователей «для отключения» и «для перезагрузки» и настроить все так, чтобы при входе этих пользователей по ssh автоматически выполнялось выключение или перезагрузка, при этом не требовался ввод пароля, создать соответствующие bat-файлы на операторском рабочем месте.

Создание группы

Первым делом понадобится группа для этих пользователей. Самая простая операция. Назовем группу, например powermanager и создадим ее (естественно, здесь и далее все команды, требующие root-доступа делаются из-под учетки root или через sudo).

groupadd powermanager

Настройка sudo, редактирование файла sudoers

В файле /etc/sudoers как раз и описывается, какие пользователи и группы имеют возможность пользоваться утилитой sudo, временно повышая свои права до root, и какие команды им разрешено выполнять без пароля.
Этот файл руками лучше не редактировать, а всегда делать это с помощью команды visudo:

Файл настроек /etc/sudoers всегда следует редактировать с помощью команды visudo. visudo блокирует файл sudoers, сохраняет изменения во временный файл и проверяет, что файл грамматически корректен, перед тем как скопировать его в /etc/sudoers.
Важно:
Крайне важно, чтобы файл sudoers был без синтаксических ошибок! Любая ошибка делает sudo неработоспособным. Всегда редактируйте его только с помощью visudo для предотвращения ошибок.
[1]

I. Улучшаем работу с sudoers

Но есть небольшая проблема, visudo, в качестве вызываемого ей редактора, использует неудобный vi, который без стакана и длительной практики может только «пищать и портить». Слава Ктулху, на компьютере стоял mc, и, соответственно, mcedit, поэтому:

1. Переопределение редактора для visudo при однократном запуске:

EDITOR=mcedit visudo

Уфф, /etc/sudoers открылся в человеческом mcedit.

2. Постоянная замена редактора для visudo
Для этого добавляем в sudoers следующие строки:

Defaults env_reset
Defaults editor=/usr/bin/mcedit, !env_editor

где editor=/usr/bin/mcedit указание, какой редактор использовать
!env_editor — запрет использования редактора, установленного переменными окружения (подробности смотрите по ссылке на детальное описание файла sudoers в конце заметки).

II. Прописываем разрешения для группы powermanager в sudoers

Для разрешения пользоваться командой shutdown без ввода пароля для пользователей группы powermanager, в sudoers следует добавить следующую конструкцию:

%powermanager ALL=NOPASSWD: /sbin/shutdown

Внимание! Для более полного понимания sudoers настоятельно рекомендую ознакомиться со статьей по ссылке в конце заметки!
Внимание! Все пути в файле sudoers должны быть полными

Пример файла sudoers можно посмотреть здесь.

Создание пользователей для перезагрузки и отключения питания

Создание пользователя для удаленной перезагрузки.

1. Создаем пользователя:

useradd -g powermanager -d /home/rebootusr -s /home/rebootusr/reboot.sh rebootusr

где:
-g powermanager группа пользователя (ранее созданная powermanager)
-d /home/rebootusr домашний каталог пользователя
-s /home/rebootusr/reboot.sh — оболочка для пользователя. Обычно здесь прописывается /bin/sh, /bin/bash для интерактивных пользователей, или /bin/false для неинтерактивных, например пользователя FTP, но можно задать и собственный скрипт, команды которого будут выполнены при входе пользователя в систему.

2. Задаем пользователю пароль (иначе не сможем залогиниться по ssh):
passwd rebootusr
3. Создаем домашний каталог:
mkdir /home/rebootusr
4. Меняем владельца каталога на пользователя rebootusr
chown rebootusr:powermanager /home/rebootusr
5. Меняем права доступа на каталог:
chmod 500 /home/rebootusr
6. Создаем в домашнем каталоге скрипт reboot.sh со следующим содержимым:

#!/bin/sh

echo "Rebooting..."
sudo /sbin/shutdown -r now

где
-r — указание программе shutdown выполнить перезагрузку
now — указание временного интервала — немедленно (можно еще выставить число в минутах, тогда перезагрузка произойдет через указанное время)

7. Меняем владельца и права доступа для скрипта reboot.sh

chown rebootusr:powermanager /home/rebootusr/reboot.sh
chmod 500 /home/rebootusr/reboot.sh

Аналогично создаем пользователя для выключения, меняя только имя, пароль, домашний каталог, название скрипта и команды в скрипте.

Содержимое скрипта для отключения питания poweroff.sh:

#!/bin/sh

echo "Power off"
sudo /sbin/shutdown -hP now

Настройка рабочего места оператора

Для Windows понадобится утилита plink, обычно она идет вместе с ssh-клиентом PuTTY. В каталоге с ней создаем два bat-файла следующего содержания.
rebootsrv.bat:
plink -ssh -P 22 -l rebootusr -pw rebootpass 192.168.0.40
pwroffsrv.bat:
plink -ssh -P 22 -l pwroffusr -pw pwroffpass 192.168.0.40

где вместо rebootusr и pwroffusr надо подставить имена пользователей для удаленной перезагрузки и отключения питания соответственно, вместо rebootpass и pwroffpass — заданные пароли, а вместо 192.168.0.40 настоящий адрес удаленного компьютера.

Источники

1. sudo [Копия]
2. Как перезагрузить компьютер без прав root [Копия]

Заметка в PDF