Skip to content

Commit

Permalink
Add apparmor support to further harden the priviledge seperation on L…
Browse files Browse the repository at this point in the history
…inux

in a similar way pledge() is used on OpenBSD. The apparmor config contains
profiles for the different iked processes (parent,ikev2,ca,control).
Each process switches to their respective policy with aa_change_profile()
before calling chroot() and setuid() to drop priviledges.
  • Loading branch information
tobhe committed May 16, 2022
1 parent ccd6831 commit b3b2639
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,9 @@ endif()
if(HAVE_VROUTE OR HAVE_VROUTE_NETLINK)
add_definitions(-DHAVE_VROUTE)
endif()
if(WITH_APPARMOR)
add_definitions(-DWITH_APPARMOR)
endif()

if(ASAN)
message("Using ASAN")
Expand Down
86 changes: 86 additions & 0 deletions contrib/iked.apparmor
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Last Modified: Thu Apr 14 17:48:19 2022
abi <abi/3.0>,

include <tunables/global>

profile iked /usr/sbin/iked {
include <abstractions/base>

capability kill,

# address/route configuration
capability net_admin,
network netlink dgram,

# config file
include <abstractions/nameservice>
/etc/iked.conf r,
/etc/iked/** r,

# switch profile
owner @{PROC}/@{tid}/mounts r,
owner @{PROC}/@{tid}/attr/current w,
change_profile -> iked//ca,
change_profile -> iked//control,
change_profile -> iked//ikev2,

signal (send) peer=iked//ca,
signal (send) peer=iked//control,
signal (send) peer=iked//ikev2,
signal (send) peer=iked//resolvectl,

owner /run/iked.sock w,
network key raw,

/usr/bin/resolvectl cx -> resolvectl,
profile resolvectl {
include <abstractions/base>
include <abstractions/dbus>

signal (receive) peer=iked,

/usr/bin/resolvectl r,
}

profile ca {
include <abstractions/base>

# privsep
capability setuid,
capability setgid,
capability sys_chroot,
signal (receive) peer=iked,

# certs/keys
/etc/iked/** r,
}

profile control {
include <abstractions/base>

# privsep
capability setuid,
capability setgid,
capability sys_chroot,
signal (receive) peer=iked,

# ikectl control sock
network unix raw,
}

profile ikev2 {
include <abstractions/base>

# privsep
capability setuid,
capability setgid,
capability sys_chroot,
signal (receive) peer=iked,

# IKEv2
network inet dgram,
network inet6 dgram,
# PFKEY
network key raw,
}
}
18 changes: 15 additions & 3 deletions iked/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,16 @@ else()
PRIVATE util event crypto ssl compat
)
endif()
target_link_libraries(iked
PRIVATE util event crypto ssl compat iked-shared
)

if(WITH_APPARMOR)
target_link_libraries(iked
PRIVATE util event crypto ssl compat iked-shared apparmor
)
else()
target_link_libraries(iked
PRIVATE util event crypto ssl compat iked-shared
)
endif()

add_custom_command(
OUTPUT parse.c
Expand Down Expand Up @@ -150,6 +157,11 @@ install(FILES ${CMAKE_SOURCE_DIR}/iked.conf
)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/iked.conf.5 DESTINATION ${CMAKE_INSTALL_MANDIR}/man5/)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/iked.8 DESTINATION ${CMAKE_INSTALL_MANDIR}/man8/)
if(WITH_APPARMOR)
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../contrib/iked.apparmor
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/apparmor.d/
RENAME usr.sbin.iked)
endif()
install(DIRECTORY DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/iked/ca)
install(DIRECTORY DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/iked/certs)
install(DIRECTORY DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/iked/crls)
Expand Down
26 changes: 26 additions & 0 deletions iked/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
#include <sys/socket.h>
#include <sys/wait.h>

#ifdef WITH_APPARMOR
#include <sys/apparmor.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
Expand Down Expand Up @@ -388,6 +392,28 @@ proc_run(struct privsep *ps, struct privsep_proc *p,
fatalx(__func__);
}

#ifdef WITH_APPARMOR
switch(p->p_id) {
case PROC_IKEV2:
if (aa_change_profile("iked//ikev2") == -1)
log_warnx("warning: aa_change_profile"
"(\"iked//ikev2\") failed");
break;
case PROC_CONTROL:
if (aa_change_profile("iked//control") == -1)
log_warnx("warning: aa_change_profile"
"(\"iked//control\") failed");
break;
case PROC_CERT:
if (aa_change_profile("iked//ca") == -1)
log_warnx("warning: aa_change_profile"
"(\"iked//ca\") failed");
break;
default:
break;
}
#endif

/* Change root directory */
if (p->p_chroot != NULL)
root = p->p_chroot;
Expand Down

0 comments on commit b3b2639

Please sign in to comment.