Linux Kernel + grsecurity – my way! 7 May 2012

Krótko i na temat – będzie to art na temat rekompilacji kernela z tym, że po mojemu. Z racji tego, że używam na co dzień dystrybucji Debian, instrukcje i skrypty będą przeznaczone właśnie dla tego distro. Mam nadzieję na stworzenie kompleksowej obsługi instalacji nowego jajka i w miarę zrozumiałej dla wszystkich ;)

Co jest potrzebne?

  • źródła jądra Linuksa
  • patch grsecurity pasujący do pobranego kernela
  • paczki: fakeroot, kernel-package, libncurses5-dev, paxctl, bzip2

Wszystkie operacje wykonujemy jako root:

01 root@srv # apt-get update && apt-get install -y fakeroot kernel-package libncurses5-dev paxctl bzip2
02 root@srv # cd /usr/src
03 root@srv /usr/src # wget http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.3.4.tar.bz2
04 root@srv /usr/src # wget http://grsecurity.net/test/grsecurity-2.9-3.3.4-201204272006.patch
05 root@srv /usr/src # tar -jxf linux-3.3.4.tar.bz2
06 root@srv /usr/src # rm linux; ln -s linux-3.3.4 linux
07 root@srv /usr/src # cd linux
08 root@srv /usr/src/linux # cp /boot/config-`uname -r` .config
09 root@srv /usr/src/linux # patch -p1 < ../grsecurity-2.9-3.3.4-201204272006.patch
10 root@srv /usr/src/linux # make menuconfig

OK, co sie do tej pory stało? Zainstalowaliśmy potrzebne paczki (01) oraz przeszliśmy do katalogu, w którym będzie odbywała sie kompilacja (02). Następnie pobraliśmy źródła kernela oraz patch grsec (03 i 04). Po rozpakowaniu kernela (05) utworzyliśmy link symboliczny jako linux do wypakowanego katalogu linux-3.3.4 (06). Następnie weszliśmy do katalogu linux (07), skopiowaliśmy domyślny plik konfiguracyjny i zapisaliśmy go jako .config (08). Po wykonaniu patchowania kernela źródłem z grsec (09) zaczynamy konfigurację (10).

W pierwszym oknie załaduj konfigurację z pliku .config wykorzyctując "Load an Alternate Configuration File" a następnie przejdź do "Security options". Jeśli patchowanie przebiegło bez problemów, powinieneś zobaczyć:

Co włączyć w zakładce "Grsecurity"? Moje ustawienia wyglądają następująco:

Security Level (Custom)
Memory Protections  --->
  [*] Deny reading/writing to /dev/kmem, /dev/mem, and /dev/port
  [*] Restrict VM86 mode
  [*] Disable privileged I/O
  [*] Harden ASLR against information leaks and entropy reduction
  [*] Deter exploit bruteforcing
  [*] Hide kernel symbols
  [*] Active kernel exploit response
Role Based Access Control Options  --->
  [ ] Disable RBAC system
  [*] Hide kernel processes
  (3) Maximum tries before password lockout
  (30) Time to wait after max password tries, in seconds
Filesystem Protections  --->
  [*] Proc restrictions
  [*]   Restrict /proc to user only
  [*] Additional restrictions
  [*] Linking restrictions
  [*] FIFO restrictions
  [*] Sysfs/debugfs restriction
  [*] Runtime read-only mount protection
  [*] Chroot jail restrictions
  [*]   Deny mounts
  [*]   Deny double-chroots
  [*]   Deny pivot_root in chroot
  [*]   Enforce chdir("/") on all chroots
  [*]   Deny (f)chmod +s
  [*]   Deny fchdir out of chroot
  [*]   Deny mknod
  [*]   Deny shmat() out of chroot
  [*]   Deny access to abstract AF_UNIX sockets out of chroot
  [*]   Protect outside processes
  [*]   Restrict priority changes
  [*]   Deny sysctl writes
  [*]   Capability restrictions
