[ubuntu-hardened] apache2 and hardening flags: hardening-wrapper and buildflags.mk

Robie Basak robie.basak at ubuntu.com
Mon Jan 6 17:52:26 UTC 2014


I'm preparing a merge for apache against Debian apache2 2.4.7-1. Ubuntu is
currently at 2.4.6-2ubuntu4 in Trusty.

I noticed that the PIE hardening delta no longer applies cleanly. I've attached
the previous PIE hardening delta (split out from the rest of the Ubuntu delta)
and the debian/rules file from 2.4.7-1.

I thought this would be an opportunity to rework the Ubuntu hardening delta in
apache2 to the minimal best way. But I've ended up with more questions than
answers. It seems to be that I can just drop the delta entirely, but I'm
concerned that I don't regress it.

I've read https://wiki.ubuntu.com/Security/HardeningWrapper and
https://wiki.debian.org/Hardening but I'm not quite clear on where to from
here.

Questions and observations:

• https://wiki.debian.org/Hardening specifies DPKG_EXPORT_BUILDFLAGS = 1 but
this isn't used in 2.4.7-1, though it does include
/usr/share/dpkg/buildflags.mk. Is this still necessary, and if so then does
Debian need this too?

• 2.4.7-1 uses export DEB_BUILD_MAINT_OPTIONS=hardening=+bindnow. What about
PIE? Do we want hardening=+all in Ubuntu instead?

• 2.4.6-2ubuntu4 uses hardnening-wrapper. Is this superfluous, given that
2.4.7-1 uses buildflags.mk? Can I drop the use of hardening-wrapper?

• I used hardening-check to verify the resulting binaries built without our
previous Ubuntu hardening delta. Results below. Does this mean that just
dropping the Ubuntu delta for hardening is sufficient, as all hardening is now
done by default through buildflags.mk, which Debian uses?

• Given that we now have dep8 testing capability, should we have dep8 tests
that run hardening-check to prevent hardening regressions? If so, can we
standardise on how this should be done?

• Is hardening-check sufficient on its own to detect regressions, or are there
other hardening flags that might be missed or regressed that hardening-check
does not detect?

• So what's the current best practice in Ubuntu for building hardened packages
that use buildflags.mk and thus do not need hardening-wrapper?

>From my latest merge in progress, which does not apply the previous Ubuntu
hardening delta at all:

# hardening-check /usr/sbin/apache2
/usr/sbin/apache2:
 Position Independent Executable: yes
 Stack protected: yes
 Fortify Source functions: yes (some protected functions found)
 Read-only relocations: yes
 Immediate binding: yes

# hardening-check /usr/lib/apache2/modules/mod_dav.so
/usr/lib/apache2/modules/mod_dav.so:
 Position Independent Executable: no, regular shared library (ignored)
 Stack protected: yes
 Fortify Source functions: no, only unprotected functions found!
 Read-only relocations: yes
 Immediate binding: yes

>From 2.4.6-2ubuntu4:

# hardening-check /usr/sbin/apache2
/usr/sbin/apache2:
 Position Independent Executable: yes
 Stack protected: yes
 Fortify Source functions: yes (some protected functions found)
 Read-only relocations: yes
 Immediate binding: yes

# hardening-check /usr/lib/apache2/modules/mod_dav.so
/usr/lib/apache2/modules/mod_dav.so:
 Position Independent Executable: no, regular shared library (ignored)
 Stack protected: yes
 Fortify Source functions: no, only unprotected functions found!
 Read-only relocations: yes
 Immediate binding: yes

Thanks,

Robie
-------------- next part --------------
#!/usr/bin/make -f
# -*- makefile -*-

DEB_BUILD_ARCH_OS    ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS)

# Uncomment this to turn on verbose mode.
# export DH_VERBOSE=1

export DEB_BUILD_MAINT_OPTIONS=hardening=+bindnow
include /usr/share/dpkg/buildflags.mk

