From f38b7f6939b8d88291933a05eb1df94dad8fce12 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Tue, 31 Jul 2018 17:10:16 +0200 Subject: [PATCH 1/3] Check for apparmor, and if system provides it, change the profile before serving clients. This allows for more fine-grained control in apparmor, where we first allow the process to bind and chroot and setuidgid, and deny all those privileges afterwards. --- configure.ac | 1 + src/Makefile.am | 5 ++++- src/thttpd.c | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index be32818..7171c8e 100644 --- a/configure.ac +++ b/configure.ac @@ -16,6 +16,7 @@ AC_PROG_AR AC_CHECK_LIB(crypt, crypt) AC_CHECK_LIB(rt, clock_gettime) AC_CHECK_LIB(resolv, hstrerror) +PKG_CHECK_MODULES([APPARMOR], [libapparmor], [AC_DEFINE([HAVE_APPARMOR],[1],[Use Apparmor])]) # Checks for header files. AC_CHECK_HEADERS([arpa/inet.h fcntl.h grp.h memory.h netdb.h netinet/in.h osreldate.h paths.h poll.h stdlib.h string.h sys/devpoll.h sys/event.h sys/param.h sys/poll.h sys/socket.h sys/time.h syslog.h unistd.h]) diff --git a/src/Makefile.am b/src/Makefile.am index 7b6ae9f..8934005 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,6 @@ + +AM_CPPFLAGS = $(APPARMOR_CFLAGS) + sbin_PROGRAMS = thttpd thttpd_SOURCES = thttpd.c thttpd.h \ fdwatch.c fdwatch.h \ @@ -6,7 +9,7 @@ thttpd_SOURCES = thttpd.c thttpd.h \ timers.c timers.h \ tdate_parse.c tdate_parse.h \ mime_encodings.h mime_types.h version.h -thttpd_LDADD = libmatch.a +thttpd_LDADD = libmatch.a $(APPARMOR_LIBS) noinst_LIBRARIES = libmatch.a libmatch_a_SOURCES = match.c match.h diff --git a/src/thttpd.c b/src/thttpd.c index ad97188..3509f69 100644 --- a/src/thttpd.c +++ b/src/thttpd.c @@ -59,6 +59,10 @@ #include #include +#ifdef HAVE_APPARMOR +#include +#endif + #ifndef SHUT_WR #define SHUT_WR 1 #endif @@ -714,6 +718,20 @@ main( int argc, char** argv ) "started as root without requesting chroot(), warning only" ); } + /* Drop to another profile after binding to stuff */ +#ifdef HAVE_APPARMOR + if ( aa_is_enabled() ) + { + if( aa_change_profile( "thttpd_confined" ) < 0 ) + { + syslog( + LOG_WARNING, + "could not change the AppArmor profile - %m" ); + perror("aa_change_profile "); + } + } +#endif + /* Initialize our connections table. */ connects = NEW( connecttab, max_connects ); if ( connects == (connecttab*) 0 ) From 7f9625b20e308046c16a3a5c35d57c60cfdadd0e Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Tue, 31 Jul 2018 18:17:12 +0200 Subject: [PATCH 2/3] Add an apparmor profile for thttpd --- dist/apparmor/usr.sbin.thttpd | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 dist/apparmor/usr.sbin.thttpd diff --git a/dist/apparmor/usr.sbin.thttpd b/dist/apparmor/usr.sbin.thttpd new file mode 100644 index 0000000..c01c15d --- /dev/null +++ b/dist/apparmor/usr.sbin.thttpd @@ -0,0 +1,30 @@ +include +include +include +include +include + +/usr/sbin/thttpd { + include + include + include + include + + capability setuid setgid, + capability sys_chroot, + capability fsetid chown fowner dac_override, + + /etc/thttpd/thttpd.conf r, + /var/log/thttpd.log rw, + /run/thttpd.pid rw, + /run/ rw, + change_profile -> thttpd_confined, + + profile ^thttpd_confined { + /var/www/** rpx, + /var/log/thttpd.log w, + } + +} + + From 116483f4a07caec4be04fd817e345ebe9ff5c5e9 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Tue, 31 Jul 2018 18:33:09 +0200 Subject: [PATCH 3/3] Add a conditional flag for building with AppArmor support --- configure.ac | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 7171c8e..f356fca 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,12 @@ AC_PROG_AR AC_CHECK_LIB(crypt, crypt) AC_CHECK_LIB(rt, clock_gettime) AC_CHECK_LIB(resolv, hstrerror) -PKG_CHECK_MODULES([APPARMOR], [libapparmor], [AC_DEFINE([HAVE_APPARMOR],[1],[Use Apparmor])]) + +# Apparmor +AC_ARG_WITH([apparmor], AS_HELP_STRING([--with-apparmor], [Build with support for AppArmor])) +AS_IF([test "x$with_apparmor" = "xyes"], [ + PKG_CHECK_MODULES([APPARMOR], [libapparmor], [AC_DEFINE([HAVE_APPARMOR],[1],[Use Apparmor])]) +]) # Checks for header files. AC_CHECK_HEADERS([arpa/inet.h fcntl.h grp.h memory.h netdb.h netinet/in.h osreldate.h paths.h poll.h stdlib.h string.h sys/devpoll.h sys/event.h sys/param.h sys/poll.h sys/socket.h sys/time.h syslog.h unistd.h])