Kernel Auditing  --->
  [*] Single group for auditing
  (1007) GID for auditing
  [*] Exec logging
  [*] Resource logging
  [*] Log execs within chroot
  [*] Ptrace logging
  [*] Chdir logging
  [*] (Un)Mount logging
  [*] Signal logging
  [*] Fork failure logging
  [*] Time change logging
  [*] /proc//ipaddr support
  [*] Denied RWX mmap/mprotect logging
  [ ] ELF text relocations logging (READ HELP)
Executable Protections  --->
  [*] Dmesg(8) restriction
  [*] Deter ptrace-based process snooping
  [*] Require read access to ptrace sensitive binaries
  [*] Enforce consistent multithreaded privileges
  [*] Trusted Path Execution (TPE)
  [*]   Partially restrict all non-root users
  [*]   Invert GID option
  (1005)  GID for trusted users
Network Protections  --->
  [*] Larger entropy pools
  [*] TCP/UDP blackhole and LAST_ACK DoS prevention
  [*] Socket restrictions
  [*]   Deny any sockets to group
  (1004)  GID to deny all sockets for
  [*]   Deny client sockets to group
  (1003)  GID to deny client sockets for
  [*]   Deny server sockets to group
  (1002)  GID to deny server sockets for
Sysctl support  --->
  [*] Sysctl support
  [*]   Extra sysctl support for distro makers (READ HELP)
  [*]   Turn on features by default
Logging Options  --->
  (10) Seconds in between log messages (minimum)
  (6) Number of messages in a burst (maximum)

A PaX wygląda tak:

PaX Control  --->
  [*] Support soft mode
  [*] Use legacy ELF header marking
  [*] Use ELF program header marking
  [*] Use filesystem extended attributes marking
      MAC system integration (direct)  --->
Non-executable pages  --->
  [*] Enforce non-executable pages
  [*]   Paging based non-executable pages
  [*]   Segmentation based non-executable pages
  [*] Emulate trampolines
  [*] Restrict mprotect()
  [*]   Use legacy/compat protection demoting (read help)
  [*]   Allow ELF text relocations (read help)
  [*] Enforce non-executable kernel pages
Address Space Layout Randomization  --->
  [*] Address Space Layout Randomization
  [*] Randomize kernel stack base
  [*] Randomize user stack base
  [*] Randomize mmap() base
Miscellaneous hardening features  --->
  [*] Sanitize kernel stack
  [*] Prevent invalid userland pointer dereference
  [*] Prevent various kernel object reference counter overflows
  [*] Harden heap object copies between kernel and userland
  [*] Prevent various integer overflows in function size parameters

Tutaj mała uwaga: jeśli w zakładce "Grsecurity" włączymy logowanie exec(), to musimy liczyć się z tym, że system plików może tego nie wytrzymać. Bardziej obciążone systemy (współdzielone hostingi, shellownie) powinny się zaopatrzyć w dodatkowe miejsce na partycjach.

Taka konfiguracja pozwala na manipulowanie niektórymi parametrami z linii poleceń. Jeśli już wystartujemy system z nowym jajkiem, poprzez sysctl możemy sterować niektórymi ustawieniami. Przygotowałem ich spis wraz z opisem dostępnym w "help" podczas wyboru danej opcji z kernela. Należy je umieścić w pliku /etc/sysctl.conf:

################################################## GRSECURITY ####
kernel.grsecurity.grsec_lock = 0

#   If  you  say  Y  here,  non-root users will not be able to use
#dmesg(8) to view up to the last 4kb of messages in  the  kernelâs
#log buffer. If the sysctl option is enabled, a sysctl option with
#name "dmesg" is created.
kernel.grsecurity.dmesg = 0

#   If you say Y here, users with a  resource  limit  on  processes
# will  have  the value checked during execve() calls.  The current
# system only checks the system limit during fork() calls.  If  the
# sysctl  option is enabled, a sysctl option with name "execve_lim-
# iting" is created.
kernel.grsecurity.execve_limiting = 0

#   If you say Y here, all execve() calls will be logged (since the
# other exec*() calls are frontends to execve(), all execution will
# be logged).  Useful for shell-servers that like to keep track  of
# their  users.   If  the sysctl option is enabled, a sysctl option
# with name "exec_logging" is created. WARNING:  This  option  when
# enabled  will produce a LOT of logs, especially on an active sys-
# tem.
kernel.grsecurity.exec_logging = 0

