### Startup Services, The init Process & Boot Loader Security ###
Required base knowledge of:
- init - basic linux commands - run levels - the boot loader [per the distro]
** Apologies in advance for the lazyness of not fixing my lines/indentation/etc. **
## Relatively speaking linux and the kernel are fairly secure by default. Linux offers great security when it comes to user permissions and access control. The permissions aspect of linux form a strong basis for much of it's touted security. Also the linux kernel has several inherent security features. The linux os/kernel in general is incredibly malleaable and extensive. Also linux often comes with many built in tools to allow a greater hardening of sorts.
## Linux is highly dependent on a wide range of configuration files, both at the level of the os and the application layer. The highly customizable nature of linux and the kernel is one of it's strongest suits, though this can also be one of it's downfalls at times. There can often be a sort of global impact to the os/kernel when subtle configuration changes are made, either manually or automatically, and this in itself can lead to indirect exposure to various elements.
## Linux especially is never static, it's a continually dynamic system, to a much greater degree [ime] than windows. Entropy can be a primary issue to linux, above most other things. From this, various operational/functional changes can lead to vulnerabilities, exposing risks, whether it be in singular binaries or the packages themselves.
** Keeping linux secure is a continual process. There is no rest in that sense. **
## Many distros come prepacked/preconfigured with a base set of packages, configurations and applications. This is usually based on the author/s of the distro and their intended target/userbase and what they deem to be included in their distribution based on the former. Much of the above offers a greater level of control and security, though occasionally risks can become evident due to the design parameters set forth.
** For example, the authors making it easier for their intended users to set up and install their distro, configure it and to run many of the applications.
## A good beginning step is minimalism, in the sense of only installing/running what's needed per your use case. A good 'general' list of packages/binaries [to start] to look out for and 'potentially' remove are:
- games - network servers - daemons and services - database applications - web tools - editors - media related devices - dev tools/compilers - printing applications - office applications - x windows - doc management
** One example of the above is x-windows, while possibly needed for the common home user, x-windows over time has had several security vulnerabilities. Unlike the windows os, linux doesn't necessarily need a graphical setup to be used. Everything is doable from the command line.
!! I just want to state that the above list is generalized. Obviously you're not removing ALL the daemons, for example. It's up to the user to read the man page for the daemon, application, tool, etc, see what sub systems, files, devices, etc that could be affected, if any, by the removal of such a thing, and make an informed decision based on that. Often times a portion of the things mentioned in the above list NEED to be on the system for it to function, but not ALL of the things.
### Boot Loader and Boot Time Services ###
- Someone that has actual physical access to a given linux system can bypass much of the initial security inherent to it. Rebooting the system and changing the config of the boot loader, init processes, and what processes are ran at boot and their initial boot sequence.
- Linux can allow quite alot of access to someone that's able to control how they're to boot into your system. It's good practice to restrict who is able to boot into your os, how they're to interact with the boot loader, and what kernel [if several] they're able to boot into.
- Some of the boot time elements are services, though some are oneoff scripts, daemons, specific configurations, applications/tools, etc.
## Most linux distros provide 1 of 2 boot loaders:
-GRUB -LILO
## Boot loaders such as these control the loading of a given boot image and what kernel's to be booted into at runtime. These are loaded after the bios configures what's needed. Generally from this point a small time window of x-seconds passes until the specified kernel is booted into, unless you were to intervene prior/during.
** Per the above it's good practice to not have a swath of potential kernels to boot in to, especially if there's older kernel versions within the boot loader menu. You'd be surprised often times how some linux savy folk have older kernel versions lying around in their boot loader. This obviously has security implications that I really need not explain.
## The lilo and grub boot loaders by their nature aren't all that secure if there's physical access to the system. Their defaults typically allow a user to boot into s-u mode [single user mode]. Within the single user mode the user would have root privs. And also in this instance no root passphrase is needed. From this there's a variety of commands that can be ran on the boot loader command line, and there's a great potential from that point to compromise the system.
## The grub and lilo boot loaders are able to be secured with a passphrase if need be. Below I'll show this process for both.
### Securing the LILO Boot Loader ###
- The lilo.conf file is typically located in '/etc/lilo.conf':
sudo nano /etc/lilo.conf
- And below is lilo.conf:
prompt boot=/dev/hda timeout=50 default=linux install=/boot/boot.b map=/boot/map message=/boot/message linear
image=/boot/vmlinuz-2.4.18-14 label=linux initrd=/boot/initrd-2.4.18-14.img read-only append="root=LABEL=/"
- With the above we're going to add two lines to this file: 'password' and 'restricted':
prompt boot=/dev/hda timeout=50 default=linux install=/boot/boot.b map=/boot/map message=/boot/message linear restricted password=somegreatpasswrd
image=/boot/vmlinuz-2.6.19-21 initrd=/boot/initrd-2.6.19-21.img read-only label=linux append="root=LABEL=/" ## Here you would add in a suitable passphrase, though being in cleartext, if someone has potential access to this file then they could read the passphrase.
** [though they shouldn't given that it should require root privs for access] **
** The restricted line in the lilo.conf file isn't absolutely necessary. This line's meant for once a user accesses the boot loader command line, if they were to try say, single user mode by typing 'single', then they would be prompted for a passphrase. So if you were to remove the 'restricted' line, then no matter the command entered by the user they'd be automatically prompted for a passphrase. This is probably a good idea.
## You can also add the 'password=somegreatpassword' line into the bottom half of the lilo.conf file underneath the boot image in order to protect that particular boot image/kernel [this would be if you had several kernels to boot into]:
image=/boot/vmlinuz-2.6.19-21 password=somegreatpassword initrd=/boot/initrd-2.6.19-21.img read-only label=linux append="root=LABEL=/" ## Now you need to make sure that 'lilo.conf' has the correct permissions and ownership set for only the authorized user:
sudo chown root:root /etc/lilo.conf && sudo chmod 600 /etc/lilo.conf
## And finally if you ever do any sorts of changes to lilo.conf, you need to run the lilo command to refresh the configuration:
sudo /sbin/lilo
## Below we'll now secure grub. The grub boot loader has a bit more extensive security with it's required password versus lilo. With grub you're able to secure the password with a hash, particularly SHA-256 in this instance.
### Securing the GRUB Boot Loader ###
- The grub.conf file can be in a number of places, and can be pretty dependent on the distro. Please reference the internet to figure out where your grub.conf file resides. Mine happens to be in '/etc/default/grub.conf'.
- To access grub terminal in my case, you hold down the SHIFT key during reboot. Below is the command to run once once in the grub boot loader terminal:
grub> grub-crypt --sha-256 Password: ************* Retype password: ************* $6$GXGrYVEnbKXAnQoT$p64OkyclNDt5qM2q47GMsgNxJxQaclNs77gvYYsl4h07ReDtJpt5P5kQn1KQ52u2eW8pKHTqcG50ffv0UlRcW0 grub> quit
## Now copy the SHA-256 hash generated in the grub terminal.
## Upon logging back into linux we need to access our grub.conf file [talked on that above] and paste the SHA-256 hash on our 'password' line:
sudo nano /etc/default/grub.conf
prompt boot=/dev/hda timeout=50 default=linux install=/boot/boot.b map=/boot/map message=/boot/message linear password=$6$GXGrYVEnbKXAnQoT$p64OkyclNDt5qM2q47GMsgNx \ JxQaclNs77gvYYsl4h07ReDtJpt5P5kQn1KQ52u2eW8pKHTqcG50ffv0UlRcW0
image=/boot/vmlinuz-2.6.19-21 initrd=/boot/initrd-2.6.19-21.img read-only label=linux append="root=LABEL=/" ** Now when you reboot you won't be able to interact with the grub menu/terminal unless you type '-p' followed by the password you'd entered earlier.
## Now finally we need to set the permissions on the grub.conf file with user and group ownership to root, along with chmod'n permissions to '600' [r/w permissions for the root user, negating all other permissions for root group and other:
sudo chown root:root /etc/grub.conf && sudo chmod 600 /etc/grub.conf
** Now having a SHA-256 hash for grub to compare, this helps add an additional layer of security for the boot loader, versus just having a plaintext entry.
## The init Services and Boot Sequences ##
- Linux has a large number of services that are ran during boot. A portion of these services are crucial to the system, while others are primarily used to start specific applications, file sequences, etc. A percentage of these files though are not required for linux and someof these can automatically start services that could pose potential security risks to the system.
- Below is a somewhat complete list, depending on the distro, of most of the common services that are typically started on linux systems at boot:
-anacron ## cron tool variant -atd ## at daemon/scheduling -autofs ## automount -apmd ## power management -cups ## printing functions -crond ## the cron daemon -functions ## .sh script functions for init -gpm ## mouse support for text apps -irada ## irda support -isdn ## isdn support -keytable ## keyboard mapping -kudzu ## hardware probing -lpd ## the printing daemon -netfs ## mounts network fs's -nfs ## nfs services -nfslock ## nfs locking services -ntpd ## daemon for network time protocol -pcmcia ## pcmcia support -portmap ## connection support for rpc -random ## random state snapshots -rawdevices ## assigns raw devices to block devices -snmpd ## snmp support -snmtptrap ## snmp trap daemon -sshd ## ssh daemon -windbind ## samba support -xfs ## x font server -ypbind ## yp client support
** You certainly won't want to remove all these, as a portion of these are needed, and other's will depend on your individual setup and needs. Some of these to the linux savy folk are commonsense to remove. For instance - I personally have zero reason to use 'winbind' on my main machine, I'm not going to be doing any sort of communication with windows machines whatsoever within my network. If you're unsure of what to remove, just google it, read on the specific service, how it interops with other files & services on your linux machine/network, and make an informed decision based on that.
** A common things for daemon's to do, especially with the time/entropy factor, they can 'on occasion' create files at startup that are 'too permissive'. In this case you could set the 'umask', which is the base standard permissions mask for newly created files on the linux system. Newly created files will have their permissions set according to the umask value.
** I'll go over umask in another tutorial **
## Working With init Scripts and Services ##
- Typically init scripts are located within the '/etc/init.d/' directory, with a portion of these scripts ran at boot/startup. The sequence for running the various scripts is usually statically defined. The init service will decide which scripts to run based on the set run levels.
- To check what init services are running, you can run the command 'sudo service --status-all' to see what's running, what's not, and what doesn't have a status switch.
- In the '/etc/init.d/' directory the various init scripts/services, if you use vim or nano to open one of them you'll notice the commented section near the top of each script. Within one of the commented lines you'll notice the run levels at which that service should start and stop.
- For instances:
# Provides: rsyslog # Required-Start: $remote_fs $time # Required-Stop: umountnfs $time # X-Stop-After: sendsigs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6
- 'Default Start' is the default run levels by which this script/service should be ran. The 'default Stop' line defines the default run levels by which the script/service should stop. '2, 3, 4, 5' are the typical default run levels to start most init scripts/services. Same goes for the default run levels '0, 1, 6' which are the default levels to stop the given service.
** 2, 3, 4, 5 are whats called user/multi-user runlevels
** 0, 1, 6 runlevels are defined as:
- 0 ## Halt - 1 ## Single User Mode - 6 ## Reboot
- I'll also go over a set of other numbers that can/will show up within init scripts [though not all that common in most debian based init scripts], they're called 'sequence numbers', for example you could see something like on occasion:
2,3,4,5 20 80
- The above means that at run levels 2,3,4,5 the given service will start with the sequence number '20', and in ascending order will stop at sequence number '80'. The sequence numbers can sometimes vary, though their importance isn't too great to the scope of this tutorial.
## Now we'll look at the debian based command 'update-rc.d'
- The init scripts within /etc/init.d/ can be started, stopped or modified on the fly through the 'update-rc.d' command. The 'update-rc.d' command is an all-in-one command to handle everything needed when dealing with init scripts/services. Aside from starting, stopping, or modifying preexisting runlevels, with 'update-rc.d' can do other tasks such as adding new init scripts, explicitly modifying an init script, removing an init script and all associated sym links/files, etc.
## Adding a New init Script ##
- To add a new init script/service under the /etc/init.d/ directory you run:
sudo update-rc.d servicename defaults
- Above, after the update-rc.d command, you specify the 'servicename' followed by 'defaults', unless you want to explicitly state the given run levels and sequence numbers. The 'defaults' option defaults to the standard run levels '2,3,4,5' and '0,1,6' with the default sequence number/s '20'.
- You can also specify the sequence number/s after declaring the 'defaults' option. An example of this:
sudo update-rc.d servicename defaults 20 70
- Explicit/granular control with 'update-rc.d' can be done like so:
sudo update-rc.d servicename start 20 2 3 4 5 . stop 20 0 1 6 .
## The above configuration is just longform layout of the 'defaults' option [per debian based systems]. Though with this longform style of init script modification you can specify your own starting/stopping run levels, along with your own sequence numbers.
## Removing a init Script ##
- Removing an init script fully requires two commands, in one line:
sudo rm -f /etc/init.d/scriptname && sudo update-rc.d scriptname remove
** The 'f' flag just forces rm to delete despite any inherent system warnings **
## Adding Your Own Custom Script to Init ##
- Firstly you need to have a script that you'd want executed during startup. So first you'd need to write your own script. For this example I'll just use a bash script. And for this bash script to work and be recognized by init, you need to add the common headers/comment lines at the top of the script, followed by whatever your bash script consists of.
- An example:
#! /bin/bash
### BEGIN INIT INFO # Provides: somescriptname # Required-Start: $local_fs $network # Required-Stop: $local_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: random startup script # Description: Runs some superawesome startup script ### END INIT INFO
then write some script in this section
- After completing your script, you then need to update the runlevel directories under /etc/rc*.d/:
sudo update-rc.d somescriptname defaults
- And that's all that's needed to have your own custom init based script of some kind.
## The 'update-rc.d' command also has the '-f' option which can be used in conjunction with 'remove' which forces all linking to be deleted [symbolic links, etc] even if the service script is still within the /etc/init.d/ directory.
** Also, it's generally good rpactice to lock down permissions and ownership on this directory 'if' it hasn't already been done so by default:
sudo chown root:root /etc/init.d/* && sudo chmod 700 /etc/init.d/*
** The above commands assign user and group ownership for the files in /etc/init.d/ and also chmod'd permissions to '700' [only root user having r/w/x permissions, negating all other permissions for 'group' and 'other'. The default permissions on most distros are something along the lines of '755' [full root permissions, r/x permissions for root group and r/x permissions for other].
|