<?php include('HEADER.php'); ?>

<h1>Linux Administration</h1>

<p>These are my notes from the <a href="http://www.amazon.com/gp/product/0131480057/ref=as_li_ss_tl?ie=UTF8&tag=whatspaulread-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0131480057">Unix and Linux System Administration Handbook</a>, which I strongly recommend. I primarily use Debian, so that's what I focus on here.</p>

<p>The <a href="http://www.debian.org/doc/manuals/debian-reference/">Debian Reference</a> is useful.</p>

<ul>
<li><a href="#manpages">Man pages</a></li>
<li><a href="#ioredirection">I/O redirection</a></li>
<li><a href="#filters">Filters</a></li>
<li><a href="#booting">Booting</a></li>
<li><a href="#accesscontrol">Access control</a></li>
<li><a href="#processes">Processes</a></li>
<li><a href="#filesystem">Filesystems</a></li>
<li><a href="#devices">Devices and drivers</a></li>
<li><a href="#"></a></li>
<li><a href="#"></a></li>
</ul>

<h2 id="manpages">Man Page Sections</h2>

<pre class="prettyprint">$ man 5 shadow
$ apropos shadow</pre>

<p>1: User-level stuff<br />
2: Sys call, kernel errors<br />
3: Lib calls<br />
4: Device driver, network protocols<br />
5: File formats<br />
6: Games, demos<br />
7: Other files, documents<br />
8: Sys admin commands<br />
9: Obscure kernel stuff</p>

<p>Man pages live in <code>/usr/share/man/</code>. The <code>manpath</code> command shows where <code>man</code> looks for man pages (which can be overridden with <code>export MANPATH=/home/whatever/man:/usr/share/man</code>).</p>

<h2 id="ioredirection">Input/Output Redirection</h2>

<p>Every process gets at least three channels: STDIN (file descriptor 0), STOUT (file descriptor 1), and STDERR (file descriptor 2).</p>

<p>The <code>&lt;</code> operator tells a command's STDIN to get its input from a file (or file-like thing). The <code>&gt;</code> operator writes the command/s STDOUT  o a file (<code>&gt;&gt;</code> appends rather than overwrites).</p>

<pre class="prettyprint">$ ps ux &gt; myfile.txt
$ mysql -u root -p mydatabase &lt; dbdump.sql</pre>

<p>The <code>&gt;&amp;</code> operator sends STDOUT and STDERR to the same destination. The <code>2&gt;</code> operator redirects only STDERR (i.e.&mdash;file descriptor 2).</p>

<p>The pipe operator <code>|</code> connects the STDOUT of the first command to the STDIN of a second command.</p>

<pre class="prettyprint">ls | grep foo</pre>

<h2 id="filters">Filters</h2>

<p>The <code>cut</code> filter selects only certain fields from a delimited records. The default delimiter is TAB.</p>

<p>The <code>uniq</code> filter show only unique or non-unique lines, and can count them.</p>

<pre class="prettyprint">$ cut -d: -f7 /etc/passwd | sort | uniq -c
14 /bin/bash
10 /bin/false</pre>

<h3>sort Flags</h3>

<p>-b Ignore leading whitespace<br />
-f Case insensitive<br />
-k Sort on column k<br />
-n Sort as integers<br />
-r Reverse order<br />
-t Set delimiter (default is whitespace)<br />
-u Output only unique lines</p>

<p>The <code>tee</code> filter sends its input to both STDOUT and a specified file (or file-like device as shown below).</p>

<pre class="prettyprint">$ find /home/me -name foo | tee /dev/tty | wc -l</pre>

<p>Also: wc, head, tail, grep, and less.</p>

<h2 id="booting">Booting</h2>

<ol>
<li>ROM/BIOS finds MBR on boot device</li>
<li>MBR points to boot loader (GRUB)</li>
<li>Boot loader loads &amp; initializes kernel</li>
<li>Kernel loads &amp; configures devices</li>
<li><p>Kernel creates spontaneous user-space processes</p>
<p>The kernel always creates 'init' as PID 1. <code>ps</code> shows these spontaneous processes with [brackets] around their names. If there's a slash and a number after the process name, the number indicates on which core the process is running.</p></li>
<li>Admin intervention (if single-user mode)</li>
<li>Run init scripts</li>
</ol>

<h3>GRUB</h3>

<p>The GRUB config file is <code>/boot/grub/menu.1st</code>. GRUB loads a kernel in <code>/boot</code>. Press [c] to enter command line mode from the GRUB boot screen. GRUB's command line lets you edit config files, pass arguments to the kernel, and load kernels that aren't listed in menu.1st. Press [TAB] for a list of command line options.</p>

<h3>Booting Into Single User Mode</h3>

<p>Highlight the desired kernel on the GRUB splash screen, and press [a]. Then:</p>