#   If you say Y here, users will not be able  to  write  to  FIFOs
# they  donât own in world-writable +t directories (i.e. /tmp), un-
# less the owner of the FIFO is the same  owner  of  the  directory
# itâs  held  in.  If the sysctl option is enabled, a sysctl option
# with name "fifo_restrictions" is created.
kernel.grsecurity.fifo_restrictions = 0

kernel.grsecurity.forkfail_logging = 0

#    If you say Y here, /tmp race exploits will be prevented, since
# users will no longer be able to follow symlinks  owned  by  other
# users  in  world-writable  +t directories (i.e. /tmp), unless the
# owner of the symlink is the owner of the  directory.  users  will
# also  not  be  able to hardlink to files they do not own.  If the
# sysctl option is enabled, a sysctl option with name  "linking_re-
# strictions" is created.
kernel.grsecurity.linking_restrictions = 0

kernel.grsecurity.harden_ptrace = 0

#   If you say Y here, all attempts  to  overstep  resource  limits
# will  be  logged  with the resource name, the requested size, and
# the current limit.  It is highly recommended that you say Y here.
# If  the  sysctl option is enabled, a sysctl option with name "re-
# source_logging" is created.  If the RBAC system is  enabled,  the
# sysctl value is ignored.
kernel.grsecurity.resource_logging = 0

#    If  you  say Y here, all chdir() calls will be logged.  If the
# sysctl option is enabled, a sysctl option with name "audit_chdir"
# is created.
kernel.grsecurity.audit_chdir = 0

kernel.grsecurity.audit_gid = 20004

#   Setting this GID determines what group TPE restrictions will be
# *disabled* for.  If the sysctl option is enabled, a sysctl option
# with  name  "tpe_gid"  is  created.
kernel.grsecurity.tpe_gid = 20000

#   If you say Y here, the exec, chdir, and (un)mount logging  fea-
# tures  will  only operate on a group you specify.  This option is
# recommended if you only want to watch certain  users  instead  of
# having  a  large  amount  of logs from the entire system.  If the
# sysctl option is enabled, a sysctl option with name "audit_group"
# is created.
kernel.grsecurity.audit_group = 0

#    If  you say Y here, processes inside a chroot will not be able
# to raise the priority of processes in the chroot,  or  alter  the
# priority of processes outside the chroot.  This provides more se-
# curity than simply removing CAP_SYS_NICE from the processâ  capa-
# bility  set.   If  the  sysctl option is enabled, a sysctl option
# with name "chroot_restrict_nice"  is  created.
kernel.grsecurity.chroot_restrict_nice = 0

#    If  you say Y here, processes inside a chroot will not be able
# to kill,  send  signals  with  fcntl,  ptrace,  capget,  getpgid,
# setpgid,  getsid,  or view any process outside of the chroot.  If
# the sysctl option is enabled, a  sysctl  option  with  name  "ch-
# root_findtask" is created.
kernel.grsecurity.chroot_findtask = 0

#   If you say Y here, all executions inside a chroot jail will  be
# logged  to syslog.  This can cause a large amount of logs if cer-
# tain applications (eg. djbâs daemontools) are  installed  on  the
# system, and is therefore left as an option.  If the sysctl option
# is enabled, a sysctl option with name "chroot_execlog" is  creat-
# ed.
kernel.grsecurity.chroot_execlog = 1

#    If you say Y here, the current working directory of all newly-
# chrooted applications will be set to the the  root  directory  of
# the chroot. The man page on chroot(2) states: Note that this call
# does not change  the  current  working directory,  so   that  â.â
# can  be  outside the tree rooted at â/â.  In particular, the  su-
# per-user  can  escape  from  a âchroot jailâ by doing âmkdir foo;
# chroot  foo;  cd  ..â.   It  is  recommended that you say Y here,
# since itâs not known to break any software.  If the sysctl option
# is  enabled,  a sysctl option with name "chroot_enforce_chdir" is
# created.
kernel.grsecurity.chroot_enforce_chdir = 1

