Веб-сервер BASH на порту 80 без постоянного запуска от имени пользователя root

Я создаю очень маленький http-сервер для управления устройством на основе raspberry pi из браузера, используя это в качестве отправной точки: http://paulbuchheit.blogspot.com/2007/04/webserver-in-bash.html

Суть его заключается в следующем:

#!/bin/bash

RESPONSE=/tmp/webresp
[ -p $RESPONSE ] || mkfifo $RESPONSE

while true ; do
    ( cat $RESPONSE ) | nc -l -p 8080 | (
    REQUEST=`while read L && [ " " "<" "$L" ] ; do echo "$L" ; done`
    REQ="`echo \"$REQUEST\" | head -n 1`"

    echo "[ `date '+%Y-%m-%d %H:%M:%S'` ] $REQ" >>/var/log/http-access.log

    if [[ $REQ =~ ^GET\ /a[\ \/\#?] ]]; then
        # ...
        RESP="<p>You are at A</p><p><a href='/'>Home</a></p>"
    elif [[ $REQ =~ ^GET\ /b[\ \/\#?] ]]; then
        # ...
        RESP="<p>You are at B</p><p><a href='/'>Home</a></p>"
    elif [[ $REQ =~ ^GET\ /c[\ \/\#?] ]]; then
        # ...
        RESP="<p>You are at C</p><p><a href='/'>Home</a></p>"
    else 
        read -r -d '' RESP <<'HTMLDOC'
        <h3>Home</h3>
        <p><a href='/a'>A</a></p>
        <p><a href='/b'>B</a></p>
        <p><a href='/c'>C</a></p>
HTMLDOC

    fi

    cat >$RESPONSE <<EOF
HTTP/1.0 200 OK
Cache-Control: private
Content-Type: text/html
Server: bash/2.0
Connection: Close
Content-Length: ${#RESP}

$RESP
EOF
    )
done

Он отлично работает, за исключением того, что если я хочу запустить сервер на порту 80, мне нужно выполнить sudo. Я думаю, что это, вероятно, плохая идея - постоянно запускать сервер с повышенными привилегиями. Как я могу отключить sudo после того, как он начнет прослушивать порт 80? Похоже, что команда nc перезапускается при каждом запросе.

Да, я знаю, что могу запустить «настоящий» легкий веб-сервер, но я хочу, чтобы объем памяти был как можно меньше, и я решил, что bash уже работает. Кроме того, я хотел бы, чтобы установка была ограничена добавлением нескольких файлов .sh и запуском одного с файлом ~/.config/autostart/autorun.desktop.


person Mike    schedule 17.03.2013    source источник
comment
Я думаю, что это, вероятно, плохая идея - постоянно запускать сервер с повышенными привилегиями. - уже довольно плохая идея создать свой собственный веб-сервер. Делать это в bash... хорошо для экспериментов с игрушками, но не более того.   -  person Mat    schedule 17.03.2013
comment
nginx или Простой HTTP-сервер Python (даже для простого варианта использования) может подойти здесь лучше. Они не такие ресурсоемкие, как Apache, но меньше головной боли, чем делать это вручную в Bash :)   -  person Nick Tomlin    schedule 17.03.2013


Ответы (2)


Проблема

Вы не можете отказаться от привилегий в сценариях Bash так, как вы думаете. Однако на самом деле вашему сценарию не нужны привилегии root; только netcat требует их для привязки к привилегированному порту.

Решение

Запустите скрипт от имени непривилегированного пользователя и замените nc -l -p 8080 на sudo nc -l -p 80. Это ограничит привилегии суперпользователя процессом netcat, а не предоставит их всему сценарию.

person Todd A. Jacobs    schedule 17.03.2013

Все порты ниже 1024 зарезервированы для суперпользователя (см. здесь). Пока вы запускаете сервер на другом порту, который еще не используется, все в порядке.

person michaelmeyer    schedule 17.03.2013