<pre class="prettyprint">grub append&gt; ro root=LABEL=/ rhgb quiet single</pre>

<h3>Init</h3>

<p><code>init</code> executes shell scripts in <code>/etc/init.d/</code>. <code>init</code> executes various scripts depending on the systems run level. <code>/etc/inittab</code> tells <code>init</code> what scripts to run for each level.</p>

<p>(Although, there's an additional layer of abstraction in that sym links in /etc/rc0.d/, /etc/rc1.d/, /etc/rc2.d/ &amp;c actually get looked at to determine what runs. The link names start with "S" or "K" to determine what gets started or killed when entering that run level. Further, the sym links are named with a number that determines the order in which they run. These sym links mostly point back to files in /etc/init.d/.)</p>

<h3>Run Levels</h3>

<p>0: shutdown<br />
1: single-user mode<br />
2-5: normal multiuser mode (Debian's default run level is 2)<br />
6: reboot</p>

<p>The <code>telinit</code> command forces a change in run level (e.g.&mdash;<code>telinit 3</code>). <code>telinit q</code> tells <code>init</code> to re-read <code>/etc/inittab</code>.</p>

<p><q>"There seem to be more run levels defined than are strictly necessary or useful. The traditional explaination for this is that a phone switch had 7 run levels, so it was thought that a UNIX system should have at least that many."</q> Hah!</p>

<h2 id="accesscontrol">Access Control</h2>

<p>Unix has several access control systems.</p>

<p>System calls have access controls. Only root can make certain system calls, for example, and those system calls themselves simply check if the caller is root. Other system calls, such as <code>kill</code>, make more complicated calculations about access, checking the caller's idenity, object owners, and making special allowances for root.</p>

<p>The filesystem has its own access controls. Files have an owner (mapped between username and UID in <code>/etc/passwd</code>) and a group owner (mapped between group name and GID in <code>/etc/group</code>). Groups and users may be recorded in a system like NIS or LDAP rather than in etc files.</p>

<p>Processes have access controls. Process owners can send their processes signals and change (reduce) their priority. Each process has several associated identities:</p>

<ul>
<li>a <em>real</em> UID used for accounting</li>
<li>an <em>effective</em> UID (normally the same as the real UID) used for access permissions</li>
<li>a <em>saved</em> UID saves the original UID if privileges are temporarily changed to a different (more privileged) UID</li>
<li>a <em>filesystem</em> UID used for file permissions (part of NFS under Linux, and usually the same as the effective UID)</li>
<li>a real, effective, and saved GID</li>
</ul>

<p>The superuser 'root' account can perform any valid operation on a process or file, and has the UID zero. Executables can be setuid or setgid to run with privileges other than those of the user who ran them (more elevated privileges). When a user changes his password, for example, the <code>passwd</code> command runs setuid so it has sufficient permission to write to <code>/etc/shadow</code>.</p>

<p>A few special accounts not associated with human users exist besides root. Accounts with UID's below 100 are typically for some particular software or daemon, and those below 10 are core system accounts. To prevent anyone from logging in under these accounts with a password or SSH key, the password field in <code>/etc/shadow</code> is replaced by a star (*) and the shell is set to '/bin/false'.</p>

<h3>"Modern" Access Control</h3>

<p>The previous section describes traditional unix security. Various enhanced security systems have been developed to address real and perceived inadequacies with traditional security, adding features such as auditing or role-based access controls.</p>

<p>SELinux, a distro developed by the NSA, added <em>mandatory access control</em> (MAC), which has since been integrated as an option in the mainline kernel. With MAC, all permission must be assigned only by admins; regular unprivileged users can't delegate their access.</p>

<p><em>Pluggable authentication modules</em> (PAM) provide authentication rather than authorization. PAM lets authentication worth through modern cryptographic or biometric mechanisms, for example, rather than simply checking a password against /etc/shadow. It's an authentication framework/wrapper for various particular authentication methods/implementations.</p>

<p><em>Kerberos</em> is one such authentication method. Kerberos client authenticate against a trusted server, which gives the client cryptographic credintials that the client can subsequently present to various services as proof of identity.</p>

<p><em>Access control lists</em> (ACLs) elaborate on traditional filesystem permissions.</p>

<h3>Sudo</h3>

<p>Unlike the "modern" access control embellishments described above, <code>sudo</code> is widely used as an enhancement to traditional unix security. Sudo lets users listed in <code>/etc/sudoers</code> execute commands with root privileges. Sudo logs the commands and who executed them. <code>/etc/sudoers</code> provides some fine-grained control, like letting a user only execute one particular command on a particular host with elevated privileges. Edit <code>/etc/sudoers</code> with <code>visudo</code> (which makes sure no one else is editing it at the time, and validates the entries).</p>

<h2 id="processes">Processes</h2>

<p>A <em>process</em> is an abstraction for an allocated address space inside the kernel, which includes the program's code, library code it uses, storage for its variables, and information the kernel uses to keep track of the process:</p>

<ul>
<li>The kernel assigned a <i>process ID</i> (PID) to every process.</li>
<li>Each process has a <i>parent PID</i>&mdash;the PID of the parent from which it forked. Most processes (except the few created directly by the kernel) are ultimately descendants of init.</li>
<li>The <i>UID</i> is the user ID of the person who created the process.</li>
<li>The <i>effective user ID</i> (EFID) determines a process's permissions. It's usually identical to the UID, unless the process has elevated permissions (setuid). It maintains the distinction between <i>identity</i> (UID) and <i>permission</i> (EFID).</li>
<li>The <em>saved UID</em> saves the effective UID if privileges are temporarily changed to a different UID. A conservative setuid process might operate under its saved UID most of the time, using elevated privileges only when it must.</li>
<li>A <em>filesystem</em> UID is used for file permissions (part of NFS under Linux, and usually the same as the effective UID). It's mostly only used for internal kernel stuff.</li>
<li>The real, effective, and saved group ID are like the UID's. GID doesn't do much, except impart a default group to any file the process creates; a process's complete group list is stored in its EGID, and this determines its actual access permissions.</li>
<li><i>Niceness</i> is the process's scheduling priority. It's a value between -20 (most favorable) and 19 (least favorable). A process generally inherits the niceness value of its parent. See <code>nice</code> and <code>renice</code>.</li>
<li>Every non-daemon process has a <i>control termial</i> that indicates its STDIN, STDOUT, STERR, and signaling (see below). This may be the shell window from which the process was started.</li>
<li>A process has one of four possible <i>states</i>. The <i>runnable</i> state means the process is ready to execute as soon as the kernel gives it CPU time. <i>Sleeping</i> means the process is waiting for a signal (a daemon waiting to receive its next request, for example). A <i>zombied</i> processes has finished execution, but hasn't had its exit status collected. A <i>stopped</i> is administratively suspended until restarted with a CONT signal.</li>
</ul>

<p>A process can fork itself into threads, which execute on different processor cores, but share the same memory space.</p>

<h3>Signals</h3>

<p>A variety of process-level interrupt requests can be sent to notify a process of an event, kill the process, or act as inter-processes communication. A process can catch a signal if it has an appropriate handler; otherwise, the kernel takes a default action on behalf of the process.</p>

<p>The <code>kill <i>PID</i></code> command can send any signal to a process, though by default it sends TERM (a catchable, blockable termination). <code>kill -KILL <i>PID</i></code> terminates the process (uncatchable, unblockable). <code>kill -INT <i>PID</i></code> is like KILL, but catchable and blockabe; this is the signal sent by typing CTRL-C in a terminal. <code>kill -STOP <i>PID</i></code> suspends the process (uncatchable, unblockable) until it receives the CONT signal. TSTP is similar to STOP, but gives the process a chance to clean up its state first (catchable, blockable); this is the signal sent by hitting CTRL-Z in a terminal. Many daemons understand <code>kill -HUP <i>PID</i></code> as a request that they re-read their config files without fully restarting; HUP may also get sent to processes attached to a disconnected terminal.</p>

<p><code>kill -l</code> gives a complete list of signals.</p>

<h3>Monitoring Processes</h3>

<p>Examine processes with <code>ps</code>. Two useful sets of flags are <code>ps aux</code> and <code>ps lax</code>. "a" is all processes, "u" formates the output for reading by a user, "x" includes even those without a control terminal, "l" is long output format.</p>

<p>See also <code>top</code> and <code>htop</code>. Note that top includes video memory in the memory used stats as well as memory used by shared libraries, so some processes seem to have an oversized memory footprint. Hitting "f" then "s" in top shows a <i>data</i> column that tends to me a more accurate indicator of memory usage for a given process.</p>

<p>Process information is also available under the /proc/ pseudo-filesystem, including these files of interest:</p>

<ul>
<li>cmd - command the process is executing</li>
<li>cmdline - full command line of process command</li>
<li>cwd - process's current working directory</li>
<li>environ - process's environment variables</li>
<li>exe - sym link to file being executed</li>
<li>fd - links to each open file descriptor</li>
<li>maps - mem mapping info, including linked libraries</li>
<li>root - sym link to process's root directory, as set by chroot</li>
<li>stat - general info, like from ps</li>
<li>statm - mem usage</li>
</ul>

<p>The <code>strace -p <i>PID</i></code> command shows all the system calls a process makes. <code>strace -c -p <i>PID</i></code> tallies all the system calls. <code>strace -T -p <i>PID</i></code> shows the time spent on each system call.</p>

<p>The <code>fuser</code> and <code>lsof</code> commands help find which process is using a file.</p>

<p>There's also tons of good info via <code>cat /proc/1234/status</code>, where "1234" is the pid.</p>

<h2 id="filesystem">Filesystems</h2>

<p>On unix, everything is a file (i.e.&mdash;exposed/represented as a file), including processes processes, devices, and kernel tuning parameters. Consider the filesystem as having four characteristics:</p>

<ul>
<li>a namespace of particular names and hierarchical relationships</li>
<li>an API of system calls that manipulate objects</li>
<li>a security model</li>
<li>an implementation that ties the logical filesystem to the hardware</li>
</ul>

<h2 id="devices">Devices &amp; Drivers</h2>

<p>Although linux, like most unices, is basically a monolithic kernel (meaning virtual memory, device drivers, interprocess communication, etc. use the same chunk of reserved memory), it support drivers implemented as modules. Modules load without the need to recompile the kernel and reboot.</p>

<p>Modules get loaded in one of two ways. Either you explicitly tell the kernel to load it, or the kernel detects the device and loads the module on its own. The later happens at boot time or (in the case of many USB devices, for example) while the system is running.</p>

<p>Drivers provide an abstraction layer between the kernel and the hardware. Because drivers are compiled into the kernel or loaded into kernel-space as modules, user access to devices comes through <code>/dev/</code> files, that map user file operations to driver calls.</p>

<p>Devices have a major number and a minor number:</p>

<pre class="prettyprint">$ ll /dev |grep sda
brw-rw----   1 root   8,   0 Apr 11 18:18 sda
brw-rw----   1 root   8,   1 Apr 11 18:18 sda1
brw-rw----   1 root   8,   2 Apr 11 18:18 sda2</pre>

<p>The major number ("8" for sda*) identifies the device driver (and, by implication, the type of device). The minor number (0, 1, 2) identifies a particular device from others of its type.</p>

<p>A device might have more than one associated /dev/ file, with each device file supporting different functions (on a sound card, for example, one device might correspond to playback, another to capture).</p>

<h3>Creating /dev entries, udev</h3>

<p>Traditionally, the admin would create device files like <code>mknod <i>fileName b(lock)|c(haracter) majorNumber minorNumber</i></code>. Under linux, <code>udevd</code> listens for device status change messages from the kernel, and creates or removes /dev files as necessary.</p>

<h3>Pseudo-Devices</h3>

<p>Some /dev/ files are convenient abstraction that don't correspond to actual devices. The tty* devices are not actual terminals, for example. Other pseudo-devices include <code>/dev/null</code> and <code>/dev/random</code>.</p>

<h3>Kernel Config</h3>

<p>Getting devices working (or working optimally) may require some kernel configuration in one of four ways (listed from least to most annoying): tuning kernel parameters in <code>/proc/sys</code>, loading modules into a running kernel, setting GRUB directives at boot time, or compiling a new kernel from scratch with any necessary patches.</p>

<p>Tune kernel parameters as follows. Note that these tunings do not persist after a reboot if you just cat a value into them. For persistent changes, use the <code>sysctl</code> command or edit <code>/etc/sysctl.conf</code>.</p>

<pre class="prettyprint">$ cat /proc/sys/dev/cdrom/autoeject
0
$ sudo sh -c "echo 1 &gt; /proc/sys/dev/cdrom/autoeject"
$ sudo sysctl dev.cdrom.autoeject=1</pre>

<p>Loadable kernel modules let you load or remove a device driver (or whatever) from a running kernel. Loadable modules are in <code>/lib/modules/</code>. The <code>lsmod</code> command shows currently loaded modules. The <code>insmod</code> code inserts new modules into the running kernel, <code>rmmod</code> unloads a running module. The <code>modprobe</code> command may be preferable to <code>insmod</code> in some cases, as it understands a bit about module dendencies and options (using info from <code>/etc/modprobe.d/</code>). The <code>modinfo</code> show the parameters a module accepts; see also <code>/etc/modules</code>. Note that udev will automatically load many modules for you.</p>

<p>There are few reasons these days to compile a custom kernel, but the Debian way is:</p>

<pre># cd /usr/src/linux
# make menuconfig
# make-kpg clean
# make-kpkg --initrd --revision=custom.1.0 kernel_image
# dpkg -i ../linux-image-2.6.32-amd64.1.0_i386.deb
# shutdown -r now
</pre>

<h3>Udev</h3>

<p>Udev is a user space device management system that watches for device installation and removal (by watching the virtual filesystem <code>/sys/</code>), and maintains device files in /dev/. The udev management tool is <code>udevadm</code>. Also see <code>/etc/udev/</code></p>

<p>(/sys/ was designed as a better organized replacement for /proc/. /proc/ is slowly being reverted back to its original purpose of showing only process information.)</p>

<?php include('../FOOTER.php'); ?>