#   If you say Y here, processes inside a chroot will not  be  able
# to  connect  to  abstract (meaning not belonging to a filesystem)
# Unix domain sockets that were bound outside of a chroot.   It  is
# recommended  that  you  say  Y here.  If the sysctl option is en-
# abled, a sysctl option with name "chroot_deny_unix"  is  created.
kernel.grsecurity.chroot_deny_unix = 1

#    If you say Y here, an attacker in a chroot will not be able to
# write to sysctl entries, either by sysctl(2) or through  a  /proc
# interface.   It  is  strongly recommended that you say Y here. If
# the sysctl option is enabled, a  sysctl  option  with  name  "ch-
# root_deny_sysctl"   is   created.
kernel.grsecurity.chroot_deny_sysctl = 1

#   If you say Y here, processes inside a chroot will not  be  able
# to  attach to shared memory segments that were created outside of
# the chroot jail. It is recommended that you say Y here.   If  the
# sysctl  option  is enabled, a sysctl option with name "chroot_de-
# ny_shmat" is created.
kernel.grsecurity.chroot_deny_shmat = 1

#   If you say Y here, processes inside a chroot will not  be  able
# to use a function called pivot_root() that was introduced in Lin-
# ux 2.3.41.  It works similar to chroot in  that  it  changes  the
# root  filesystem.   This  function could be misused in a chrooted
# process to attempt to break out  of  the  chroot,  and  therefore
# should not be allowed.  If the sysctl option is enabled, a sysctl
# option with name "chroot_deny_pivot" is created.
kernel.grsecurity.chroot_deny_pivot = 1

#    If  you say Y here, processes inside a chroot will not be able
# to mount or remount filesystems.  If the  sysctl  option  is  en-
# abled,  a sysctl option with name "chroot_deny_mount" is created.
kernel.grsecurity.chroot_deny_mount = 1

#   If you say Y here, processes inside a chroot will  not  be  al-
# lowed  to mknod.  The problem with using mknod inside a chroot is
# that it would allow an attacker to create a device entry that  is
# the  same as one on the physical root of your system, which could
# range from anything from the console device to a device for  your
# harddrive  (which  they could then use to wipe the drive or steal
# data).  It is recommended that you say Y here, unless you run in-
# to software incompatibilities. If the sysctl option is enabled, a
# sysctl option with name  "chroot_deny_mknod"  is  created.
kernel.grsecurity.chroot_deny_mknod = 1

#    If  you say Y here, a well-known method of breaking chroots by
# fchdirâing to a file descriptor of  the  chrooting  process  that
# points to a directory outside the filesystem will be stopped.  If
# the sysctl option is enabled, a  sysctl  option  with  name  "ch-
# root_deny_fchdir"   is   created.
kernel.grsecurity.chroot_deny_fchdir = 1

#   If you say Y here, processes inside a chroot will not  be  able
# to chroot again outside the chroot.  This is a widely used method
# of breaking out of a chroot jail and should not be  allowed.   If
# the  sysctl  option  is  enabled,  a sysctl option with name "ch-
# root_deny_chroot" is created.
kernel.grsecurity.chroot_deny_chroot = 1

#    If  you say Y here, processes inside a chroot will not be able
# to chmod or fchmod files to make them have  suid  or  sgid  bits.
# This  protects against another published method of breaking a ch-
# root.  If the sysctl option is enabled, a sysctl option with name
# "chroot_deny_chmod"   is  created.
kernel.grsecurity.chroot_deny_chmod = 1

#   If you say Y here, the capabilities on all root processes with-
# in  a  chroot  jail will be lowered to stop module insertion, raw
# i/o, system and net admin tasks, rebooting the system,  modifying
# immutable files, modifying IPC owned by another, and changing the
# system time. This is left an option because  it  can  break  some
# apps.   Disable  this  if  your chrooted apps are having problems
# performing those kinds of tasks.  If the  sysctl  option  is  en-
# abled,  a sysctl option with name "chroot_caps" is created.
kernel.grsecurity.chroot_caps = 0

#   If you say Y here, all attempts to  attach  to  a  process  via
# ptrace will be logged.  If the sysctl option is enabled, a sysctl
# option with name  "audit_ptrace"  is  created.
kernel.grsecurity.audit_ptrace = 0