LSB_RELEASE := $(shell lsb_release -i -s)
SERVER_VERSION := $(shell dpkg-parsechangelog | perl -ne 'print $$1 if m/Version:\s*([\d\.]+)/')
DEBIAN_VERSION := $(shell dpkg-parsechangelog | perl -ne 'print $$1 if m/Version:\s*(.+)/')
MODULE_DIR := /usr/lib/apache2/modules/
API = $(shell perl -ne 'print $$1 if m/define\s+MODULE_MAGIC_NUMBER_MAJOR\s+?(.*)$$/' < include/ap_mmn.h)
AP2_CFLAGS = -pipe $(CFLAGS)
AP2_LDFLAGS = -Wl,--as-needed $(LDFLAGS)
AP2_CPPFLAGS = -DPLATFORM='\"$(LSB_RELEASE)\"' $(CPPFLAGS)
AP2_LTFLAGS = --no-silent


support/suexec-custom.c: support/suexec.c debian/patches/suexec-custom.patch
	cp support/suexec.c support/suexec-custom.c
	patch -p1 -i debian/patches/suexec-custom.patch

prebuild-checks:
	ERRS="" ;\
	for a in $$(find debian/config-dir/ -type f) ; do \
		t="$$a.$$$$" ;\
		unexpand < "$$a" > "$$t" ;\
		cmp -s "$$a" "$$t" || ERRS="$$ERRS $$a" ;\
		rm "$$t" ;\
	done ;\
	if [ -n "$$ERRS" ] ; then \
		echo 'ERROR: The following files contain spaces instead of tabs. Run through unexpand!' ;\
		ls -1 $$ERRS ;\
		false ;\
	fi

clean-config-vars:
	# Clean up config_vars.mk
	# FIXME: Maybe someone could document here why we actually need to
	# cleanup some stuff here
	perl ./debian/clean_config_vars '$(AP2_CFLAGS)' '$(AP2_CPPFLAGS)' '$(AP2_LDFLAGS)'

%: %.in
	sed 's#__SERVER_VERSION__#$(SERVER_VERSION)#; s#__MODULE_DIR__#$(MODULE_DIR)#; s#__API__#$(API)#;' $< > $@
	chmod `/usr/bin/stat -c '%a' "$<"` $@

prepare-scripts: debian/a2query debian/debhelper/dh_apache2
	(grep -s -v apache2:API debian/apache2-bin.substvars; echo apache2:API=apache2-api-$(API)) > debian/apache2-bin.substvars.new
	mv debian/apache2-bin.substvars.new debian/apache2-bin.substvars

generate-maintainer-scripts:
	set -e ; \
	for type in custom pristine ; do \
		for f in postinst preinst prerm links dirs lintian-overrides postrm; do \
			if [ -e debian/apache2-suexec.$$f.in ] ; then \
				perl -pe "s{__TYPE__}{$$type}g" < debian/apache2-suexec.$$f.in > debian/apache2-suexec-$$type.$$f ;\
				chmod `/usr/bin/stat -c '%a' "debian/apache2-suexec.$$f.in"` debian/apache2-suexec-$$type.$$f ;\
			fi ;\
		done ;\
	done
	set -e ; \
	for type in worker itk prefork event ; do \
		for f in postinst preinst prerm links dirs lintian-overrides postrm; do \
			if [ -e debian/apache2-mpm.$$f.in ] ; then \
				perl -pe "s{__TYPE__}{$$type}g" < debian/apache2-mpm.$$f.in > debian/apache2-mpm-$$type.$$f ;\
				chmod `/usr/bin/stat -c '%a' "debian/apache2-mpm.$$f.in"` debian/apache2-mpm-$$type.$$f ;\
			fi ;\
		done ;\
	done


clean build build-arch build-indep binary binary-arch binary-indep: %:
	dh $@ --parallel --with autotools_dev

override_dh_auto_configure: generate-maintainer-scripts prebuild-checks support/suexec-custom.c
	./configure --enable-layout=Debian --enable-so --with-program-name=apache2 \
		--enable-suexec --with-suexec-caller=www-data \
		--with-suexec-bin=/usr/lib/apache2/suexec --with-suexec-docroot=/var/www \
		--with-suexec-userdir=public_html --with-suexec-logfile=/var/log/apache2/suexec.log \
		--with-suexec-uidmin=100 --enable-suexec=shared --enable-log-config=static \
		--with-apr=/usr/bin/apr-1-config --with-apr-util=/usr/bin/apu-1-config \
		--with-pcre=yes \
		--enable-pie \
		--enable-mpms-shared=all \
		--enable-mods-shared="all cgi" \
		--enable-mods-static="unixd logio watchdog version" \
		CFLAGS="$(AP2_CFLAGS)" CPPFLAGS="$(AP2_CPPFLAGS)" LDFLAGS="$(AP2_LDFLAGS)" \
		LTFLAGS="$(AP2_LTFLAGS)"


