Before start, I install following packages:
# dnf install selinux-policy-devel rpm-build
Let’s start!
I create directory with policy files.
$ mkdir myapp-selinux-0.1
$ cd myapp-selinux-0.1/
Then I create basic SELinux policy, something like this:
$cat myapp.te
policy_module(myapp,1.0)
type myapp_t;
type myapp_exec_t;
init_daemon_domain(myapp_t, myapp_exec_t)
# Grant myapp_t the signal privilege
allow myapp_t self:process { signal };
$ cat myapp.fc
/sbin/myapp -- gen_context(system_u:object_r:myapp_exec_t,s0)
$ cat myapp.if
##
My app service.
Now, we can see following files in myapp-selinux-0.1 directory:
$ ls
myapp.fc myapp.if myapp.te
We also need Makefile to build this policy:
TARGETS?= myapp
MODULES?=${TARGETS:=.pp.bz2}
all: ${TARGETS:=.pp.bz2}
%.pp.bz2: %.pp
@echo Compressing $^ -\ $@
bzip2 -9 $^
%.pp: %.te
make -f /usr/share/selinux/devel/Makefile $@
clean:
rm -f *~ *.tc *.pp *.pp.bz2
rm -rf tmp
Run:
$ make
This should create following file myapp.pp.bz2.
$ ls
Makefile myapp.fc myapp.if myapp.pp.bz2 myapp.te tmp
Create archive from directory with SELinux policy files:
$ cd ..
$ tar -czf myapp-selinux-0.1.tar.gz myapp-selinux-0.1/
Create spec file for rpm package.
%global selinuxtype targeted
%global moduletype services
%global modulenames myapp
# Usage: _format var format
# Expand 'modulenames' into various formats as needed
# Format must contain '$x' somewhere to do anything useful
%global _format() export %1=""; for x in %{modulenames}; do %1+=%2; %1+=" "; done;
# Relabel files
%global relabel_files() \ # ADD files in *.fc file
# Version of distribution SELinux policy package
%global selinux_policyver 3.13.1-128.6.fc22
# Package information
Name: myapp-selinux
Version: 0.1
Release: 1%{?dist}
License: GPLv2
Group: System Environment/Base
Summary: SELinux Policies for Docker
BuildArch: noarch
URL: https://HOSTNAME
Requires(post): selinux-policy-base >= %{selinux_policyver}, selinux-policy-targeted >= %{selinux_policyver}, policycoreutils, policycoreutils-python libselinux-utils
BuildRequires: selinux-policy selinux-policy-devel
Source: %{name}-%{version}.tar.gz
%description
SELinux policy modules for use with myapp
%prep
%setup -q
%build
make SHARE="%{_datadir}" TARGETS="%{modulenames}"
%install
# Install SELinux interfaces
%_format INTERFACES $x.if
install -d %{buildroot}%{_datadir}/selinux/devel/include/%{moduletype}
install -p -m 644 $INTERFACES \
%{buildroot}%{_datadir}/selinux/devel/include/%{moduletype}
# Install policy modules
%_format MODULES $x.pp.bz2
install -d %{buildroot}%{_datadir}/selinux/packages
install -m 0644 $MODULES \
%{buildroot}%{_datadir}/selinux/packages
%post
#
# Install all modules in a single transaction
#
%_format MODULES %{_datadir}/selinux/packages/$x.pp.bz2
%{_sbindir}/semodule -n -s %{selinuxtype} -i $MODULES
if %{_sbindir}/selinuxenabled ; then
%{_sbindir}/load_policy
%relabel_files
fi
%postun
if [ $1 -eq 0 ]; then
%{_sbindir}/semodule -n -r %{modulenames} &> /dev/null || :
if %{_sbindir}/selinuxenabled ; then
%{_sbindir}/load_policy
%relabel_files
fi
fi
%files
%defattr(-,root,root,0755)
%attr(0644,root,root) %{_datadir}/selinux/packages/*.pp.bz2
%attr(0644,root,root) %{_datadir}/selinux/devel/include/%{moduletype}/*.if
%changelog
* Fri Mar 06 2015 Lukas Vrabec <lvrabec@redhat.com> - 0.1.0-1
- First Build
Note: If you create custom SELinux policy that is included in distribution SELinux policy package use following spec file:
%global selinuxtype targeted
%global moduletype services
%global modulenames myapp
# Usage: _format var format
# Expand 'modulenames' into various formats as needed
# Format must contain '$x' somewhere to do anything useful
%global _format() export %1=""; for x in %{modulenames}; do %1+=%2; %1+=" "; done;
# Relabel files
%global relabel_files() \ # ADD files in *.fc file
# Version of distribution SELinux policy package
%global selinux_policyver 3.13.1-128.6.fc22
# Package information
Name: myapp-selinux
Version: 0.1.0
Release: 1%{?dist}
License: GPLv2
Group: System Environment/Base
Summary: SELinux Policies for Docker
BuildArch: noarch
URL: https://HOSTNAME
Requires(post): selinux-policy-base >= %{selinux_policyver}, selinux-policy-targeted >= %{selinux_policyver}, policycoreutils, policycoreutils-python libselinux-utils
BuildRequires: selinux-policy selinux-policy-devel
Source: %{name}-%{version}.tar.gz
%description
SELinux policy modules for use with myapp
%prep
%setup -q
%build
make SHARE="%{_datadir}" TARGETS="%{modulenames}"
%install
# Install policy modules
%_format MODULES $x.pp.bz2
install -d %{buildroot}%{_datadir}/selinux/packages
install -m 0644 $MODULES \
%{buildroot}%{_datadir}/selinux/packages
%post
#
# Install all modules in a single transaction
#
%_format MODULES %{_datadir}/selinux/packages/$x.pp.bz2
%{_sbindir}/semodule -n -s %{selinuxtype} -i $MODULES
if %{_sbindir}/selinuxenabled ; then
%{_sbindir}/load_policy
%relabel_files
fi
%postun
if [ $1 -eq 0 ]; then
%{_sbindir}/semodule -n -r %{modulenames} &> /dev/null || :
if %{_sbindir}/selinuxenabled ; then
%{_sbindir}/load_policy
%relabel_files
fi
fi
%files
%defattr(-,root,root,0755)
%attr(0644,root,root) %{_datadir}/selinux/packages/*.pp.bz2
%changelog
* Fri Mar 06 2015 Lukas Vrabec <lvrabec@redhat.com> - 0.1.0-1
- First Build
Just change name and add SELinux module name on line 3.
Copy archive with selinux files to ~/rpmbuild/SOURCES like:
$ cp myapp-selinux-0.1.tar.gz ~/rpmbuild/SOURCES/
Finally, run:
$ rpmbuild -ba myapp-selinux.spec
After these steps, you have new rpm package ready for install. Package is stored in:
ls ~/rpmbuild/RPMS/noarch/
This package can be shipped separately or as subpackage. If you have any question or idea, feel free to comment this post.