#   If you say Y here, calls to mmap() and mprotect() with explicit
# usage of PROT_WRITE and PROT_EXEC together will  be  logged  when
# denied  by the PAX_MPROTECT feature.  If the sysctl option is en-
# abled, a sysctl option with  name  "rwxmap_logging"  is  created.
kernel.grsecurity.rwxmap_logging = 0

#    If  you  say  Y here, text relocations will be logged with the
# filename of the offending library or binary.  The purpose of  the
# feature  is  to help Linux distribution developers get rid of li-
# braries and binaries that need text relocations which hinder  the
# future  progress  of  PaX.   Only  Linux  distribution developers
# should say Y here, and never on a production machine, as this op-
# tion  creates  an  information leak that could aid an attacker in
# defeating the randomization of a single memory  region.   If  the
# sysctl  option  is enabled, a sysctl option with name "audit_tex-
# trel" is created.
kernel.grsecurity.audit_textrel = 0

#   If you say Y here, you will be able to choose a gid to  add  to
# the  supplementary  groups of users you want to mark as "untrust-
# ed." These users will not be able to execute any files  that  are
# not  in  root-owned  directories  writable  only by root.  If the
# sysctl option is enabled, a sysctl option with name "tpe" is cre-
# ated.
kernel.grsecurity.tpe = 0

#    If  you say Y here, all non-root users will be covered under a
# weaker TPE restriction.  This is separate from, and  in  addition
# to, the main TPE options that you have selected elsewhere.  Thus,
# if a "trusted" GID is chosen, this restriction  applies  to  even
# that GID. Under this restriction, all non-root users will only be
# allowed to execute files in directories they  own  that  are  not
# group  or  world-writable,  or  in  directories owned by root and
# writable only by root.  If the sysctl option is enabled, a sysctl
# option with name "tpe_restrict_all" is created.
kernel.grsecurity.tpe_restrict_all = 0

#   If you say Y here, the group you specify in the TPE  configura-
# tion  will  decide what group TPE restrictions will be *disabled*
# for.  This option is useful if you want TPE  restrictions  to  be
# applied to most users on the system.  If the sysctl option is en-
# abled, a sysctl option with name "tpe_invert" is created.  Unlike
# other sysctl options, this entry will default to on for backward-
# compatibility.
kernel.grsecurity.tpe_invert = 0

#   If you say Y here, neither TCP resets nor ICMP  destination-un-
# reachable  packets  will  be  sent in response to packets sent to
# ports for which no associated listening process exists. This fea-
# ture  supports both IPV4 and IPV6 and exempts the loopback inter-
# face from blackholing.  Enabling this feature makes a  host  more
# resilient  to  DoS attacks and reduces network visibility against
# scanners.  The blackhole  feature  as-implemented  is  equivalent
# to the FreeBSD blackhole feature, as it prevents RST responses to
# all packets, not just SYNs.  Under most application behavior this
# causes no problems, but applications (like haproxy) may not close
# certain connections in a way that cleanly terminates them on  the
# remote  end,  leaving the remote host in LAST_ACK state.  Because
# of this side-effect and to prevent  intentional  LAST_ACK  DoSes,
# this feature also adds automatic mitigation against such attacks.
# The mitigation drastically reduces the amount of  time  a  socket
# can spend in LAST_ACK state.  If youâre using haproxy and not all
# servers it connects to have this option  enabled,  consider  dis-
# abling  this feature on the haproxy host.   If  the sysctl option
# is enabled, two sysctl  options  with  names  "ip_blackhole"  and
# "lastack_retries" will be created. While "ip_blackhole" takes the
# standard zero/non-zero on/off toggle, "lastack_retries" uses  the
# same  kinds  of values as "tcp_retries1" and "tcp_retries2".  The
# default value of 4 prevents a socket from lasting  more  than  45
# seconds  in  LAST_ACK  state.  kernel.grsecurity.ip_blackhole = 0
kernel.grsecurity.lastack_retries = 0

#   If you say Y here, you will be able to choose a  GID  of  whose
# users  will be unable to connect to other hosts from your machine
# or run server applications from your machine.  If the sysctl  op-
# tion is enabled, a sysctl option with name "socket_all" is creat-
# ed.
kernel.grsecurity.socket_all = 0