override_dh_install: clean-config-vars prepare-scripts
	dh_install --list-missing

override_dh_fixperms-arch:
	# standard suexec
	chmod 4754 debian/apache2-suexec-pristine/usr/lib/apache2/suexec-pristine
	chgrp www-data debian/apache2-suexec-pristine/usr/lib/apache2/suexec-pristine
	# configurable suexec
	chmod 4754 debian/apache2-suexec-custom/usr/lib/apache2/suexec-custom
	chgrp www-data debian/apache2-suexec-custom/usr/lib/apache2/suexec-custom
	dh_fixperms -a -Xusr/lib/apache2/suexec-custom -Xusr/lib/apache2/suexec-pristine
	chown -R www-data:www-data debian/apache2/var/cache/apache2/mod_cache_disk
	chown root:adm debian/apache2/var/log/apache2
	chmod o-rx debian/apache2/var/log/apache2

override_dh_fixperms-indep:
	dh_fixperms -i

override_dh_installinit:
	dh_installinit --restart-after-upgrade --error-handler=true -- defaults 91 09

override_dh_installdocs-indep:
	# TODO: So, did anyone check convert_docs needs an update? ;)
	perl debian/convert_docs debian/apache2-doc/usr/share/doc/apache2-doc/manual
	dh_installdocs -i

override_dh_installdocs-arch:
	dh_installdocs --link-doc=apache2 -papache2 -papache2-dbg \
		-papache2-mpm-worker -papache2-mpm-prefork -papache2-mpm-event \
		-papache2-mpm-itk
	dh_installdocs --link-doc=apache2-bin -papache2.2-bin -plibapache2-mod-proxy-html \
	    -plibapache2-mod-macro
	dh_installdocs --link-doc=apache2-suexec-pristine -papache2-suexec
	dh_installdocs -a

override_dh_installchangelogs:
	# Do not install changelogs for transitional packages and the -data
	# package not to trash the disk at the installation site. Together with
	# dh_installdocs this means that changelogs are installed in a few
	# packages only.
	dh_installchangelogs -Napache2-suexec -Napache2-mpm-worker \
		-Napache2-mpm-prefork -Napache2-mpm-event -Napache2-mpm-itk \
		-Napache2-data -Nlibapache2-mod-proxy-html -Napache2.2-bin \
		-Nlibapache2-mod-macro

override_dh_installman:
	mv debian/tmp/usr/share/man/man8/suexec.8 debian/tmp/usr/share/man/man8/suexec-pristine.8
	pod2man debian/debhelper/dh_apache2 > debian/manpages/dh_apache2.1
	pod2man debian/a2query.in > debian/manpages/a2query.8
	dh_installman

override_dh_strip:
	dh_strip --dbg-package=apache2-dbg

override_dh_auto_install:
	dh_auto_install -- -j1

override_dh_builddeb:
	dh_builddeb -- -Zxz

override_dh_auto_clean:
	dh_auto_clean

override_dh_gencontrol:
	dh_gencontrol  -p libapache2-mod-proxy-html -- -v1:$(DEBIAN_VERSION)
	dh_gencontrol  -p libapache2-mod-macro -- -v1:$(DEBIAN_VERSION)
	dh_gencontrol --remaining-packages

.PHONY: generate-maintainer-scripts clean-config-vars prepare-scripts prebuild-checks
.PHONY: clean build build-arch build-indep binary binary-arch binary-indep
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-debian-control-rules-Enable-PIE-hardening.patch
Type: text/x-diff
Size: 2010 bytes
Desc: not available
URL: <https://lists.ubuntu.com/archives/ubuntu-hardened/attachments/20140106/3c3277bc/attachment.patch>


More information about the ubuntu-hardened mailing list