Простая инструкция по установке 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, краткая инструкция

Запускающий скрипт для tinyproxy

Ставил я не так давно простой и легкий прокси-сервер tinyproxy, и с удивлением не обнаружил в комплекте запускающего (инициализационного) скрипта.
Что это за зверь такой, если кто не знает. Ко многим демонам в Linux в комплекте идет инициализационный скрипт, позволяющий демона запустить, «убить» или перезапустить из консоли командой вида daemonname start (stop, restart) без необходимости вручную отлавливать идентификатор процесса, убивать его командой kill и проверять, завершен ли процесс (или наоборот, стартовал ли он). К squid, например, такой скрипт идет, называется (в Slackware) rc.squid и лежит в /etc/rc.d, а к tinyproxy в комплекте не шло, но написать его оказалось не так и сложно.
Итак, скрипт будет получать из командной строки единственный параметр с командой:
start — запускать прокси-сервер
stop — останавливать его
restart — перезапускать (останавливать, а после остановки запускать)
status — отображать, запущен или не запущен прокси.

Определяем основные переменные
#!/bin/bash

PIDFILE="/home/provproxy/tinyproxy.pid"
TINYPROXYCMD="/usr/sbin/tinyproxy"
PIDVAL=0
WTIMEOUT=30
OK=0

CH_S[0]='-' #pseudographic items
CH_S[1]='/'
CH_S[2]='|'
CH_S[3]='\'
ITEM_ARR=0 #current item counter

PIDFILE — переменная, в которой указан PID-файл, файл, содержащий идентификатор основного процесса прокси-сервера. Tinyproxy при запуске создает сразу несколько процессов, позволяющих ему распараллеливать свою внутреннюю работу. Минимальное и максимальное число таких процессов задается в конфигурационном файле /etc/tinyproxy.conf параметрами MinSpareServers и MaxSpareServers, а процесс, идентификатор которого указан в PID-файле основной, управляющий. Ему можно послать сигнал, например, командой kill, и все остальные процессы тоже завершатся. Местоположение PID-файла также указывается в файле /etc/tinyproxy.conf в параметре PidFile. Конечно, правильнее читать сам конфигурационный файл, и выдергивать значение параметра оттуда, ну да ладно, параметр этот перенастраивается нечасто, посему пусть такое решение останется на моей совести -=^_^-=.
TINYPROXYCMD — путь к исполняемому файлу прокси-сервера
PIDVAL — здесь будет храниться значение PID, полученное из PID-файла.
WTIMEOUT — максимальное время ожидания запуска tinyproxy, или его завершения.
OK — флаг, принимающий значение 1 в случае успешного запуска/завершения, или 0 — в случае неуспеха. Вообще-то, можно и без него обойтись, но мне с ним удобнее и нагляднее.

CH_S[0] - CH_S[3], массив с псевдографическими элементами, для украшательства, отображения хода процесса запуска. Подробности про украшательства тут или тут , и если кому не надо, выбросить лишние команды из скрипта — дело нехитрое. Переменная ITEM_ARR предназначена для тех же целей.

Функции

Далее, определим в скрипте несколько функций.

см. описание функций под катом

Проверка параметров.

Проверять параметры будем при помощи оператора case, после объявления функций.

case "$1" in
    start)
	start_proxy
	;;
    stop)
	stop_proxy
	;;
    restart)
	restart_proxy
	;;
    status)
	status_proxy
	;;
    *)
	echo "Usage: $0 {start|stop|restart|status}"
esac


Если первый параметр, переданный из командной строки start, stop, restart или status — выполняются соответствующие функции, если что-то еще (*) — выводим краткую справку по использованию скрипта. В списке источников в конце заметки есть ссылка на более подробное описание оператора.

Статус процесса

Получается функцией process_status(). Вот ее код:

    #Получаем PID
    if [ -e $PIDFILE ];then #если файл существует
	PIDVAL=`cat $PIDFILE` #читаем PID
	TMPGREP=`ps -p $PIDVAL|grep "tinyproxy" -c` #процесс запущен - 1 иначе 0
	if [ $TMPGREP -ge 1 ];then #процесс запущен
	    return #выходим из функции
	else #pid-файл есть, процесса нет
	    rm $PIDFILE #удаляем pid-файл
	fi
    fi
    PIDVAL=0