#   If you say Y here, you will be able to choose a  GID  of  whose
# users will be unable to connect to other hosts from your machine,
# but will be able to run servers.  If this option is enabled,  all
# users in the group you specify will have to use passive mode when
# initiating ftp transfers from the shell on your machine.  If  the
# sysctl  option  is  enabled,  a  sysctl  option  with name "sock-
# et_client" is created.
kernel.grsecurity.socket_client = 0

#   If you say Y here, you will be able to choose a  GID  of  whose
# users  will  be  unable  to run server applications from your ma-
# chine.  If the sysctl option is enabled,  a  sysctl  option  with
# name "socket_server" is created.
kernel.grsecurity.socket_server = 0

#   If you say Y here, a sysctl option with name  "romount_protect"
# will  be  created.   By  setting  this  option  to  1 at runtime,
# filesystems will be protected in the following ways:
# *  No new  writable  mounts  will  be allowed
# *  Existing read-only mounts wonât be able to be remounted
#    read/write
# *  Write  operations  will  be denied on all block devices
# This option acts independently of grsec_lock:  once  it is set to
# 1,  it  cannot  be turned off.  Therefore, please be  mindful  of
# the resulting behavior if this option is enabled in an init
# script on a read-only filesystem. This feature is mainly intended
# for secure embedded systems.
# kernel.grsecurity.romount_protect = 0

#   Here you can choose the GID to disable socket access  for.  Re-
# member  to  add  the users you want socket access disabled for to
# the GID specified here.  If  the  sysctl  option  is  enabled,  a
# sysctl  option with name "socket_all_gid" is created.
kernel.grsecurity.socket_all_gid = 20001

#   Here you can choose the GID to  disable  client  socket  access
# for. Remember to add the users you want client socket access dis-
# abled for to the GID specified here.  If the sysctl option is en-
# abled,  a sysctl option with name "socket_client_gid" is created.
kernel.grsecurity.socket_client_gid = 20002

#   Here you can choose the GID to  disable  server  socket  access
# for. Remember to add the users you want server socket access dis-
# abled for to the GID specified here.  If the sysctl option is en-
# abled,  a sysctl option with name "socket_server_gid" is created.
kernel.grsecurity.socket_server_gid = 20003

#   If you say Y here, all mounts and unmounts will be logged.   If
# the  sysctl  option  is  enabled,  a sysctl option with name "au-
# dit_mount" is created.
kernel.grsecurity.audit_mount = 0

#   If you say Y here, certain important signals  will  be  logged,
# such  as SIGSEGV, which will as a result inform you of when a er-
# ror in a program occurred, which in some cases could mean a  pos-
# sible  exploit attempt. If the sysctl option is enabled, a sysctl
# option with name "signal_logging" is  created.
kernel.grsecurity.signal_logging = 0

#    If  you say Y here, all failed fork() attempts will be logged.
# This could suggest a fork bomb, or someone attempting to overstep
# their  process  limit.  If the sysctl option is enabled, a sysctl
# option with name "forkfail_logging" is created.
kernel.grsecurity.forkfail_logging = 0

#    If  you  say  Y  here, any changes of the system clock will be
# logged. If the sysctl option is enabled,  a  sysctl  option  with
# name    "timechange_logging"    is   created.
kernel.grsecurity.timechange_logging = 0

Tutaj uwaga na opcję "kernel.grsecurity.grsec_lock = 0" - jeśli w pliku /etc/sysctl.conf ustawimy ją na "1" to nie będziemy mieli już możliwości zmiany parametrów *.grsec* z poziomu sysctl!

W porządku, zatem mamy przygotowany kernel, ustawione opcje. Teraz należy wykonać kompilację:

01 root@srv /usr/src/linux # export CONCURRENCY_LEVEL=$[`cat /proc/cpuinfo|grep ^processor|wc -l|awk '{print $1}'`]
02 root@srv /usr/src/linux # make-kpkg clean && make-kpkg --rootcmd fakeroot --initrd kernel_image kernel_headers

