Cgi-bin скрипт за котиране на файл, собственост на потребител

Използвам Ubuntu сървър и имам cgi-bin скрипт, който прави следното. . .

#!/bin/bash
echo Content-type: text/plain
echo ""
cat /home/user/.program/logs/file.log | tail -400  | col -b > /tmp/o.txt
cat /tmp/o.txt

Сега, ако стартирам този скрипт с I am "su", скриптът запълва o.txt и след това host.com/cgi-bin/script се изпълнява, но се показва само до точката, в която последно съм го стартирал от CLI

Моят регистър за грешки на apache показва грешки „отказано разрешение“. Знам, че потребителят apache, под който работи, по някакъв начин не може да хване този файл. Опитах да използвам chown без резултат. Тъй като този файл е в потребителска директория, кой е най-добрият начин да го дублирате или да го свържете символно или какво?

Дори обмислях да стартирам скрипта като root в crontab, за да "актуализирам" файла в /tmp/, но това не работи за мен. Как някой с опит с cgi-bin ще се справи с достъпа до файл в потребителска директория?


person Matt3324    schedule 13.03.2014    source източник
comment
Изпълнението на tail -n 400 logfile | sudo -u www-data tee /var/www/tail.txt >/dev/null веднъж на минута би премахнало необходимостта от CGI скрипт на първо място.   -  person tripleee    schedule 13.03.2014


Отговори (2)


Потребителят на Apache www-data няма достъп за запис във временен файл, собственост на друг потребител.

Но в този конкретен случай не е необходим временен файл.

tail -n 400 logfile | col -b

Въпреки това, ако Apache работи в ограничен chroot, той също няма достъп до /home.

Регистрационният файл трябва да бъде chmod o+r и всички директории, водещи до него, трябва да бъдат chmod o+x. Уверете се, че разбирате последиците от това! Ако потребителят има причина да иска да предотврати достъпа до междинна директория, достъпът за четене на самия файл няма да е достатъчен. (Да направиш нещо да има www-data като собственик на групата е възможно на теория, но непрактично и безсмислено, тъй като всеки, който намери CGI скрипта, така или иначе ще има достъп до файла.)

По-общо, ако имате нужда от временен файл, простото решение (дори не заобиколно решение) е да генерирате уникално име на временен файл и да го премахнете след това.

temp=$(mktemp -t cgi.XXXXXXXX) || exit $?
trap 'rm -f "$temp"' 0
trap 'exit 127' 1 2 15

tail -n 400 logfile | col -b >"$temp"

Първият trap гарантира, че файлът се премахва, когато скриптът приключи. Вторият гарантира, че първият trap се изпълнява, ако скриптът бъде прекъснат или убит.

person tripleee    schedule 13.03.2014
comment
Опитах се да използвам само опашка и ето новата грешка в моя регистър на грешки на apache опашка: не мога да отворя `/home/user/.program/log' за четене: Разрешението е отказано - person Matt3324; 13.03.2014
comment
Числата на сигнала в trap трябва правилно да бъдат символични. Твърде стари и мързеливи, за да ги потърся. EXIT и ... нещо и HUP и INT предполагам? - person tripleee; 13.03.2014
comment
Потребителят знае ли и одобрява ли това? Тогава получаването на разрешения и/или преместването на файла на по-достъпно място трябва да е лесен въпрос. - person tripleee; 13.03.2014
comment
да, потребителят е моят потребител, файлът е журнал, създаден от програма в потребителската област, която не трябва да се изпълнява като root. Има ли лесен начин да копирате този файл на живо, докато расте до местоположение, до което Apache има достъп? Мислех за crontab, но може би знаете по-лесен начин. - person Matt3324; 13.03.2014
comment
Да имате файла на здраво място като начало вероятно е по-добре. Обърнете внимание на скорошната актуализация относно: разрешения за директории. - person tripleee; 13.03.2014
comment
Ти го направи, нямам представа какво правят o+r и o+x, но ще прочета за това. Мислех, че наличието на chmod 777 ще е достатъчно, но предполагам, че не. - person Matt3324; 13.03.2014
comment
Знаете, че произвежда нещо сега, но всъщност е стара част от дневника и когато дневникът се актуализира и опресня страницата, страницата остава същата. Нямам идея. - person Matt3324; 13.03.2014
comment
Аз съм единственият потребител на сървъра, само root и моят потребител, chmod 777 все още ли е лоша идея? - person Matt3324; 13.03.2014
comment
Добре, така че това всъщност работи, но само веднъж, след това всеки път, когато отида да актуализирам страницата, зарежда само оригиналната котка на дневника, няма да повтори процеса. Нямам идея защо. - person Matt3324; 13.03.2014

Бих бил склонен да променя програмата, която създава регистрационния файл на първо място, и да го запиша на някое място, видимо за Apache - може би чрез символни връзки.

Например:

ln -s /var/www/cgi-bin/logs /home/user/.program/logs

Така че вашата програма продължава да пише в /home/user/.program/logs, но данните всъщност попадат в /var/www/cgi-bin/logs, където Apache може да ги прочете.

person Mark Setchell    schedule 13.03.2014
comment
Ако крайната дестинация не е разрешена, Apache също няма да може да премине през символната връзка. В противен случай би било тривиално да получите достъп до неща, от които сте блокирани! - person tripleee; 13.03.2014
comment
Apache не трябва да използва символната връзка. Оригиналната програма на OP пише чрез символната връзка, Apache чете истинския файл. Съжалявам, имах връзката отзад напред. - person Mark Setchell; 13.03.2014
comment
символните връзки имат смисъл за мен, помислих си, че това може да е начинът, пуснах equiv на логиката на моята система, но казах, че не успях да създам, файлът съществува. Съжалявам, нямам представа, понякога cgi скриптът се изпълнява между другото. . . Объркан съм. - person Matt3324; 13.03.2014
comment
Трябва да преместите стария файл настрана или да стартирате ln -fs, за да го принудите. Това обаче ще презапише всеки съществуващ дневник. - person tripleee; 13.03.2014