Сначала проверяется наличие PID-файла, если он существует, отправляем его содержимое (конструкция «), прочитанное с помощью команды cat в переменную PIDVAL, далее, запрашиваем информацию о процессе (ps) по его PID (ключ -p). Если процесс существует, команда ps отправит на стандартный вывод что-то типа:

PID TTY TIME CMD
2100 ? 00:00:00 tinyproxy

А если процесса не существует:

PID TTY TIME CMD

Далее, этот вывод передается команде grep, которая фильтрует строки с именем искомого процесса (tinyproxy) и подсчитывает их количество (ключ -c). Если строк 1 процесс с данным PID существует, если 0 — процесса нет.
Если PID-файл существует, то в переменной $PIDVAL остается идентификатор процесса и происходит выход из функции

[...]
if [ $TMPGREP -ge 1 ];then #процесс запущен
	    return #выходим из функции

[...]


Если PID-файл существует, а процесс с данным PID не обнаружен, значит в PID-файле указан не тот PID, что, в большинстве случаев, может произойти из-за падения программы (с tinyproxy это случается довольно редко), либо из-за общего системного сбоя вызванного, например, отключением питания. Поэтому стоит PID-файл удалить.
Если процесс не обнаружен, или PID-файл не найден, то происходит выход из всех условных конструкций и переменной $PIDVAL присваивается значение 0
[...]
PIDVAL=0
[...]

Таким образом, если процесс существует, то в переменной $PIDVAL будет присутствовать его идентификатор, если не существует — значение 0.

Примечание о безопасности и стабильности использования PID-файлов
. Конечно, есть более универсальный способ найти процесс не обращаясь к PID-файлу, например, получить список процессов командой ps ax и отgrep’ать его, найдя нужное нам имя, и, если надо, то завершить его командой pkill имя_процесса, и данный способ весьма неплохо будет работать с тем же tinyproxy.
Но tinyproxy — это просто web-прокси сервер, и неизвестно, что произойдет, если применить такой метод, например, к серверу баз данных. Возможно, какие-то транзакции не завершатся, порушится сама база. Поэтому, информации, сохраняемой программами в PID-файлах, стоит доверять. Безопасность их использования и контроль доступа к ним других пользователей должны решаться другими средствами ОС. Посему я не вижу смысла загромождать скрипт дополнительными проверками.
За пояснение благодарю [info]ketmar@ljr

Отображение статуса tinyproxy

Если функция process_status() используется для получения статуса (и PID) процесса для внутренних целей скрипта, то функция status_proxy() выводит информацию пользователю. И хоть она очень проста, но лучше вынести ее отдельно, дабы не смешивать взаимодействие с пользователем со внутренней механикой программы.

Вот код этой функции:

status_proxy()
{
    process_status
    if [ $PIDVAL -eq 0 ]; then
	echo "Tinyproxy not running"
    else
	echo "Tinyproxy running [PID=$PIDVAL]"
    fi
}


Как я и говорил, функция очень проста, сначала вызывается функция process_status, и если в переменной $PIDVAL значение 0, то выводится сообщение о том, что tinyproxy не запущен, иначе, что запущен и дополнительно выводится его PID.

Запуск прокси-сервера

Выполняет его функция start_proxy(). Вот ее код:
см. код и описание функции под катом

ПРИМЕЧАНИЕ:
Если прокси не запускается, то для поиска неисправности удобно запустить прокси-сервер с ключом -d
tinyproxy -d
В таком случае прокси запустится не в виде фонового процесса (демона), а в виде обычного, и выдаст ошибки на консоль. Например, если на файерволе закрыты порты, необходимые серверу, будет выведено сообщение:
tinyproxy: Could not create listening socket.

Остановка прокси-сервера

За остановку прокси-сервера отвечает функция stop_proxy(). Ее код:
см. код и описание функции под катом

Перезагрузка прокси-сервера.
Тут вообще все просто.
1. Запускаем функцию остановки stop_proxy.
2.
Сбрасываем флаг: $OK=0
Выполняем функцию запуска start_proxy

Вот нехитрый код функции restart_proxy():

restart_proxy()
{
    stop_proxy
    OK=0
    start_proxy
}

Скачать скрипт

С Pastebin
С Mega.nz

Список источников

1.Bash. Функции.
2.Возврат значений из функции
3.Оператор case
4.Tinyproxy
5.Коды завершения, имеющие предопределенный смысл