Co tym razem robimy? Ustawiamy parametr "CONCURRENCY_LEVEL" na wartość X, gdzie X to liczba wątków procesora dostępnych dla systemu (01). Warto wspomnieć, że przypiszemy wszystkie wątki, aby kompilacja przebiegła w miarę szybko. Jeśli jednak chcesz zachować jakieś zasoby dla systemu, ustaw CONCURRENCY_LEVEL=$[`cat /proc/cpuinfo|grep ^processor|wc -l|awk '{print $1}'` - 1 ]. Następnie wykonujemy kompilację, która stworzy paczkę *.deb zarówno z nowym jakiem, jak i headerami dla niego. Po udanej akcji w katalogu /usr/src powinnieneś zobaczyć:

root@srv /usr/src/linux # ls -al /usr/src/
-rw-r--r--  1 root root  6903602 03-29 19:56 linux-headers-3.3.4-d2_3.3.4-d2-10.00.Custom_i386.deb
-rw-r--r--  1 root root  6889906 05-04 00:10 linux-image-3.3.4-d2_3.3.4-d2-10.00.Custom_i386.deb

Skąd się wzięła opcja "-d2" w tej nazwie? (będzie ona prezentowana jako nazwa kernela po wydaniu polecenia uname -r, tutaj: 3.3.4-d2). Aby ustawić własną wersję należy w "General setup --->" dopisać własną rewizję do parametru "Local version - append to kernel release", a z pliku /usr/src/linux/localversion-grsec wywalić wpis "-grsec".

W kernelach z gałęzi 2.6.3x na debianie 5 (i 6 zresztą też) występował czasami taki problem:

echo "The UTS Release version in include/linux/version.h";
echo " \"\" ";
echo "does not match current version:";
echo " \"2.6.33.1\" "
echo "Please correct this."; exit 2
The UTS Release version in include/linux/version.h
""
does not match current version:
"2.6.33.3"
Please correct this.

Można to szybko naprawić ręcznie:

1) Otwórz /usr/share/kernel-package/ruleset/misc/version_vars.mk

2) Znajdź:
UTS_RELEASE_HEADER=$(call doit,if [ -f include/linux/utsrelease.h ]; then  \
                           echo include/linux/utsrelease.h;            \
                       else                                            \
                               echo include/linux/version.h ;              \
                       fi) 

3) Zamień na:
UTS_RELEASE_HEADER=$(call doit,if [ -f include/generated/utsrelease.h ]; then \
                               echo include/generated/utsrelease.h;           \
                           elif [ -f include/linux/utsrelease.h ]; then       \
                               echo include/linux/utsrelease.h;               \
                           else                                               \
                               echo include/linux/version.h;                  \
                           fi) 

4) Otwórz:
5) Zmień zawartość /etc/kernel/postinst.d/initramfs-tools na:
#!/bin/sh

version="$1"
bootopt=""

# passing the kernel version is required
[ -z "${version}" ] && exit 0

# kernel-package passes an extra arg
if [ -n "$2" ]; then
  if [ -n "${KERNEL_PACKAGE_VERSION}" ]; then
    bootdir=$(dirname "$2")
    bootopt="-b ${bootdir}"
  else
    # official Debian linux-images take care themself
    exit 0
  fi
fi

# avoid running multiple times
if [ -n "$DEB_MAINT_PARAMS" ]; then
  eval set -- "$DEB_MAINT_PARAMS"
  if [ -z "$1" ] || [ "$1" != "configure" ]; then
    exit 0
  fi
fi

# we're good - create initramfs.  update runs do_bootloader
update-initramfs -c -t -k "${version}" ${bootopt} 

OK, chyba się udało. Teraz aby zainstalować nowe jajko wydajemy polecenie:

root@srv /usr/src # dpkg -i linux-headers-3.3.4-d2_3.3.4-d2-10.00.Custom_i386.deb
root@srv /usr/src # dpkg -i linux-image-3.3.4-d2_3.3.4-d2-10.00.Custom_i386.deb

UWAGA: przy instalacji kolejnej wersji jajka, przy włączonym grsec, należy włączyć opcje PAGEEXEC oraz SEGMEXEC. W przeciwnym przypadku będziesz miał kłopot z post-instalacyjnymi skryptami, które wywołuje dpkg:

