2012-05-11 19 views
5

Napisałem własny serwer WWW w C. Jak mogę powiązać go z portem 80 bez bycia rootem, aby zabezpieczenia nie zostały naruszone (przepełnienia bufora itp.)?Powiąż serwer WWW z portem 80 bez korzenia

Czy powinienem po prostu przekazać ruch z innego "stabilnego" serwera działającego na porcie 80?

Odpowiedz

5

Korzystanie z przekazywania proxy jest rzeczywiście najłatwiejszym i najbardziej zalecanym rozwiązaniem. Ma także tę zaletę, że filtruje okropnie nieprawidłowe żądania, zanim dotrze do twojego samouka serwera.
Jeśli twoja aplikacja używa adresu IP użytkownika do czegoś, pamiętaj, aby pobrać go z dowolnego nagłówka, którego używa twój serwer sieciowy (X-Client-IP itd.). Możesz to jednak zrobić tylko w przypadku żądań, które naprawdę pochodzą z Twojego serwera internetowego, w przeciwnym razie użytkownicy mogą podszyć swój adres IP. Możesz to zrobić, sprawdzając, czy żądanie pochodzi z twojego adresu IP i tylko sprawdzasz nagłówek w tym przypadku lub po prostu przypisuj powiązanie aplikacji do localhost.

Innym rozwiązaniem byłoby przyznanie temu programowi zdolności CAP_NET_BIND_SERVICE. To wymaga, aby root używał setcap cap_net_bind_service=ep /path/to/the/executable - ponieważ flaga jest przechowywana w atrybucie systemu plików, zostanie utracona podczas kopiowania pliku do innego systemu lub rekompilacji aplikacji.

Oczywiście można również ustawić program jako root, a następnie przełączyć się do nieuprzywilejowanego użytkownika zaraz po wywołaniu bind(). Jednak w zależności od tego, jak działa twój program i co robi, może to nie być dobry pomysł - na przykład, jeśli z jakiegoś powodu musi zamknąć i ponownie otworzyć gniazdo nasłuchu, konieczne będzie pełne ponowne uruchomienie procesu.

+0

+1 dla możliwości, chociaż nie są one przenośne dla żadnego innego systemu UNIX. – dwalter

+0

Większość osób korzysta z Linuksa. I chyba * BSD ma coś podobnego. – ThiefMaster

2

Jeśli chcesz powiązać swój serwer z portem 80, musisz to zrobić jako root, a następnie zrzucić uprawnienia.

bind(sockfd, addr, addrlen); 
/* process is running as root, drop privileges after bind*/ 
if (setgid(groupid) != 0) 
    errx(1, "setgid: Unable to drop group privileges: %s", strerror(errno)); 
if (setuid(userid) != 0) 
    errx(1, "setuid: Unable to drop user privileges: %S", strerror(errno)); 

Jak mogę powiązać go z portu 80, nie będąc korzeń tak, że bezpieczeństwo nie jest wykradzenie (przepełnienia bufora itp)

nie działające jako korzeń robi nie uczynić swoje system bardziej bezpieczny, po prostu dodaje kolejną warstwę do wykorzystania. Więc zamiast myśleć o tym, jak nie uruchomić jako root, upewnij się, że nie korzystają z żadnych znanych-niepewny funkcje jak strcpy(), sprintf() itp ale zamiast używać strncpy(), snprintf() itp

+0

Należy wspomnieć, że 'errx' jest niestandardową funkcją dostępną w wielu systemach pochodnych BSD lub kompatybilnych. Jeśli potrzebujesz jego funkcjonalności (która jest trywialną funkcją 2-3 linii) powinieneś napisać własną, aby nie skrzywdzić przenośności twojego programu. –

3

alternatywą do wywoływania bind() jako root, a następnie upuszczenie uprawnień, ma mieć proces główny, który tworzy gniazdo i wiąże go, a następnie przekazuje gniazdo nasłuchiwania do nieuprzywilejowanego procesu przez połączenie z gniazdami w domenie systemu UNIX za pomocą komunikatu SCM_RIGHTS.

2

Tak jak wiesz, wszystkie porty poniżej 1024 w systemie Unix wymagają uprawnień root'a do otwarcia. W systemie Unix nie chcesz, aby jak najmniejsza liczba aplikacji działała z uprawnieniami roota. Jest i zawsze będzie dużym zagrożeniem dla bezpieczeństwa.

Alternatywą jest użycie iptables do przekierowania ruchu portu 80 do bardziej nieszkodliwego portu, takiego jak 8080. Oto description, jak go skonfigurować.

Iptables nie jest najprostszym narzędziem do konfiguracji, ale po opanowaniu go jest bardzo użyteczny i wydajny (i bezpieczny).

+0

Dla mnie to działało tylko na tabeli NAT w łańcuchu OUTPUT. Ale jest to najprostsza odpowiedź na to pytanie. – nus

0

Pracowałem nad tym problemem od dłuższego czasu i doszła do wniosku, że systemd + iptables jest rozwiązaniem, a nie możliwości, jak elaborated in great detail here.

Powiązane problemy