root@srv # paxctl -c /usr/sbin/grub-probe
root@srv # paxctl -C /usr/sbin/grub-probe
root@srv # paxctl -ps /usr/sbin/grub-probe

I teraz najważniejszy moment instalacji. Zakładam, że nie używasz narzędzi typu kexec, KVM (tym razem nie kernel virtual machine, tylko keyboard-video-mouse ;) ), iLO, *RAC itd, tylko samego SSH. Może się zdarzyć, że nowy kernel nie wstanie (kernel panic...) i będzie kłopot z rebootem maszyny, która siedzi sobie np 100km od Ciebie. Z pomocą przychodzi grub i jego opcje, które pozwolą nam na bezpieczny reboot do nowej wersji, a w przypadku paniki, czy innego błędu, który nie pozwoli wstać maszynie - przywróci starą, działającą wersję kernela.

Operacje, które teraz będziemy wykonywać to "grub failsafe". Jest w sieci kilka artów na ten temat, ale nie wszystkie były opisane w pigułce. Przyjrzyjmy się fail-safe dla gruba1 i gruba2:

==== grub
1. install kernel + headers
2. edit /boot/grub/menu.lst
default saved
3. przy NOWYM kernelu
... panic=5
savedefault 1
4. przy DOBRYM kernelu
savedefault
5. set default
grub-set-default 2 (dobry kernel)
6. reboot
grub-reboot 0 (nowy kernel)

==== grub2

1. install kernel + headers
2. edit /etc/default/grub
GRUB_DEFAULT=saved
GRUB_CMDLINE_LINUX_DEFAULT="quiet panic=5"
3. set default
grub-set-default 2 (dobry kernel)
4. regenerate config
grub-mkconfig
update-grub
update-grub2
5. reboot do nowego
grub-reboot 0 (nowy kernel)

root@srv # cat /boot/grub/grubenv
saved_entry=2 <- dobry kernel prev_saved_entry= [...]

Wybierz opcję odpowiadającą Twojej konfiguracji. Jeśli wszystko skonfigurowałeś prawidłowo, wykonaj reboot i sprawdź, czy system wstał z nowym kernelem weryfikując poprzez:

root@srv # uname -a
Linux tdhack.com 3.3.4-d2 #1 SMP Fri May 4 00:09:04 CEST 2012 i686 GNU/Linux

Na tym moglibyśmy skończyć, gdyby nie fakt, że dobrze by było wszystkie te operacje zautomatyzować ;) Do tego celu napisałem poniższy skrypt: compile_kernel.sh

Co robi skrypt? Szuka na stronach najnowszej wersji grsecurity, później ściąga kernel pod tą wersję. Patchuje, kompiluje i gotowe paczki wrzuca do $HOME przy okazji informując mailowo administratora o przebiegu instalacji oraz o lokacji nowego kernela. Taki skrypt można sobie wrzucić do crona i raz w tygodniu pobawić się kompilacją:

0 0 * * sat /root/scripts/compile_kernel.sh > /dev/null 2>&1

UPDATE: skrypt prawdopodobnie już nie działa - zmieniła się zarówno strona kernel.org jak i grsecurity.net, a co za tym idzie, też składnia html, której parsowanie było zaszyte w skrypcie.
TODO: poprawić skrypt ;)

Tagi: ,


Odpowiedzi: 5 do wpisu “Linux Kernel + grsecurity – my way!”

  1. bryn1u says:

    Super tutek !

    Przydalo by sie cos wiecej o chroocie z usluga ssh, www, mysql.

    Pozdrawiam.

  2. d2 says:

    Nie ten wątek, ale mam na oku taki tutorial. Pewnie wkrótce się ukaże. Pozdrawiam.

  3. bryn1u says:

    Jeszcze jedno. Usun te przecinki z pierwszego “code” bo wywala bledy.

    Budowanie drzewa zależno¶ci
    Odczyt informacji o stanie… Gotowe
    E: Nie udało się odnaleĽć pakietu fakeroot,
    E: Nie udało się odnaleĽć pakietu kernel-package,
    E: Nie udało się odnaleĽć pakietu libncurses5-dev,
    E: Nie udało się odnaleĽć pakietu paxctl,

  4. d2 says:

    poprawione, dzięki

Zostaw odpowiedź