Linux exercises

advertisement
Table of Contents
Exercise 1 ............................................................................................................................. 2
Exercise 2. Text Viewer, The: less is More ............................................................................ 4
Exercise 3. Bash: The shell, .profile, .bashrc, .bash_history .................................................. 6
Exercise 4. Bash: working with files, pwd, ls, cp, mv, rm, touch ............................................ 9
Exercise 5. Bash: environment variables, env, set, export .................................................. 12
Exercise 6. Bash: language settings, LANG, locale, dpkg-reconfigure locales .................... 14
Exercise 7. Bash: redirection, stdin, stdout, stderr, <, >, >>, |, tee, pv ................................. 17
Exercise 8. Bash: more on redirection and filtering: head, tail, awk, grep, sed .................... 20
Exercise 9. Bash: job control, jobs, fg ................................................................................. 25
Exercise 10. Bash: program exit code (return status) .......................................................... 28
Exercise 11. Bash: wrapping up .......................................................................................... 30
Exercise 12. Documentation: man, info ............................................................................... 33
Exercise 13. Documentation: Google .................................................................................. 36
Exercise 14. Package management: Debian package management utility aptitude ............ 38
Exercise 15. System boot: runlevels, /etc/init.d, rcconf, update-rc.d .................................... 43
Exercise 16. Processes: working with proccesses, ps, kill ................................................... 48
Exercise 17. Job schedulers: cron, at .................................................................................. 53
Exercise 18. Logging, /var/log, rsyslog, logger .................................................................... 57
Exercise 19. Filesystems: mounting, mount, /etc/fstab ........................................................ 64
Exercise 20. Filesystems: modifying and creating filesystems, tune2fs, mkfs ...................... 68
Exercise 21. Filesystems: changing root directory, chroot ................................................... 75
Exercise 22. Filesystems: moving data around: tar, dd ....................................................... 76
Exercise 23. Filesystems: security permissions, chown, chmod, umask.............................. 81
Exercise 24. Networking: interface configuration, ifconfig, netstat, iproute2, ss, route ......... 87
Exercise 25. Networking: configuration files, /etc/network/interfaces ................................... 98
Exercise 26. Networking: packet filter configuration, iptables ............................................ 101
Exercise 27. Networking: secure shell, ssh, sshd, scp ...................................................... 114
Exercise 28. Performance: getting performance stats, uptime, free, top ............................ 123
Exercise 29. Kernel: kernel messages, dmesg .................................................................. 130
Exercise 30. Lather, Rinse, Repeat: The Grand Rote Learning ......................................... 133
1
Exercise 1
Now, log into a Linux virtual machine and type:
vim hello.txt
You should see the following:
Hello, brave adventurer!
~
~
~
~
~
~
~
~
~
~
~
~
~
"hello.txt" [New File] 0,0-1
All
There is a joke that says that vim has 2 modes – “beep repeatedly” and “break
everything”. Well, if you do not know how to use vim, it is pretty much true, because
vim is modal text editor.
The modes are:
NORMAL mode: moving your cursor around and doing operations with text like
delete, copy and paste.
INSERT mode: entering text.
This greatly confuses newcomers because they try to avoid NORMAL mode as
much as possible. Well, this is wrong, so now I will give you correct outline of
working with vim:
start vim
while editing is not finished, repeat
navigate to desired position in NORMAL mode
enter INSERT mode by pressing i
type text
exit INSERT mode by pressing <ESCAPE>
when editing is finished, type :wq
What is the most important is that you stay in NORMAL mode almost all the time,
entering INSERT mode for a short time to type something and then immediately
exiting it. Looking this way, vim has only one mode, and that mode is NORMAL
mode.
Now, let us try it out. Remember, press i to enter INSERT mode and <ESCAPE> to
return to NORMAL mode. Type the following (press <ENTER> at the end of each
line):
iRoses are red
Linux is scary
<ESCAPE>
This is what you should see:
Roses are red
Linux is scary
~
~
2
~
~
~
4,17
All
Now I'll give you list of commands to navigate the cursor in NORMAL mode:
h — move left
j — move down
k — move up
l — move right
i — enter INSERT mode
o — insert a line under cursor and enter INSERT mode
<ESCAPE> — exit INSERT mode
x — delete symbol under cursor
dd — delete a line
:wq – write changes to the file and exit. Yes, that's right, it is colon follower by wq
and <ENTER>.
:q! – do not write changes to the file and exit.
That will suffice. Now, place cursor on first line and type this:
oViolets are blue<ESCAPE>
After this, place cursor on the line “Linux is scary” and type this:
oBut I'm scary too<ESCAPE>
You should see this:
Roses are red
Violets are blue
Linux is scary
But I'm scary too
~
~
~~
~
~
~
4,17
All
Now type :wq to save the file and exit. You should see this:
Violets are blue
Linux is scary
But I'm scary too
~
~
~~
~
~
"hello.txt" 4L, 64C written
student@vm1:~$
Well, you did it! You just edited a text file in vim, the mighty and terrible!
Extra credit
Start vim again by typing vim hello.txt and try some other commands I gave you.
Play this game which will allow you to feel more comfortable in vim: http://vimadventures.com/
3
Exercise 2. Text Viewer, The: less is More
Now you can edit text files, that is nice. But what if you want just to view a text file?
Of course, you could use vim for that, but very often it is overkill. And two more thing
to consider: If you want to view really large file, you will want to view it in a program
which is as fast as possible.Often you would not want to accidentally change
something in a file.So I introduce you to the mighty less, which is more. “More than
what?” you might ask. Well… Once upon a time there was a viewer which was called
more. It was pretty simple, and just showed you the text file you asked it to show. It
was so simple that it could show you text files in only one direction, which is forward.
This was found unsatisfactory by Mark Nudelman, who wrote less it in 1983-85, and
since then it received many advanced features. Because it was more advanced than
more, a saying was born: “Less is more, and more is less”.
Well, let us try it.
Type this:
less .bashrc
You should see this:
student@vm1:~$ less .bashrc
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
# don't put duplicate lines in the history. See bash(1) for more options
# don't overwrite GNU Midnight Commander's setting of `ignorespace'.
HISTCONTROL=$HISTCONTROL${HISTCONTROL+:}ignoredups
.bashrc
If you don't have wide enough terminal, text will look like a mess because whole lines
will not fit in it. To fix it, type - -ch<ENTER><ENTER>. Yes, dash-dash-c-h-ENTERENTER. This will enable horizontal scrolling.
To navigate text up and down use already familiar j and k. To exit press q.
Now I will show you an advanced feature of less, which allows you see only those
lines you want. Type &enable<ENTER>. You should see this:
# enable color support of ls and also add hand
# enable programmable completion features (you
# this, if it's already enabled in /etc/bash.b
~
~
~
~
~
~
& (END)
Behold! To discard filter, just type &<ENTER>. Again, commands to remember:
j — move up.
k — move down.
q — quit less.
- -chop-long-lines or - -ch<ENTER><ENTER> — enable horizontal scrolling.
/ — search.
&something — show only those line from your file which contain something.
4
Extra credit
Linux has online manuals which are called by typing man. By default in out system
this manuals are viewed with less. Type man man and read it, then quit less.
That is it, not more extra credit for you.
5
Exercise 3. Bash: The shell, .profile,
.bashrc, .bash_history
When working with Linux using CLI (command line interface), you are interacting
with a program called a shell. All you type is passed to the shell, which interprets
what you have typed, does parameters expansion (which is somewhat similar to
brace expansion in algebra) and executes programs for you. Shell which we will be
using is called Bash, which stands for Bourne Again Shell, which is in turn a pun.
Now I will show you general overview of how the bash works in plain English:
YOU
Log into a Linux box
Your identity is verified by username (student) and password (Pa$$w0rd)
Bash is executed
Bash
reads and executes initial commands from your profile, which define:
What your command prompt will look like
What colors you will see when working in Linux
What you editor is
What you viewer is
...
After initial commands are read, Bash enters in a loop
While not ordered to exit by typing 'exit', 'logout' or hitting <CTRL+D>:
Read a line
Parse this line, expand braces
Execute command with expanded parameters
I repeat, any command which you type is not executed directly, but expanded firstly
and only then executed. For example, when you type ls * the star * is expanded into
list of all files in current directory.
Now you will learn how to modify your profile and how to write and view your history.
Do this
1: ls -al
2: cat .profile
3: echo Hello, $LOGNAME!
4: cp -v .profile .profile.bak
5: echo 'echo Hello, $LOGNAME!' >> .profile
6: tail -n 5 .profile
7: history -w
8: ls -altr
9: cat .bash_history
10: exit
What you should see
student@vm1's password:
Linux vm1 2.6.32-5-amd64 #1 SMP Sun May 6 04:00:17 UTC 2012 x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Jun 7 12:03:29 2012 from sis.site
Hello, student!
student@vm1:~$ ls -al
6
total 20
drwxr-xr-x 2 student student 4096 Jun 7 12:18 .
drwxr-xr-x 3 root root 4096 Jun 6 21:49 ..
-rw-r--r-- 1 student student 220 Jun 6 21:48 .bash_logout
-rw-r--r-- 1 student student 3184 Jun 6 21:48 .bashrc
-rw-r--r-- 1 student student 697 Jun 7 12:04 .profile
student@vm1:~$ cat .profile
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.
# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
echo Hello, $LOGNAME!
student@vm1:~$ echo Hello, $LOGNAME!
Hello, student!
student@vm1:~$ cp -v .profile .profile.bak
`.profile' -> `.profile.bak'
student@vm1:~$ echo 'echo Hello, $LOGNAME!' >> .profile
student@vm1:~$ tail -n 5 .profile
# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
echo Hello, $LOGNAME!
student@vm1:~$ history -w
student@vm1:~$ ls -altr
total 28
-rw-r--r-- 1 student student 3184 Jun 6 21:48 .bashrc
-rw-r--r-- 1 student student 220 Jun 6 21:48 .bash_logout
drwxr-xr-x 3 root root 4096 Jun 6 21:49 ..
-rw-r--r-- 1 student student 741 Jun 7 12:19 .profile.bak
-rw------- 1 student student 308 Jun 7 12:21 .bash_history
-rw-r--r-- 1 student student 697 Jun 7 12:25 .profile
drwxr-xr-x 2 student student 4096 Jun 7 12:25 .
student@vm1:~$ cat .bash_history
ls -al
cat .profile
echo Hello, $LOGNAME!
cp -v .profile .profile.bak
echo 'echo Hello, $LOGNAME!' >> .profile
7
tail -n 5 .profile
history -w
ls -altr
student@vm1:~$ exit
logout
Don not be afraid, all this commands will be explained. Line numbers correspond to
those “Now type this” section.
Explanation
Prints out all files in current directory, including hidden ones. Options -al tell ls to
print file list in long format and include all files including hidden ones. .profile and
.bash_rc are hidden files, because they start with dot .. Every file starting with dot is
hidden, it is that simple. This two particular files are shell scripts, They contain
instructions which are executed when you log in.
Prints out your .profile file. Just that.
Tells your shell, which is in your case bash, to output a string Hello, $LOGNAME!,
substituting $LOGNAME with environment variable $LOGNAME which happens to
contain your login.
Copies your .profile file to .profile.bak. Key -v tells cp to be verbose, which means
it will print out all operations. Remember this key, it is often used to tell commands to
feed you more information than they do by default.
Adds a line to your .bash_rc profile. From now on, every time you will log into vm1
this command will be executed. Attention, >> means to add something to file, but >
means replacing file with something. If you accidentally replaced your .profile
instead of appending to it, command
cp -v .profile.bak .profile
will return your old .profile file.
Prints out exactly five last lines from .profile file.
Writes all your command history to .bash_history file. Normally this is done at the
end of your session, when you close it by typing exit or by pressing <CTRL>+D.
Prints out files in current directory. Options -tr mean that file list is sorted by time in
reverse direction. This means that most recently created and modified files are
printed last. Notice how you have 2 new files now.
Prints out file which keeps history of your commands. Notice how all that you have
type is here.
Closes the session.
Extra credit
Search online why ls -al tells you “total 20” then there are only 5 files present. What
does it mean? Notice that ”.” and ”..” are special file entries, which correspond to the
current directory and parent directory respectively.
Log in vm1 and type man -K /etc/profile, now using cursor keys scroll to
“INVOCATION” section and read it. To exit man, type “q”. Type man man to find out
what -K man option means.
Type in uname with space before the command. Now, type history. You see? If you
prepend a command with space it won't be saved in history! Hint: usable when you
need to specify the password ring on the command line.
Find a wiki page about bash and try to read it. No worries if it scares you, just omit
frightening sections for now.
8
Exercise 4. Bash: working with files,
pwd, ls, cp, mv, rm, touch
In Linux everything is a file. But what is a file? For now it will suffice to say that it is
an object which contains some information. It is usually defined like this:
A computer file is a block of arbitrary information, or resource for storing information,
which is available to a computer program and is usually based on some kind of
durable storage. A file is durable in the sense that it remains available for programs
to use after the current program has finished. Computer files can be considered as
the modern counterpart of paper documents which traditionally are kept in offices'
and libraries' files, and this is the source of the term.
But this definition is too general, so let us be more specific. man stat tells us that file
is an object which has the following properties additionally to information it contains:
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
Don not be intimidated, just remember the following properties:
Size, which is exactly what is says on the tin.
Time of last access, which is updated when you view a file.
Time of last modification, which is updated when you change a file.
Now you will learn how to print out your current directory, files in your directory, copy
and move files.
Do this
1: pwd
2: ls
3: ls -a
4: ls -al
5: ls -altr
6: cp -v .bash_history{,1}
7: cp -v .bash_history1 .bash_history2
8: mv -v .bash_history1 .bash_history2
9: rm -v .bash_history2
10: touch .bashrc
11: ls -al
12: ls .*
What you should see
Hello, student!
student@vm1:~$ pwd
/home/student
student@vm1:~$ ls
9
student@vm1:~$ ls -a
. .. .bash_history .bash_history1 .bash_logout .bashrc .lesshst .profile .profile.bak .profile.bak1
student@vm1:~$ ls -al
total 40
drwxr-xr-x 2 student student 4096 Jun 7 13:30 .
drwxr-xr-x 3 root root 4096 Jun 6 21:49 ..
-rw------- 1 student student 853 Jun 7 15:03 .bash_history
-rw------- 1 student student 308 Jun 7 13:14 .bash_history1
-rw-r--r-- 1 student student 220 Jun 6 21:48 .bash_logout
-rw-r--r-- 1 student student 3184 Jun 6 21:48 .bashrc
-rw------- 1 student student 45 Jun 7 13:31 .lesshst
-rw-r--r-- 1 student student 697 Jun 7 12:25 .profile
-rw-r--r-- 1 student student 741 Jun 7 12:19 .profile.bak
-rw-r--r-- 1 student student 741 Jun 7 13:12 .profile.bak1
student@vm1:~$ ls -altr
total 40
-rw-r--r-- 1 student student 3184 Jun 6 21:48 .bashrc
-rw-r--r-- 1 student student 220 Jun 6 21:48 .bash_logout
drwxr-xr-x 3 root root 4096 Jun 6 21:49 ..
-rw-r--r-- 1 student student 741 Jun 7 12:19 .profile.bak
-rw-r--r-- 1 student student 697 Jun 7 12:25 .profile
-rw-r--r-- 1 student student 741 Jun 7 13:12 .profile.bak1
-rw------- 1 student student 308 Jun 7 13:14 .bash_history1
drwxr-xr-x 2 student student 4096 Jun 7 13:30 .
-rw------- 1 student student 45 Jun 7 13:31 .lesshst
-rw------- 1 student student 853 Jun 7 15:03 .bash_history
student@vm1:~$ cp -v .bash_history{,1}
`.bash_history' -> `.bash_history1'
student@vm1:~$ cp -v .bash_history1 .bash_history2
`.bash_history1' -> `.bash_history2'
student@vm1:~$ mv -v .bash_history1 .bash_history2
`.bash_history1' -> `.bash_history2'
student@vm1:~$ rm -v .bash_history2
removed `.bash_history2'
student@vm1:~$ touch .bashrc
student@vm1:~$ ls -al
total 36
drwxr-xr-x 2 student student 4096 Jun 14 12:23 .
drwxr-xr-x 3 root root 4096 Jun 6 21:49 ..
-rw------- 1 student student 853 Jun 7 15:03 .bash_history
-rw-r--r-- 1 student student 220 Jun 6 21:48 .bash_logout
-rw-r--r-- 1 student student 3184 Jun 14 12:24 .bashrc
-rw------- 1 student student 45 Jun 7 13:31 .lesshst
-rw-r--r-- 1 student student 697 Jun 7 12:25 .profile
-rw-r--r-- 1 student student 741 Jun 7 12:19 .profile.bak
-rw-r--r-- 1 student student 741 Jun 7 13:12 .profile.bak1
student@vm1:~$
student@vm1:~$ ls .*
.bash_history .bash_logout .bashrc .lesshst .profile .profile.bak .profile.bak1
.:
ls.out
..:
student
Explanation
10
Prints out your current working directory, which is your home directory. Notice how
this differs from ~ in student@vm1:~, which also indicates that your are in your
home directory. That is because ~ is a shortcut for your home directory.
You get nothing here because there are only hidden files in your home directory.
Remember, hidden files are ones which names start with a dot.
Prints out all files in your home directory, because -a parameter tells ls to show all
files including hidden ones.
Prints out all files in your home directory in long format: permissions, owner,
group, size, timestamp (normally modification time) and filename.
Notice how files are now arranged by date, newest files being last. -t tells ls to sort
by time, and -r tells ls to reverse the sort.
Copies .bash_history to .bash_history1. It may seem cryptic to you, but
explanation is really simple. Bash has a feature called brace expansion, that it has a
set of rules which define how constructs like something{1,2,3} are treated. In our
case .bash_history{,1} expands into two arguments, namely .bash_history and
.bash_history1. Bash just takes a parameter before the brace, .bash_history in our
case, and adds everything which is in braces, separated by commas, to this
parameter consequentially. First addition becomes just .bash_history because first
argument in braces is void, there is no first argument. Next, Bash adds 1 because
that's the second argument, and voila! Resulting arguments, which are passed to cp
after expansion are -v .bash_history .bash_history1.
This might be obvious for you now. Copies recently created .bash_history1 to
.bash_history2.
Moves .bash_history1 to .bash_history2. Notice that it overwrites the destination
file without asking, so there is no more .bash_history2, gone!
Removes .bash_history2. Where is no warning, so beware. Also, always use -v
key.
Updates .bashrc timestamp to current date and time. This means that all .bashrc
time attributes, st_atime, st_mtime and st_ctime are set to current date and time.
You may become sure of this by typing in stat .bashrc.
Prints out all files in long format again. Notice how .bashrc timestamps changed.
Prints out files in you home directory in short format. Notice that you get listing of not
only of /home/student directory, but also of /home directory itself. Do not use this
construct with any command, especially rm, ever! Chances are, you will accidentally
cripple your system by deleting wrong files or changes access right to them.
11
Exercise 5. Bash: environment
variables, env, set, export
Consider the following: you want a program to print out your username. How will this
program know it? For this in Linux there are environment variables. What this means
is that there are many variables in your shell, many of which are set up
automatically, and every time you run a program, some of them are passed to this
program.
To elaborate on this:
Some variables are set just for your current shell. They are called local shell
variables. You can list them by typing set, a bash built-in command, which means
that no other program is started then you execute it. This command is processed by
bash itself.
Other variables are passed to every program you launch from your current shell.
They are called environment variables and can be listed by env program, which
means that then typing env you will see what variables every program you start gets.
You may want do dig a bit deeper. To do this, grasp the concept of a subshell which
is a child process that is created when you run a program and which becomes your
program.
Now you will learn how to create variables and how to use them.
Do this
1: foo='Hello World!'
2: echo $foo
3: set | grep foo
4: env | grep foo
5: export foo
6: env | grep foo
7: foo='ls -al'
8: $foo
What you should see
student@vm1:~$ foo='Hello World!'
student@vm1:~$ echo $foo
Hello World!
student@vm1:~$ set | grep foo
foo='Hello World!'
student@vm1:~$ env | grep foo
student@vm1:~$ export foo
student@vm1:~$ env | grep foo
foo=Hello World!
student@vm1:~$ foo='ls -al'
student@vm1:~$ $foo
total 36
drwxr-xr-x 2 student student 4096 Jun 14 12:23 .
drwxr-xr-x 3 root root 4096 Jun 6 21:49 ..
-rw------- 1 student student 4042 Jun 15 18:52 .bash_history
-rw-r--r-- 1 student student 220 Jun 6 21:48 .bash_logout
-rw-r--r-- 1 student student 3184 Jun 14 12:24 .bashrc
-rw------- 1 student student 50 Jun 15 18:41 .lesshst
-rw-r--r-- 1 student student 697 Jun 7 12:25 .profile
-rw-r--r-- 1 student student 741 Jun 7 12:19 .profile.bak
12
-rw-r--r-- 1 student student 741 Jun 7 13:12 .profile.bak1
Explanation
Creates a variable foo and places the line “Hello World!” into it.
Prints out variable foo.
Prints out list of all your environment variables, which is passed to grep, which prints
out only lines containing variable foo. Notice how variable foo is present.
Prints out all list of your environment variables which are passed to any program you
execute. Notice how variable foo is absent.
Makes variable foo available to all programs you execute from the current shell.
Now you can see that your variable is indeed available to all programs you execute.
Puts ls / into variable foo.
Executes a command which is contained in variable foo.
Extra credit
Type in and execute env and set. See how many different variable there are? No
worries, usually you can quickly understand what a variable does by googling it. Try
to do this.
Try typing:
set | egrep '^[[:alpha:]].*$'
Now, try just set. See what I did here? Quick explanation is that
egrep '^[[:alpha:]].*$'
prints out only those lines which start with alphanumeric character, that is every
letter, and omits any other lines. Don't bother too much with this for now. Don not
bother about | symbol either, I will explain it later on.
Read about difference between env and set here:
http://stackoverflow.com/questions/3341372/differnce-between-the-shell-andenvironment-variable-in-bash Remember, stackoverflow is your friend! I will repeat it
many times.
Try typing set FOO=helloworld bash -c 'echo $FOO'. Explanation is here:
http://stackoverflow.com/questions/10938483/bash-specifying-environmentvariables-for-echo-on-command-line. Again, don not bother with this too much, it will
come to you after lots of practice automatically, I promise.
Try this:
PS1_BAK=$PS1
PS1='Hello, world! $(pwd) > '
PS1=$PS1_BAK
Notice how I used $(pwd) to access command output as a variable. Now, type man
bash, / (yes, just a slash), PS1, press <ENTER>. You can now press n to go to the
next result. Skim through PROMPTING and type q to exit man. Now, navigate to
http://stackexchange.com/ and search bash PS1. Understand how those two
documentation sources differ.
13
Exercise 6. Bash: language settings,
LANG, locale, dpkg-reconfigure locales
In Linux language selection is as simple as an exporting of a variable. That is right,
programs decide how to talk to you by looking into this varibale. Of course, for this to
work program must support locales and have translation to your language available
and installed. Let us see how it works by installing French locale.
Now you will learn how to install and select a locale.
Do this
1: echo $LANG
2: locale
3: man man # press q to exit man
4: sudo dpkg-reconfigure locales
Now, select the fr_FR.UTF-8 locale by navigating through the list using cursor keys
and select the locale using space. Select en_US.UTF-8 as the default system
locale.
5: export LANG=fr_FR.UTF-8
6: echo $LANG
7: locale # press q to exit man
8: man man
9: export LANG=en_US.UTF-8
What you should see
student@vm1:~$ echo $LANG
en_US.UTF-8
student@vm1:~$ locale
LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
student@vm1:~$ man man
MAN(1)
Manual pager utils
MAN(1)
NAME
man - an interface to the on-line reference manuals
student@vm1:~$ sudo dpkg-reconfigure locales
---------------| Configuring locales |----------------------|
|
| Locales are a framework to switch between multiple
|
| languages and allow users to use their language,
|
| country, characters, collation order, etc.
|
|
|
14
| Please choose which locales to generate. UTF-8 locales |
| should be chosen by default, particularly for new
|
| installations. Other character sets may be useful for |
| backwards compatibility with older systems and software. |
|
|
|
<Ok>
|
|
|
-----------------------------------------------------------------------| Configuring locales |-------| Locales to be generated:
|
|
|
| [ ] fr_BE@euro ISO-8859-15
|
| [ ] fr_CA ISO-8859-1
|
| [ ] fr_CA.UTF-8 UTF-8
|
| [ ] fr_CH ISO-8859-1
|
| [ ] fr_CH.UTF-8 UTF-8
|
| [*] fr_FR ISO-8859-1
|
| [ ] fr_FR.UTF-8 UTF-8
|
| [ ] fr_FR@euro ISO-8859-15
|
|
|
|
|
|
<Ok>
<Cancel>
|
|
|
----------------------------------------------------------- Configuring locales ---------------------|
|
| Many packages in Debian use locales to display text in |
| the correct language for the user. You can choose a
|
| default locale for the system from the generated
|
| locales.
|
|
|
| This will select the default language for the entire |
| system. If this system is a multi-user system where not |
| all users are able to speak the default language, they |
| will experience difficulties.
|
|
|
|
<Ok>
|
|
|
------------------------------------------------------------------------ Configuring locales -------------| Default locale for the system environment: |
|
|
|
None
|
|
en_US.UTF-8
|
|
fr_FR.UTF-8
|
|
|
|
|
|
<Ok>
<Cancel>
|
|
|
----------------------------------------------Generating locales (this might take a while)...
en_US.UTF-8... done
fr_FR.UTF-8... done
Generation complete.
student@vm1:~$ export LANG=fr_FR.UTF-8
student@vm1:~$ echo $LANG
fr_FR.UTF-8
15
student@vm1:~$ locale
LANG=fr_FR.UTF-8
LANGUAGE=en_US:en
LC_CTYPE="fr_FR.UTF-8"
LC_NUMERIC="fr_FR.UTF-8"
LC_TIME="fr_FR.UTF-8"
LC_COLLATE="fr_FR.UTF-8"
LC_MONETARY="fr_FR.UTF-8"
LC_MESSAGES="fr_FR.UTF-8"
LC_PAPER="fr_FR.UTF-8"
LC_NAME="fr_FR.UTF-8"
LC_ADDRESS="fr_FR.UTF-8"
LC_TELEPHONE="fr_FR.UTF-8"
LC_MEASUREMENT="fr_FR.UTF-8"
LC_IDENTIFICATION="fr_FR.UTF-8"
LC_ALL=
student@vm1:~$ man man
MAN(1) Utilitaires de l'afficheur des pages de manuel MAN(1)
NOM
man - interface de consultation des manuels de
référence en ligne
student@vm1:~$ export LANG=en_US.UTF-8
student@vm1:~$
Explanation
Prints out your current LANG variable which is used by programs to determine which
language to use when interacting with you.
Prints out all locale variables which are used by programs for setting up number,
address, phone format, etc. according to the format of the specified country.
Shows you manual page about unix manual system. Notice how I used # to
comment an action, everything after # is not executed.
Executes a program for re-configuring your locales. Because this change is system
wide, you need to run this command as root, that's why there is sudo in front of
dpkg-reconfigure locales. Don't bother about sudo now, I'd set it up for you.
Exports LANG variable which is used to set all other locale variables.
Prints out LANG variable, you can see that it's changed as you would expect.
Prints out other locale variables which are changed also.
Shows you man manual page, in French.
Reverts LANG variable back to English.
Extra credit
Read manual page about locale. To do this, type in man locale.
Now, read a man 7 locale page. Notice how I used 7 here to call a man page about
conventions. If you want, read man man now to understand what other possible
codes are, or just wait for exercise which covers it.
16
Exercise 7. Bash: redirection, stdin,
stdout, stderr, <, >, >>, |, tee, pv
In Linux, everything is just a file. This means that, for console programs:
Keyboard is represented as a file, from which Bash reads your input.
Display is represented as a file, to which Bash writes its output.
Let us say you have a program which counts lines in a file. You can call it by typing
wc -l. Try this now. Nothing happened, right? It just hangs there. Wrong, it is waiting
for your input. This is an outline of what it does:
line_counter = 0
while end of file is not reached
read a line
add 1 to line_counter
print line_counter
So wc currently reads lines from /dev/tty, which is in current context your keyboard.
A line is given to wc each time you hit Enter. Type any several lines, and then hit
CTRL+D, which will produce EOF character for wc to understand that end of file is
reached. Now it will tell you how much lines you entered.
But what if you want to count lines in existing file? Well, where is redirection for that!
To feed an existing file on its input, type this: wc -l < .bash_history. You see, it
works! And it really is that simple! redirection is a mechanism which allows you tell a
program to redirect its input and/or output from keyboard and display to another file.
To do this, you can use these special commands then starting a program:
< — replace standard input (for example keyboard) with a file.
> — replace standard output (for example display) with a file. Warning! This
command overwrites contents of file you specify, so be careful.
>> — same as above, but instead of overwriting a file it writes to the end of it,
preserving already existing information in this file. Be careful not to confuse the two.
| — Take an output from one program and connect it to the other. This will be
elaborated on in next exercise.
Now you will learn how to redirect input and output of programs to files or another
programs.
Do this
1: sudo aptitude install pv
2: read foo < /dev/tty
3: Hello World!
4: echo $foo > foo.out
5: cat foo.out
6: echo $foo >> foo.out
7: cat foo.out
8: echo > foo.out
9: cat foo.out
10: ls -al | grep foo
11: ls -al | tee ls.out
12: dd if=/dev/zero of=~/test.img bs=1M count=10
13: pv ~/test.img | dd if=/dev/stdin of=/dev/null bs=1
14: rm -v foo.out
15: rm -v test.img
What you should see
student@vm1:~$ sudo aptitude install pv
17
The following NEW packages will be installed:
pv
0 packages upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/28.9 kB of archives. After unpacking 143 kB will be used.
Selecting previously deselected package pv.
(Reading database ... 39657 files and directories currently installed.)
Unpacking pv (from .../archives/pv_1.1.4-1_amd64.deb) ...
Processing triggers for man-db ...
Setting up pv (1.1.4-1) ...
student@vm1:~$ read foo < /dev/tty
Hello World!
student@vm1:~$ echo $foo > foo.out
student@vm1:~$ cat foo.out
Hello World!
student@vm1:~$ echo $foo >> foo.out
student@vm1:~$ cat foo.out
Hello World!
Hello World!
student@vm1:~$ echo > foo.out
student@vm1:~$ cat foo.out
student@vm1:~$ ls -al | grep foo
-rw-r--r-- 1 student student 1 Jun 15 20:03 foo.out
student@vm1:~$ ls -al | tee ls.out
total 44
drwxr-xr-x 2 student student 4096 Jun 15 20:01 .
drwxr-xr-x 3 root root 4096 Jun 6 21:49 ..
-rw------- 1 student student 4865 Jun 15 19:34 .bash_history
-rw-r--r-- 1 student student 220 Jun 6 21:48 .bash_logout
-rw-r--r-- 1 student student 3184 Jun 14 12:24 .bashrc
-rw-r--r-- 1 student student 1 Jun 15 20:03 foo.out
-rw------- 1 student student 50 Jun 15 18:41 .lesshst
-rw-r--r-- 1 student student 0 Jun 15 20:03 ls.out
-rw-r--r-- 1 student student 697 Jun 7 12:25 .profile
-rw-r--r-- 1 student student 741 Jun 7 12:19 .profile.bak
-rw-r--r-- 1 student student 741 Jun 7 13:12 .profile.bak1
-rw-r--r-- 1 student student 0 Jun 15 20:02 test.img
student@vm1:~$ dd if=/dev/zero of=~/test.img bs=1M count=10
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.0130061 s, 806 MB/s
student@vm1:~$ pv ~/test.img | dd if=/dev/stdin of=/dev/null bs=1
10MB 0:00:03 [3.24MB/s]
[=================================================================================>] 100%
10485760+0 records in
10485760+0 records out
10485760 bytes (10 MB) copied, 3.10446 s, 3.4 MB/s
student@vm1:~$ rm -v foo.out
removed `foo.out'
student@vm1:~$ rm -v test.img
removed `test.img'
student@vm1:~$
Explanation
Install pv (pipe viewer) program on your system which you will need later on.
18
Reads your input to a variable foo. This is possible because display and keyboard
are actually a teletype for the system. Yes, that teletype! Read more about tty online.
This is what you type.
Redirects contents of the foo variable to the foo.out file, creating the file in the
process or overwriting an existing file without warning removing all there was!!
Prints out foo.out contents.
Redirects contents of the foo variable to the foo.out file, creating the file in the
process or appending to an existing file. This is safe, but don not confuse the two, or
great sorrow will fall upon you.
Prints out foo.out contents again.
Redirects nothing to the foo.out, emptying file in the process.
Shows that the file is, indeed, empty.
Lists your directory and pipes the output to grep. This works by taking all ls -al
output and feeding it into grep. Again, this is called piping.
Lists your directory to the screen and to the ls.out. Very useful!
Creates a zeroed file with size of 10 Megabytes. Don't bother with how this works for
now.
Reads this file to /dev/null, which is an ultimate garbage can in your system, a void.
Everything which is written into it goes nowhere. Notice how pv shows you a
progress of reading the file, if you try to read it with another command instead you
won't know how long it will take to complete.
Removes foo.out. Always remember to clean up after yourself.
Removes test.img.
Extra credit
Read about piping and redirection on stackoverflow, again on stackoverflow and on
Greg's Wiki which is very useful resource indeed, remember it.
Open man page for bash, scroll down to REDIRECTION section and read it.
Read descriptions from man pv and man tee.
19
Exercise 8. Bash: more on redirection
and filtering: head, tail, awk, grep, sed
Now that you tasted Linux, I will introduce you to the Unix way. Behold.
This is the Unix philosophy: Write programs that do one thing and do it well. Write
programs to work together. Write programs to handle text streams, because that is a
universal interface.
What this means in practical terms is that to become proficient in Linux you need to
know how to take an output from one program and feed it to the other, usually
modifying it in the process. Normally you do this by gluing several programs together
using pipes which allow you connect output of one program to another. Like this:
What happens here is really simple. Almost every Linux program opens at lest these
3 files when started:
stdin — the standard input. This is from where program reads something.
stdout — the standard output. This is where program writes something.
stderr — the standard error. This is where program whines about wrong things that
do happen.
This is how it reads:
Start Program 1
Start reading data from keyboard
Start writing errors to display
Start Program 2
Start reading input from Program 1
Start writing errors to Display
Start Program 3
Start reading input from Program 2
Start writing errors to Display
Start writing data to Display
There is another way to picture what happens if you like South Park type of humor,
but beware: what was seen cannot be unseen! Warning! You will not be able to
unsee this.
Let us consider the following pipeline which takes ls -al output and prints out only file
names and file modification times:
ls -al | tr -s ' ' | cut -d ' ' -f 8,9
20
Here is an outline of what happens:
Start ls -al
Get list of files in current directory
Write errors to Display
Write output to Pipe
Start tr -s ' '
Read input from ls -al via Pipe
Leave only 1 space between fields
Write errors to Display
Write output to Pipe
Start cut -d ' ' -f 8,9
Read input from tr -s ' ' via Pipe'
Leave only fields 8 and 9, throw away anything else
Write errors to Display
Write output to Display
To further elaborate, this is what happens on each step:
Step 1: ls -al, we get a directory listing. Every column here is called a field.
student@vm1:~$ ls -al
total 52
drwxr-xr-x 2 student student 4096 Jun 18 14:16 .
drwxr-xr-x 3 root root 4096 Jun 6 21:49 ..
-rw------- 1 student student 4865 Jun 15 19:34 .bash_history
-rw-r--r-- 1 student student 220 Jun 6 21:48 .bash_logout
-rw-r--r-- 1 student student 3184 Jun 14 12:24 .bashrc
-rw-r--r-- 1 student student 64 Jun 18 14:16 hello.txt
-rw------- 1 student student 89 Jun 18 16:26 .lesshst
-rw-r--r-- 1 student student 634 Jun 15 20:03 ls.out
-rw-r--r-- 1 student student 697 Jun 7 12:25 .profile
-rw-r--r-- 1 student student 741 Jun 7 12:19 .profile.bak
-rw-r--r-- 1 student student 741 Jun 7 13:12 .profile.bak1
-rw------- 1 student student 666 Jun 18 14:16 .viminfo
Step 2: ls -al | tr -s ' '. We leave only one space between fields because cut does
not understand multiple spaces as a way to tell several fields apart.
student@vm1:~$ ls -al | tr -s ' '
total 52
drwxr-xr-x 2 student student 4096 Jun 18 14:16 .
drwxr-xr-x 3 root root 4096 Jun 6 21:49 ..
-rw------- 1 student student 4865 Jun 15 19:34 .bash_history
-rw-r--r-- 1 student student 220 Jun 6 21:48 .bash_logout
-rw-r--r-- 1 student student 3184 Jun 14 12:24 .bashrc
-rw-r--r-- 1 student student 64 Jun 18 14:16 hello.txt
-rw------- 1 student student 89 Jun 18 16:26 .lesshst
-rw-r--r-- 1 student student 634 Jun 15 20:03 ls.out
-rw-r--r-- 1 student student 697 Jun 7 12:25 .profile
-rw-r--r-- 1 student student 741 Jun 7 12:19 .profile.bak
-rw-r--r-- 1 student student 741 Jun 7 13:12 .profile.bak1
-rw------- 1 student student 666 Jun 18 14:16 .viminfo
Step 3: ls -al | tr -s ' ' | cut -d ' ' -f 8,9. We leave only fields eight and nine, which are
what we want.
student@vm1:~$ ls -al | tr -s ' ' | cut -d ' ' -f 8,9
14:16 .
21:49 ..
19:34 .bash_history
21:48 .bash_logout
12:24 .bashrc
14:16 hello.txt
16:26 .lesshst
21
20:03 ls.out
12:25 .profile
12:19 .profile.bak
13:12 .profile.bak1
14:16 .viminfo
Now you will learn how to take output (text stream) from one program and pass it
another, and how transform it.
Do this
1: ls -al | head -n 5
2: ls -al | tail -n 5
3: ls -al | awk '{print $8, $9}'
4: ls -al | awk '{print $9, $8}'
5: ls -al | awk '{printf "%-20.20s %s\n",$9, $8}'
6: ls -al | grep bash
7: ls -al > ls.out
8: cat ls.out
9: cat ls.out | sed 's/bash/I replace this!!!/g'
What you should see
student@vm1:~$ ls -al | head -n 5
total 52
drwxr-xr-x 2 student student 4096 Jun 18 14:16 .
drwxr-xr-x 3 root root 4096 Jun 6 21:49 ..
-rw------- 1 student student 4865 Jun 15 19:34 .bash_history
-rw-r--r-- 1 student student 220 Jun 6 21:48 .bash_logout
student@vm1:~$ ls -al | tail -n 5
-rw-r--r-- 1 student student 636 Jun 18 17:52 ls.out
-rw-r--r-- 1 student student 697 Jun 7 12:25 .profile
-rw-r--r-- 1 student student 741 Jun 7 12:19 .profile.bak
-rw-r--r-- 1 student student 741 Jun 7 13:12 .profile.bak1
-rw------- 1 student student 666 Jun 18 14:16 .viminfo
student@vm1:~$ ls -al | awk '{print $8, $9}'
14:16 .
21:49 ..
19:34 .bash_history
21:48 .bash_logout
12:24 .bashrc
14:16 hello.txt
16:26 .lesshst
17:52 ls.out
12:25 .profile
12:19 .profile.bak
13:12 .profile.bak1
14:16 .viminfo
student@vm1:~$ ls -al | awk '{print $9, $8}'
. 14:16
.. 21:49
.bash_history 19:34
.bash_logout 21:48
.bashrc 12:24
hello.txt 14:16
.lesshst 16:26
ls.out 17:52
.profile 12:25
.profile.bak 12:19
22
.profile.bak1 13:12
.viminfo 14:16
student@vm1:~$ ls -al | awk '{printf "%-20.20s %s\n",$9, $8}'
.
14:16
..
21:49
.bash_history
19:34
.bash_logout
21:48
.bashrc
12:24
hello.txt
14:16
.lesshst
16:26
ls.out
17:52
.profile
12:25
.profile.bak
12:19
.profile.bak1
13:12
.viminfo
14:16
student@vm1:~$ ls -al | grep bash
-rw------- 1 student student 4865 Jun 15 19:34 .bash_history
-rw-r--r-- 1 student student 220 Jun 6 21:48 .bash_logout
-rw-r--r-- 1 student student 3184 Jun 14 12:24 .bashrc
student@vm1:~$ ls -al > ls.out
student@vm1:~$ cat ls.out
total 48
drwxr-xr-x 2 student student 4096 Jun 18 14:16 .
drwxr-xr-x 3 root root 4096 Jun 6 21:49 ..
-rw------- 1 student student 4865 Jun 15 19:34 .bash_history
-rw-r--r-- 1 student student 220 Jun 6 21:48 .bash_logout
-rw-r--r-- 1 student student 3184 Jun 14 12:24 .bashrc
-rw-r--r-- 1 student student 64 Jun 18 14:16 hello.txt
-rw------- 1 student student 89 Jun 18 16:26 .lesshst
-rw-r--r-- 1 student student 0 Jun 18 17:53 ls.out
-rw-r--r-- 1 student student 697 Jun 7 12:25 .profile
-rw-r--r-- 1 student student 741 Jun 7 12:19 .profile.bak
-rw-r--r-- 1 student student 741 Jun 7 13:12 .profile.bak1
-rw------- 1 student student 666 Jun 18 14:16 .viminfo
student@vm1:~$ cat ls.out | sed 's/bash/I replace this!!!/g'
total 48
drwxr-xr-x 2 student student 4096 Jun 18 14:16 .
drwxr-xr-x 3 root root 4096 Jun 6 21:49 ..
-rw------- 1 student student 4865 Jun 15 19:34 .I replace this!!!_history
-rw-r--r-- 1 student student 220 Jun 6 21:48 .I replace this!!!_logout
-rw-r--r-- 1 student student 3184 Jun 14 12:24 .I replace this!!!rc
-rw-r--r-- 1 student student 64 Jun 18 14:16 hello.txt
-rw------- 1 student student 89 Jun 18 16:26 .lesshst
-rw-r--r-- 1 student student 0 Jun 18 17:53 ls.out
-rw-r--r-- 1 student student 697 Jun 7 12:25 .profile
-rw-r--r-- 1 student student 741 Jun 7 12:19 .profile.bak
-rw-r--r-- 1 student student 741 Jun 7 13:12 .profile.bak1
-rw------- 1 student student 666 Jun 18 14:16 .viminfo
Explanation
Prints out only 5 first entries in directory listing.
Prints out only 5 last entries in directory listing.
Prints out only modification time and file name. Notice how I used awk, which is
smarter than cut. Difference here is that while cut understands only single symbol
23
(space in our case) as a way to tell field apart (field separator), awk treats any
number of spaces and tabs as filed separator, so there is no need to use tr which
removes unnecessary spaces.
Prints out file name and modification time in this order. This again is something cat is
not able to do.
Prints out file name and modification time nicely. Notice how output looks much
clearer now.
Prints out only those lines from directory listing which contain the word “bash”.
Writes directory listing output to file ls.out.
Prints out ls.out. cat is simplest program available that allows you to print out a file
and nothing more. Despite being so simple it is very useful when constructing
complicated pipelines.
Prints out ls.out replacing all bash entries with I replace this!!! sed is one powerful
stream editor, which is very very very useful.
Extra credit
Open man pages for head, tail, awk, grep and sed. Do not be intimidated, just
remember that man pages are always there for you. With some practice you will be
able actually understand them.
Find grep options which allow to print out one line before and one line after the lines
it finds.
Google about awk printf command, try to understand how this works.
Read Useless Use of Cat Award. Try some examples from there.
24
Exercise 9. Bash: job control, jobs, fg
Linux is a multitasking operating system. This means that there are many programs
running at the same time. From user perspective this means that you are able to run
several programs simultaneously, and bash surely has tools to control multiple jobs
execution for you. To be able to use this feature you need to learn the following
commands:
<CTRL>+z — place currently running program in the background.
jobs — list all background programs.
fg — bring a program to foreground. fg takes a number which can be obtained from
jobs as an argument, or brings last suspended program to foreground if called
without parameters.
<CTRL>+c — stop execution of currently running programs at once. While I will not
use it in this exercise, I must say that it may be very useful at times.
Now you will learn how to control program execution by using tools built in bash.
Do this
1: less -S .profile
2: <CTRL+z>
3: less -S .bashrc
4: <CTRL+z>
5: less -S .bash_history
6: <CTRL+z>
7: jobs
8: fg
9: q
10: fg
11: q
12: fg
13: q
14: fg
15: jobs
What you should see
student@vm1:~$ less -S .profile
# exists.
# see /usr/share/doc/bash/examples/startup-files for
# the files are located in the bash-doc package.
# the default umask is set in /etc/profile; for setti
# for ssh logins, install and configure the libpam-um
#umask 022
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
[1]+ Stopped
less -S .profile
student@vm1:~$ less -S .bashrc
# for examples
# If not running interactively, don't do anything
25
[ -z "$PS1" ] && return
# don't put duplicate lines in the history. See bash(
# don't overwrite GNU Midnight Commander's setting of
HISTCONTROL=$HISTCONTROL${HISTCONTROL+:}ignoredups
# ... or force ignoredups and ignorespace
HISTCONTROL=ignoreboth
# append to the history file, don't overwrite it
shopt -s histappend
[2]+ Stopped
less -S .bashrc
student@vm1:~$ less -S .bash_history
echo Hello, $LOGNAME!
echo 'echo Hello, $LOGNAME!' >> .profile
cp .profile .profile.bak
tail .profile
ls -altr
history -w
ls -al
cat .profile
echo Hello, $LOGNAME!
echo 'echo Hello, $LOGNAME!' >> .profile
cp .profile .profile.bak
tail .profile
ls -altr
[3]+ Stopped
less -S .bash_history
student@vm1:~$ jobs
[1] Stopped
less -S .profile
[2]- Stopped
less -S .bashrc
[3]+ Stopped
less -S .bash_history
student@vm1:~$ fg
student@vm1:~$ fg
student@vm1:~$ fg
student@vm1:~$ fg
-bash: fg: current: no such job
student@vm1:~$ jobs
student@vm1:~$
Explanation
Opens .profile for viewing. Notice how I use -S parameter, which tells less to staring
with - -chop-long-lines option enabled.
Suspends less.
Opens .bashrc for viewing.
Suspends less.
Opens .bash_history for viewing.
Suspends less.
Prints out list of suspended programs.
Switches to last less.
Quits it.
Switches to second less.
Quits it.
Switches to first less.
Quits it.
26
Tries to switch to last program. There is no programs left, but you do this is to make
sure there are indeed none.
Prints out list of suspended programs. This is to make sure there are no background
jobs by seeing that jobs prints out empty output.
Extra credit
Open man bash, search for JOB CONTROL typing /, JOB CONTROL, <ENTER>,
and read it.
27
Exercise 10. Bash: program exit code
(return status)
Let us say that you want to copy a directory. You may do it by typing cp -vR
/old/dir/path /new/dir/path. After issuing this command you may want to know how
did it go. Was the directory copied? Or some error occurred due to the lack of space
in destination directory or something else that did go wrong?
To understand how it works you must understand how two programs may
communicate. Let us start with stating that bash is just another program, so
generally when you issued aforementioned cp command, one program (bash, which
is a parent process) called another (cp, which is child process).
In Linux there is a standard mechanism for getting information from child process to
parent process, and this mechanism is called exit status, or return code. By using
this mechanism a small number is passed from a child process (or callee, in our
case this is cp) to a parent process (or caller, which is bash in our case) when child
process finishes its work. When program encounters no errors during execution it
returns zero, 0. If some errors did occur, this code is non-zero. That simple. In Bash
this exit code is saved into ? environment variable, which as you know now can be
accessed as $?.
Let me reiterate what I said once more, now with outlines:
Bash waits for you input
Bash parses your input
Bash starts a program for you and waits for this program to exit
Program starts
Program does what you told it
Program generates the exit code
Program exits and returns this exit code to Bash
Bash sets this exit code to the variable ?
Now you will learn how to print out program exit status.
Do this
1: ls
2: echo $?
3: ls /no/such/dir
4: echo $?
What you should see
student@vm1:~$ ls
hello.txt ls.out
student@vm1:~$ echo $?
0
student@vm1:~$ ls /no/such/dir
ls: cannot access /no/such/dir: No such file or directory
student@vm1:~$ echo $?
2
student@vm1:~$
Explanation
Prints out a directory, successfully.
Prints out ls exit code, this is 0 which means that ls encountered no errors.
28
Tries to print out nonexistent directory, failing in the process of course.
Prints out ls /no/such/dir exit code, which is indeed non-zero.
Extra credit
Read Exit status section of man ls.
29
Exercise 11. Bash: wrapping up
Now that you have tasted how working in Linux using CLI feels, your next step is to open
your favorite text editor and make yourself the following table. Search those commands and
symbols meaning of which you do not know. Warning! For this to work you must type this
table by hand. Search for those terms and commands which are new to you.
Now you will learn how to grind something. And remember, no copy-pasting!
Terms
Term
Meaning
________________________________ ______________________________________
vim normal mode
vim command mode
CLI
Shell
Profile
File
File descriptor
Process
Program
Environment
Environment variable
Redirection
Pipe
Text stream
Stdin
Stdout
Stderr
EOF
Filtering
Job
Foreground job
Background job
Exit code
vim
Command
Meaning
_____________________________
______________________________________
vim
h
j
k
l
i
o
30
<ESCAPE>
x
dd
:wq
:q!
/
less
Command
_____________________________
less
j
k
q
--ch
/
&
Bash and Bash built-in commands
Command
_____________________________
echo
history
exit
pwd
=
$
?
set
env
export
$LANG
read
<CTRL>+z
<CTRL>+c
jobs
fg
Redirection
Command
_____________________________
>
<
>>
|
/dev/stdin
/dev/stdout
/dev/stderr
Meaning
______________________________________
Meaning
______________________________________
Meaning
______________________________________
31
Other programs you have learnt
Command
Meaning
_____________________________
______________________________________
man
ls
cat
dpkg-reconfigure
head
tail
grep
awk
sed
tee
dd
pv
locale
sudo
cp
mv
rm
touch
wc
After filling in the table, write every command on a post-it note and repeat before going to
sleep for a week. Yes, I mean it, shake dust from those pen and paper and do it.
32
Exercise 12. Documentation: man, info
Now that you have tasted Linux it is time to introduce online Linux documentation
facilities. You already know about man, because I told you to look things up in it.
Maybe you even had read man documentation page. So anyway, what do you need
to know about man to use it effectively?
To begin with, man pages are just compressed text files containing special markup
so man program will know how to format them for you. In Debian they are located in
/usr/share/man/. You can browse them by using zless. It is not even a program but
a shell script, which uncompresses files and invokes less.
Next, I will quote man page about its sections:
Executable programs or shell commands
System calls (functions provided by the kernel)
Library calls (functions within program libraries)
Special files (usually found in /dev)
File formats and conventions eg /etc/passwd
Games
Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7)
System administration commands (usually only for root)
Kernel routines [Non standard]
It is exactly what it says on the tin. To invoke appropriate man section just type its
section number, like: man 1. No worries if you do not understand what some section
means, for now you will need only sections 1 and 8, which are about programs and
system administrator utilities installed on your system. Additionally, you man already
know what man(7) is for.
This are standard sections of a man page:
NAME — program name and short description.
SYNOPSIS — short list of available program options
DESCRIPTION — description of a program and explanation of available parameters.
OPTIONS — some man pages keep explanation of available parameters here.
EXIT STATUS — every program returns a code which indicates its success or
failure. This code values are explained here.
RETURN VALUE — usually the same as EXIT STATUS.
ERRORS — known errors in a program.
ENVIRONMENT — environment variables. Set those before invoking the program.
FILES — usually, program configuration files.
VERSIONS — information about changes in program.
CONFORMING TO — notes about compatibility.
NOTES — information which an author of a man page did not know where to put.
BUGS — known errors in a program.
EXAMPLE — contains examples of program invocation. Very useful!
AUTHORS — who wrote the program.
SEE ALSO — related man pages.
Now about conventions, quoting again:
bold text — type exactly as shown.
italic text — replace with appropriate argument. This text mostly is displayed not
italic, but like underlined.
[-abc] — any or all arguments within [ ] are optional.
-a|-b — options delimited by | cannot be used together.
33
argument … — argument is repeatable.
[expression] … — entire expression within [ ] is repeatable.
I will illustrate this by example. man less shows this:
Well, looks kinda scary I must say. First 4 lines are easy, just type what is shown and
that is it:
1. less -?
2. less –help
3. less -V
4. less –version
Starting from line 5, as we can see, italic text is indeed shown as underlined. And, it
looks totally incomprehensible. Let us go through it line by line.
5. less [-[+]aBcCdeEfFgGiIJKLmMnNqQrRsSuUVwWX~] — this looks more
scary.
First, it is optional because all arguments are enclosed in [].
Second, when specifying an argument it must start with -. This is non-optional.
Third, after - you may specify optional modifier +, which meaning is explained further
in the manual.
Fourth, you can specify one or several of commands which are shown as sequence
of letters here. For example, you may type less -S .bashrc, or less -+S .bashrc, or
less -SG .bashrc .profile or less -+SG .bashrc .profile
6. [-b space] [-h lines] [-j line] [-k keyfile] — simple enough, you may specify any
of the keys shown -b, -h, -j, -k with parameters space, lines, line and keyfile
respectively, which are explained in further in the manual.
7. [-{oO} logfile] [-p pattern] [-P prompt] [-t tag] — almost the same as line 6. {oO} means that you may specify -o or -O, but not both at the same time.
8. [-T tagsfile] [-x tab,…] [-y lines] [-[z] lines] — again, almost the same as line 6. x tab,… means that you may specify several values after -x, for example -x9 or x9,17. -[z] lines means, that -z is optional, and you may just type less -10 instead of
less -z10.
9. [-# shift] [+[+]cmd] [- -] [filename]… — this is somewhat more cryptic. +[+]cmd
means that you may type less +cmd or less ++ cmd. - - is just a prefix.
34
[filename]… reads one-or-more and means that you may specify several files when
invoking less, for example less .bashrc, less .bashrc .profile, etc.
We are done! Not so scary, is it? Remember, because you are viewing manuals with
less, to search what some key means type /key<ENTER> or &key<ENTER>. For
example, to search what -T key means, type /-T<ENTER>.
Now I will give you list of useful man commands:
man -k . — list all man pages in your system. Not exactly very useful, but you may
want to mediate on this list sometime. Or you can just count them all by typing man k . | wc.
man -k [search string] — search something in man pages descriptions. Tye this:
man -k tty.
man -wK [search string] - search something in man page bodies. Try man -wK tty.
Well, that is it for man. Now, there is another useful documentation utility, info. The
command list is as follows:
info […] — invoke info. If you invoke it without arguments, it will take you to the
index page.
<UP>, <DOWN>, <LEFT>, <RIGHT> allows you to scroll text.
<ENTER> open the link under cursor. Links start with * .
<TAB> — jump to the next link in document.
u — go up one level.
p — go to previous page, just like in browser.
n — go to next pages.
q — close info.
To start info with already familiar to you as I hope, vi keys, type info –vi-keys. Now
you can scroll with j and k.
Extra credit
Type man man and try to decode SYNOPSIS section, which explains how it may be
invoked.
Type info and h, read info help section.
35
Exercise 13. Documentation: Google
Introduction to finding documentation
Now that you know how to work with online Linux documentation, I will tell you this:
“Online Linux documentation is good, but it just is not enough.” This means that man
pages are useful if you already familiar with how a particular program works, but are
very unhelpful when you do not.
To get yourself started you need to read a book or find a small recipe which allows
you get started which is called a “how to”. For example, to get started with Apache
web-server you may google for “apache how to”. That is ok, and that is what Google
is for, but now I will give you a big warning:
Do not follow any How To blindly, ever!
The correct way to use Google is this:
Find a “How To”.
Follow it, but read, or at least skim, through all man pages for programs about which
you do not know about. Also, read about all options in the howto which are unknown
to you. It is that important.
Not paste, but type most of commands, the hard way. It requires some effort, but
really helps to memorize them and even better understand what you are doing.
List of useful resources
Sometimes it is better to search a particular site instead of blindly typing stuff into
Google. This is list of the useful resources:
http://en.wikipedia.org is invaluable when getting initial information about some topic.
Its links section is even more invaluable.
http://stackexchange.com/ This is very useful site for finding information about usage
examples and use cases. StackExchange network includes several resources, of
which most useful to you are http://serverfault.com/ and
http://unix.stackexchange.com/. http://stackoverflow.com/ is a very useful resource
when you are doing bash scripting.
http://www.cyberciti.biz/ contains many useful “how to's” and examples.
Homepages of many programs provide good and sometimes great documentation.
For example this are for apache and ngnix, respectively:
http://httpd.apache.org/docs/, http://nginx.org/en/docs/.
http://tldp.org/ is The Linux Documentation Project and contains many in-depth
guides about different topics.
Search tips
Google has a query language which gives you ability to execute powerful queries.
This is main commands of this language:
(screen|tmux) how to — search for screen and tmux howtos at the same time.
Remember about shell parameter expansion? This is similar.
site:serverfault.com query — search something on this site only. You may search
several sites at once with (site:serverfault.com | site:stackexchange.com)
“a long query” — shows you only those pages which contain this query exactly.
-query — excludes something from search results.
Extra credit
36
Go to http://www.google.com/advanced_search and find out what else can be
searched. Try searching for file types and last updated pages.
37
Exercise 14. Package management:
Debian package management utility
aptitude
Now it is time to get the sacred knowledge of adding new programs to your Linux
system. The programs in Linux are called packages, and are usually installed from
network repositories by tools knows as package managers.
Package is typically a compressed program, and you install a package just like this:
aptitude install program . . . To avoid installation of malicious programs, all
packages are digitally signed by their creators, which means that if package is
modified after its creation package manager will not allow you to install it.
Package manager is a program which allows you install other program. Many
programs depend on other programs, for example a program which uses dialog
windows typically needs a program which knows how to draw those windows.
Package manager knows about this dependencies, and when you ask it to install a
particular programs it installs all programs which are needed for the one you asked
to work. Debian package manager is called aptitude.
Network repository is a site with many packages, readily available for installation.
This is an outline of typical program installation:
YOU
Search for available programs using package manager
Ask your package manager to install a program
Package manager
Looks up for all programs which are needed to install current one
Marks them for installation in package manager database
Installs all needed programs including the one you need
Downloads all needed programs
Extracts files from those packages to places on your system defined by FHS standard
For every program runs a special install script which allow it to perform initial actions:
Create a directory
Create a database
Generate default configuration file
...
Updates the system package database by modifying status of installed programs to installed
YOU
Are able to run you freshly installed program now
It is time to understand where extracted files go. In Linux all same types of files are
installed in the same locations. For example, executable files from all programs are
installed in /usr/bin, documentation from all programs in /usr/share/doc and so on.
This may sound a bit messy, but it is very useful. Which files go where is defined a
document called FHS standard, you can view it by invoking man 7 hier. I will show
you abbreviated version of The Filesystem Hierarchy Standard, Version 2.2 below:
/ – This is the root directory. This is where the whole tree starts.
/bin – This directory contains executable programs which are needed in single user
mode and to bring the up or repair it.
/boot – Contains static files for the boot loader. This directory only holds the files
which are needed the boot process. The map installer and configuration files should
go to /sbin and /etc.
/dev – Special or device files, which refer to physical devices. See mknod(1).
/etc – Contains configuration files which are local to the machine.
38
/home – On machines with home directories for users, these are usually beneath
this directory, directly o The structure of this directory depends on local
administration decisions.
/lib – This directory should hold those shared libraries that are necessary to boot the
system and to run commands in the root file system.
/media – This directory contains mount points for removable media such as CD and
DVD disks or USB sticks.
/mnt – This directory is a mount point for a temporarily mounted file system. In some
distributions, /mnt contains subdirectories intended to be used as mount points for
several temporary file systems.
/proc – This is a mount point for the proc file system, which provides information
about running processes and the kernel. This pseudo-file system is described in
more detail in proc(5).
/root – This directory is usually the home directory for the root user (optional).
/sbin – Like /bin, this directory holds commands needed to boot the system, but
which are usually not executed by normal users.
/srv – This directory contains site-specific data that is served by this system.
/tmp – This directory contains temporary files which may be deleted with no notice,
such as by a regular job or at system boot up.
/usr – This directory is usually mounted from a separate partition. It should hold only
sharable, read-only data, so that it can be mounted by various machines running
Linux.
/usr/bin – This is the primary directory for executable programs. Most programs
executed by normal users which are not needed for booting or for repairing the
system and which are not installed locally should be placed in this directory.
/usr/local – This is where programs which are local to the site typically go.
/usr/share – This directory contains subdirectories with specific application data, that
can be shared among different architectures of the same OS. Often one finds stuff
here that used to live in /usr/doc or /usr/lib or /usr/man.
/usr/share/doc – Documentation about installed programs.
/var – This directory contains files which may change in size, such as spool and log
files.
/var/log – Miscellaneous log files.
/var/spool – Spooled (or queued) files for various programs.
/var/tmp – Like /tmp, this directory holds temporary files stored for an unspecified
duration.
Well, that was big. But you do not need to memorize it, man hier 7 is always there
for you. For now you need to know only about /usr/bin, /usr/share and /var/log.
Let us talk about packages and package managers a little more. First, let us
reiterate:
Every program is called a package.
Package manager manages all you packages, that is installs and uninstalls them for
you.
To be able to do this, package managers holds a database of installed and available
packages.
Every package in this database has a status, which indicates whether package is
installed, if it can be updated and so on. You can print out currently installed
packages by typing dpkg -l. Example output is shown below:
student@vm1:~$ dpkg -l | head | less -S
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
39
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name
Version
Description
+++-=====================-============================================================================
ii acpi
1.5-2
displays information on ACPI devices
ii acpi-support-base 0.137-5
scripts for handling base ACPI events such as the power
ii acpid
1:2.0.7-1squeeze4 Advanced Configuration and Power Interface event daemon
As you can see, those statuses are shown in first three columns. From this output we
can tall that all package are desired to be installed, are indeed installed and there is
no error because third column is empty. Here is a list of all possible package
statuses.
First column. Desired action, what we want to do with package:
u = Unknown (an unknown state)
i = Install. The package is selected for installation.
r = The package is selected for deinstallation (i.e. we want to remove all files, except
configuration files).
p = Purge. The package is selected to be purged (i.e. we want to remove everything
from system directories, even configuration files).
h = A package marked to be on hold is not handled by dpkg, unless forced to do that
with option –force-hold.
Second column. Package status, in what state package currently is:
n = Not-installed. The package is not installed on your system.
c = Config-files. Only the configuration files of the package exist on the system.
H = Half-installed. The installation of the package has been started, but not
completed for some reason.
U = Unpacked. The package is unpacked, but not configured.
F = Half-configured. The package is unpacked and configuration has been started,
but not yet completed for some reason.
W = Triggers-awaiting. The package awaits trigger processing by another package.
t = Triggers-pending. The package has been triggered.
i = Installed. The package is unpacked and configured OK.
Third column. Something got wrong:
R = reinst-required. A package marked reinst-required is broken and requires
reinstallation. These packages cannot be removed, unless forced with option –forceremove-reinstreq.
Again, you don not need to memorize this, just remember info dpkg command
which will show you exactly this information. And do not bother with package
statuses for now, just remember that ii status means everything is ok with the
package.
Enough talking, let us install a program called midnight commander which is a file
manager, that is it allows you to visually navigate directories on your system and
perform such operations on your files as copying, renaming or deleting them.
Now you will learn how search, install and remove packages.
Do this
1: aptitude search mc | grep -i 'midnight commander'
2: sudo aptitude install mc
3: dpkg -L mc | grep '/usr/bin'
4: aptitude search mc | grep -i 'midnight commander'
5: mc
6: <F10><ENTER>
7: sudo aptitude remove mc
40
What you should see
student@vm1:~$ aptitude search mc | grep -i 'midnight commander'
p mc
- Midnight Commander - a powerful file manag
p mc-dbg
- Midnight Commander - a powerful file manag
student@vm1:/home/student# sudo aptitude install mc
The following NEW packages will be installed:
libglib2.0-0{a} libglib2.0-data{a} mc shared-mime-info{a}
0 packages upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,957 kB/5,157 kB of archives. After unpacking 17.0 MB will be used.
Do you want to continue? [Y/n/?] y
Get:1 http://mirror.yandex.ru/debian/ squeeze/main libglib2.0-0 amd64 2.24.2-1 [1,122 kB]
Get:2 http://mirror.yandex.ru/debian/ squeeze/main libglib2.0-data all 2.24.2-1 [994 kB]
Get:3 http://mirror.yandex.ru/debian/ squeeze/main shared-mime-info amd64 0.71-4 [841 kB]
Fetched 2,957 kB in 0s (4,010 kB/s)
Selecting previously deselected package libglib2.0-0.
(Reading database ... 24220 files and directories currently installed.)
Unpacking libglib2.0-0 (from .../libglib2.0-0_2.24.2-1_amd64.deb) ...
Selecting previously deselected package libglib2.0-data.
Unpacking libglib2.0-data (from .../libglib2.0-data_2.24.2-1_all.deb) ...
Selecting previously deselected package mc.
Unpacking mc (from .../mc_3%3a4.7.0.9-1_amd64.deb) ...
Selecting previously deselected package shared-mime-info.
Unpacking shared-mime-info (from .../shared-mime-info_0.71-4_amd64.deb) ...
Processing triggers for man-db ...
Setting up libglib2.0-0 (2.24.2-1) ...
Setting up libglib2.0-data (2.24.2-1) ...
Setting up mc (3:4.7.0.9-1) ...
Setting up shared-mime-info (0.71-4) ...
student@vm1:~$ aptitude search mc | grep -i 'midnight commander'
i mc
- Midnight Commander - a powerful file manag
p mc-dbg
- Midnight Commander - a powerful file manag
student@vm1:~$ mc
Left File Command Options Right
|< ~ ---------------------.[^]>||< ~ ---------------------.[^]>|
|'n Name | Size |Modify time||'n Name | Size |Modify time|
|/..
|P--DIR|un 6 21:49||/..
|P--DIR|un 6 21:49|
|/.aptitude | 4096|un 25 18:34||/.aptitude | 4096|un 25 18:34|
|/.mc
| 4096|un 25 18:41||/.mc
| 4096|un 25 18:41|
| .bash~story| 10149|un 21 12:01|| .bash~story| 10149|un 21 12:01|
| .bash~ogout| 220|un 6 21:48|| .bash~ogout| 220|un 6 21:48|
| .bashrc | 3184|un 14 12:24|| .bashrc | 3184|un 14 12:24|
| .lesshst | 157|un 25 11:31|| .lesshst | 157|un 25 11:31|
|----------------------------------------------------------------|
|UP--DIR
--UP--DIR
|
----------- 6367M/7508M (84%) -------------- 6367M/7508M (84%) -|
Hint: The homepage of GNU Midnight Commander: http://www.midnightstudent@vm1:~$
[^]
1Help 2Menu 3View 4Edit 5Copy 6Re~ov 7Mkdir 8De~te 9Pu~Dn
student@vm1:~$ sudo aptitude remove mc
The following packages will be REMOVED:
libglib2.0-0{u} libglib2.0-data{u} mc shared-mime-info{u}
0 packages upgraded, 0 newly installed, 4 to remove and 0 not upgraded.
Need to get 0 B of archives. After unpacking 17.0 MB will be freed.
Do you want to continue? [Y/n/?] y
(Reading database ... 24637 files and directories currently installed.)
41
Removing shared-mime-info ...
Removing mc ...
Removing libglib2.0-data ...
Removing libglib2.0-0 ...
Processing triggers for man-db ...
student@vm1:~$
Explanation
Search packages which name contains mc and show only whose packages which
contain “midnight commander” in description. grep -i means that grep should search
both lowercase and uppercase letters, without it grep will not show you lines
containing Midnight Commander because they start from uppercase letters. Notice
that mc has p status, which means that the desired action with this package is
purge, and because there is nothing in other two status columns, we can conclude
that this package is not installed. You man notice, that you did not install this
package to begin with, but it is ok, because not installed packages have purged
status by default.
Installs package “mc”. Because this change is system-wide this command needs to
be invoked as superuser, which is allowed to write to all directories in the sytem.
Also notice how debian package manager aptitude automatically installs packages
libglib2.0-0, libglib2.0-data and shared-mime-info which are needed for mc.
Shows you installed package executable files. As you can see, they go into /usr/bin.
Invokes mc.
Exits mc.
Removes mc. Notice that automatically installed packages are also removed
automatically. If after mc installation you would install something that needs those
packages, aptitude will keep them.
Extra creadit
Well, that was a big one. And here is more:
Type aptiutde search emacs. Find out what v means.
Read, or at list skim, through Chapter 2. Debian package management of Debian
manual.
42
Exercise 15. System boot: runlevels,
/etc/init.d, rcconf, update-rc.d
Firstly I will give an outline of typical system boot process:
YOU
Press power switch (or start a virtual machine)
Now computer has the control
This control is passed to BIOS
BIOS
Performs hardware-specific tasks
Makes POST, Power-On Self-Test, which tests your hardware
Detects installed hardware, such as hard disks, memory type and amount, ...
Initializes hardware by writing initial values into their memory
Finds a boot device, which is usually a hard disk
Read and executes MBR (Main Boot Record) located at the beginning of this disk
Control is not passed to MBR
MBR
MBR finds and executes GRUB (Grand Unified Bootloader)
Control is now passed to GRUB
GRUB
Finds available filesystems
Finds and reads its configuration file, to find out:
Where system is located
What system to boot
What other actions perform
Executes Linux Kernel, main part of Linux OS
Control is now passed to Linux Kernel
Linux Kernel
Finds and loads initrd, which is initial ram disk
initrd contains necessary drivers which allow to access and mount real filesystems
Mounts the root file system, which is specified in GRUB config file
Executes /sbin/init, a special program which starts all the others
Control is now passed to init
init
Looks at the /etc/inittab to determine desired run level
Loads all programs appropriate for this runlevel
All programs from /etc/rc.d/rc2.d/ are loaded, because 2 is default Debian runlevel
SSH and TTY are started so you are able to connect to your computer
Booting up is now finished
YOU
Connect to your computer using SSH
SSH daemon executes bash shell for you
You can now type stuff
You are in control once again
For now we are interested only in “init” and “runlevel” stages, so I will give you a
general overview of how the system starts up and automatically starts some
programs. First, a little terminology:
Daemon — a program which runs in background all the time. This means that it does
not care if you are logged into the system, and usually you do not need to start it
manually, because daemond are started automatically when computer boots up.
Runlevel — a mode of system operation. Basically, this is just numbers which are
fed to init program, which knows which daemons are associated with each number,
and startd and stops those daemons as needed.
In Debian there are the following runlevels:
43
ID Description
S This executed then system is powered on.
0 Halt, this defines which actions are executed when system is shutting down.
Single-User mode, this is a special mode for troubleshooting. In this mode most
1
daemons are not automatically started.
2Full Multi-User, configured daemon start in this mode.
5
6 Reboot. Like halt, but instead of powering down system reboots.
But how does init know? Well, where are special directories for this:
student@vm1:/etc$ find /etc -type d -name 'rc*' 2>/dev/null | sort
/etc/rc0.d
/etc/rc1.d
/etc/rc2.d
/etc/rc3.d
/etc/rc4.d
/etc/rc5.d
/etc/rc6.d
/etc/rcS.d
As you might guess, each number and S corresponds to a run level from this table.
Let us list one of those directories, which start all needed daemons on normal boot:
student@vm1:/etc$ ls -al /etc/rc2.d | awk '{printf "%-15.15s %-3.3s %s\n",$9,$10,$11}'
.
..
README
S14portmap
-> ../init.d/portmap
S15nfs-common -> ../init.d/nfs-common
S17rsyslog
-> ../init.d/rsyslog
S17sudo
-> ../init.d/sudo
S18acpid
-> ../init.d/acpid
S18atd
-> ../init.d/atd
S18cron
-> ../init.d/cron
S18exim4
-> ../init.d/exim4
S18ssh
-> ../init.d/ssh
S20bootlogs -> ../init.d/bootlogs
S21rc.local -> ../init.d/rc.local
S21rmnologin -> ../init.d/rmnologin
S21stop-bootlog -> ../init.d/stop-bootlogd
As you can see, files in this directory are just symbolic links to actual startup scripts.
Let us look at one of this link more closely: S18ssh → ../init.d/ssh. Here is what we
are able to say about this file:
It is a link to the file ./init.d/ssh
It starts with S which means start. Each script used in Debian start-up system has at
least 2 parameters, start and stop. Now we can say that when our system switches
to runlevel 2 this script is executed with action start.
It has a number 18. Scripts in rc directories are executed in alphabetical order, so
now we understand that before starting ssh, system starts portmap, nfs-common,
rsyslog, and sudo. rsyslog is a system loggin daemon, and ssh in particular want
to log who and when accessed the system, so it needs rsyslog to be running before
starting up.
Now you will learn how to list enabled services (daemons), and enable and disable
services (daemons).
Do this
1: sudo aptitude install rcconf
44
2: ls -al /etc/rc2.d
3: sudo rcconf --list
4: sudo update-rc.d exim4 disable
5: ls -al /etc/rc2.d
6: sudo rcconf --list
7: sudo update-rc.d exim4 enable
8: ls -al /etc/rc2.d
9: sudo rcconf --list
What you should see
student@vm1:/var/log$ sudo aptitude install rcconf
The following NEW packages will be installed:
rcconf
0 packages upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/23.9 kB of archives. After unpacking 135 kB will be used.
Selecting previously deselected package rcconf.
(Reading database ... 24239 files and directories currently installed.)
Unpacking rcconf (from .../archives/rcconf_2.5_all.deb) ...
Processing triggers for man-db ...
Setting up rcconf (2.5) ...
student@vm1:/etc$ ls -al /etc/rc2.d
total 12
drwxr-xr-x 2 root root 4096 Jun 27 11:42 .
drwxr-xr-x 68 root root 4096 Jun 25 18:43 ..
-rw-r--r-- 1 root root 677 Mar 27 05:50 README
lrwxrwxrwx 1 root root 17 Jun 4 11:53 S14portmap -> ../init.d/portmap
lrwxrwxrwx 1 root root 20 Jun 4 11:53 S15nfs-common -> ../init.d/nfs-common
lrwxrwxrwx 1 root root 17 Jun 4 11:53 S17rsyslog -> ../init.d/rsyslog
lrwxrwxrwx 1 root root 14 Jun 15 19:02 S17sudo -> ../init.d/sudo
lrwxrwxrwx 1 root root 15 Jun 4 11:53 S18acpid -> ../init.d/acpid
lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18atd -> ../init.d/atd
lrwxrwxrwx 1 root root 14 Jun 4 11:53 S18cron -> ../init.d/cron
lrwxrwxrwx 1 root root 15 Jun 27 11:42 S18exim4 -> ../init.d/exim4
lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18ssh -> ../init.d/ssh
lrwxrwxrwx 1 root root 18 Jun 4 11:53 S20bootlogs -> ../init.d/bootlogs
lrwxrwxrwx 1 root root 18 Jun 4 11:53 S21rc.local -> ../init.d/rc.local
lrwxrwxrwx 1 root root 19 Jun 4 11:53 S21rmnologin -> ../init.d/rmnologin
lrwxrwxrwx 1 root root 23 Jun 4 11:53 S21stop-bootlogd -> ../init.d/stop-bootlogd
student@vm1:/etc$ sudo rcconf --list
rsyslog on
ssh on
bootlogs on
portmap on
sudo on
nfs-common on
udev on
console-setup on
kbd on
exim4 on
keyboard-setup on
acpid on
cron on
atd on
procps on
module-init-tools on
student@vm1:/etc$ sudo update-rc.d exim4 disable
45
update-rc.d: using dependency based boot sequencing
insserv: warning: current start runlevel(s) (empty) of script `exim4' overwrites defaults (2 3 4 5).
insserv: warning: current stop runlevel(s) (0 1 2 3 4 5 6) of script `exim4' overwrites defaults (0 1 6).
student@vm1:/etc$ ls -al /etc/rc2.d
total 12
drwxr-xr-x 2 root root 4096 Jun 27 11:43 .
drwxr-xr-x 68 root root 4096 Jun 25 18:43 ..
lrwxrwxrwx 1 root root 15 Jun 27 11:43 K01exim4 -> ../init.d/exim4
-rw-r--r-- 1 root root 677 Mar 27 05:50 README
lrwxrwxrwx 1 root root 17 Jun 4 11:53 S14portmap -> ../init.d/portmap
lrwxrwxrwx 1 root root 20 Jun 4 11:53 S15nfs-common -> ../init.d/nfs-common
lrwxrwxrwx 1 root root 17 Jun 4 11:53 S17rsyslog -> ../init.d/rsyslog
lrwxrwxrwx 1 root root 14 Jun 15 19:02 S17sudo -> ../init.d/sudo
lrwxrwxrwx 1 root root 15 Jun 4 11:53 S18acpid -> ../init.d/acpid
lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18atd -> ../init.d/atd
lrwxrwxrwx 1 root root 14 Jun 4 11:53 S18cron -> ../init.d/cron
lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18ssh -> ../init.d/ssh
lrwxrwxrwx 1 root root 18 Jun 4 11:53 S20bootlogs -> ../init.d/bootlogs
lrwxrwxrwx 1 root root 18 Jun 4 11:53 S21rc.local -> ../init.d/rc.local
lrwxrwxrwx 1 root root 19 Jun 4 11:53 S21rmnologin -> ../init.d/rmnologin
lrwxrwxrwx 1 root root 23 Jun 4 11:53 S21stop-bootlogd -> ../init.d/stop-bootlogd
student@vm1:/etc$ sudo rcconf --list
rsyslog on
ssh on
bootlogs on
portmap on
sudo on
nfs-common on
udev on
console-setup on
kbd on
keyboard-setup on
acpid on
cron on
atd on
procps on
module-init-tools on
exim4 off
student@vm1:/etc$ sudo update-rc.d exim4 enable
update-rc.d: using dependency based boot sequencing
student@vm1:/etc$ ls -al /etc/rc2.d
total 12
drwxr-xr-x 2 root root 4096 Jun 27 11:43 .
drwxr-xr-x 68 root root 4096 Jun 25 18:43 ..
-rw-r--r-- 1 root root 677 Mar 27 05:50 README
lrwxrwxrwx 1 root root 17 Jun 4 11:53 S14portmap -> ../init.d/portmap
lrwxrwxrwx 1 root root 20 Jun 4 11:53 S15nfs-common -> ../init.d/nfs-common
lrwxrwxrwx 1 root root 17 Jun 4 11:53 S17rsyslog -> ../init.d/rsyslog
lrwxrwxrwx 1 root root 14 Jun 15 19:02 S17sudo -> ../init.d/sudo
lrwxrwxrwx 1 root root 15 Jun 4 11:53 S18acpid -> ../init.d/acpid
lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18atd -> ../init.d/atd
lrwxrwxrwx 1 root root 14 Jun 4 11:53 S18cron -> ../init.d/cron
lrwxrwxrwx 1 root root 15 Jun 27 11:43 S18exim4 -> ../init.d/exim4
lrwxrwxrwx 1 root root 13 Jun 4 11:53 S18ssh -> ../init.d/ssh
lrwxrwxrwx 1 root root 18 Jun 4 11:53 S20bootlogs -> ../init.d/bootlogs
lrwxrwxrwx 1 root root 18 Jun 4 11:53 S21rc.local -> ../init.d/rc.local
lrwxrwxrwx 1 root root 19 Jun 4 11:53 S21rmnologin -> ../init.d/rmnologin
46
lrwxrwxrwx 1 root root 23 Jun 4 11:53 S21stop-bootlogd -> ../init.d/stop-bootlogd
student@vm1:/etc$ sudo rcconf --list
rsyslog on
ssh on
bootlogs on
portmap on
sudo on
nfs-common on
udev on
console-setup on
kbd on
exim4 on
keyboard-setup on
acpid on
cron on
atd on
procps on
module-init-tools on
student@vm1:/etc$
Explanation
Installs rcconf package which allows you to easily manage runlevels.
Prints out directory containing startup scripts for runlevel 2. Mail server exim4 is
enabled for now.
Just prints out services for the same runlevel. Notice that there are several services
which are not shown because they are considered system services. rcconf –list –
expert will list them all and many more which reside on different runlevels.
Disables automatic startup of exim4, the mail server.
Prints out directory containing startup scripts for runlevel 2. exim4 startup script is
now renamed from S18exim4 to K01exim4 which means that exim4 is stopped
(killed) when entering this runlevel. If exim4 was not running to begin with, nothing
happens.
Prints out services for runlevel 2. Service exim4 is now off.
Enables automatic startup of exim4.
Prints out directory containing startup scripts for runlevel 2 once more, exim4 in
enabled again.
Prints out services for runlevel 2. Status of exim4 changed to on as expected.
Extra credit
Read about Debian boot process here: http://www.debian.org/doc/manuals/debianreference/ch03.en.html
Try this: aptitude install sysv-rc-conf, sysv-rc-conf –list. Read man sysv-rcconf.
47
Exercise 16. Processes: working with
proccesses, ps, kill
A program in its simplest is a file on you hard disk which contain instructions for your
central processor to execute. When you start it, it is copied to memory and control is
passed to it. Executed program is called a process. In multitasking operating
systems like Linux you may start many instances of a program, so may start many
processes from one program which all will be running (executing) at the same time.
This is an outline of what happens when you running ls:
YOU
Type in ls and its arguments into your terminal emulator and press <ENTER>
Control is now passed to Bash
Bash
Locates ls on your hard disk
Forks itself to Bash clone, that is clones itself to the new location in memory
Becomes parent process to Bash clone
Control is now passed to the Bash clone
Bash clone
Becomes child process to Bash
Preserves parent Bash process environment
Knows that it is it a clone and reacts accordingly
Overwrites itself with ls
Control is now passed to ls
ls
Prints out a directory listing for you or returns an error
Returns exit code
Control is now passed to Bash
Bash
Assigns ls exit code to ? variable
Waits for your input
YOU
Are able to type something once again
Some process are not interactive like ls, but just work quietly in the background, like
ssh. Processes have number of possible states and there is a number of operations
which you may perform on them by means of the signal mechanism.
Firstly let us talk about states. If you type ps ax –forest it will print out all processes
and you will get something like this (some hardware-related processes skipped):
student@vm1:/etc$ ps --forest ax
PID TTY
STAT TIME COMMAND
1?
Ss 0:16 init [2]
297 ?
S<s 0:00 udevd --daemon
392 ?
S< 0:00 \_ udevd --daemon
399 ?
S< 0:00 \_ udevd --daemon
691 ?
Ss 0:00 /sbin/portmap
703 ?
Ss 0:00 /sbin/rpc.statd
862 ?
Sl 0:00 /usr/sbin/rsyslogd -c4
886 ?
Ss 0:00 /usr/sbin/atd
971 ?
Ss 0:00 /usr/sbin/acpid
978 ?
Ss 0:01 /usr/sbin/cron
1177 ?
Ss 0:00 /usr/sbin/sshd
6671 ?
Ss 0:00 \_ sshd: student [priv]
6675 ?
S
0:00
\_ sshd: student@pts/0
6676 pts/0 Ss 0:00
\_ -bash
7932 pts/0 R+ 0:00
\_ ps --forest ax
1191 ?
Ss 0:00 /usr/sbin/exim4 -bd -q30m
48
1210 tty2
1211 tty3
1212 tty4
1213 tty5
1214 tty6
6216 tty1
Ss+
Ss+
Ss+
Ss+
Ss+
Ss+
0:00 /sbin/getty 38400 tty2
0:00 /sbin/getty 38400 tty3
0:00 /sbin/getty 38400 tty4
0:00 /sbin/getty 38400 tty5
0:00 /sbin/getty 38400 tty6
0:00 /sbin/getty 38400 tty1
Let us go through this list column py column:
PID — process ID. Each process has unique number associated with it, which
serves for uniquely identifying it. This means no two processes can ever have the
same PID.
TTY — teletype emulator associated with the process, which allows a process to
exchange information with you.
STAT — current process status. This will be descussed in detail below.
TIME — this is the amount of time in minutes and seconds this process is executed
on CPU.
COMMAND — this is program name with arguments. Notice how /usr/sbin/sshd is
parent of sshd: student which in turn is parent of sshd: student@pts/0 which in
turn is parent of bash which in turn is parent of ps –forest ax. You need to go
deeper!
Now let us discuss possible process states, which I took from PROCESS STATE
CODES of man ps:
STATE Description
Uninterruptible sleep (usually IO). Process is busy or hung, and does not
D
respond to signals, for example beacause hard disk had crashed and read
operation can not be completed.
R
Running or runnable (on run queue). Process is being executed right now.
Interruptible sleep (waiting for an event to complete). For example terminal
S
processes and Bash are often in this state, waiting for you to type in
something.
T
Stopped, either by a job control signal or because it is being traced.
W
paging (not valid since the 2.6.xx kernel, so do not bother about this).
X
dead (should never be seen).
Defunct (“zombie”) process, terminated but not reaped by its parent. This
Z
happens with incorrectly terminated processes, or processes whos pared
terminated erroneously.
<
high-priority (not nice to other users)
N
low-priority (nice to other users)
L
has pages locked into memory (for real-time and custom IO)
is a session leader. Related processes in Linux are treated as a unit, and
s
have shared Session ID (SID). If Process ID (PID) = Session ID (SID), this
process will be a Session Leader.
l
is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)
is in the foreground process group. Such procceses are allowed to input and
+
output to the teletype emulator, tty.
Now let us talk about a way to communicate with all those process. You can do it by
sending them signals. Signal may be thought like a way to kick a process in the butt
so process will hear you and make what you want it to. This is abbreviated list of
possible signals which I took from SIGNALS section of man kill:
49
Signal Num Action Description
0
0
n/a
Exit code indicates if a signal may be sent
HUP 1
exit
Hangup on controlling terminal or parent process died
INT
2
exit
Interrupt from keyboard
QUIT 3
core Quit from keyboard
ILL
4
core Illegal instruction
TRAP 5
core Trace/breakpoint trap
ABRT 6
core Abort signal from abort(3)
FPE 8
core Floating point exception
KILL 9
exit
Non-catchable, non-ignorable kill
SEGV 11 core Invalid memory reference
PIPE 13 exit
Broken pipe: write to pipe with no readers
ALRM 14 exit
Timer signal from alarm(2)
TERM 15 exit
Terminate process
Again, do not be intimidated with not understanding, for now you just need to know
about HUP, TERM and KILL. There is even a song about KILL signal, named Kill
dash nine. Also, notice this abort(3) and alarm(2) entries? They mean that you may
read corresponding man pages by typing man 3 abort and man 2 alarm.
Now you will learn how to list running processes and send signals to them.
Do this
1: ps x
2: ps a
3: ps ax
4: ps axue --forest
5: dd if=/dev/zero of=~/test.img bs=1 count=$((1024*1024*1024)) &
6: kill -s USR1 $!
7: <ENTER>
8: kill -s USR1 $!
9: <ENTER>
10: kill -s TERM $!
11: <ENTER>
What you should see
student@vm1:/etc$ ps x
PID TTY STAT TIME COMMAND
6675 ?
S 0:00 sshd: student@pts/0
6676 pts/0 Ss 0:00 -bash
8193 pts/0 R+ 0:00 ps x
student@vm1:/etc$ ps a
PID TTY STAT TIME COMMAND
1210 tty2 Ss+ 0:00 /sbin/getty 38400 tty2
1211 tty3 Ss+ 0:00 /sbin/getty 38400 tty3
1212 tty4 Ss+ 0:00 /sbin/getty 38400 tty4
1213 tty5 Ss+ 0:00 /sbin/getty 38400 tty5
1214 tty6 Ss+ 0:00 /sbin/getty 38400 tty6
6216 tty1 Ss+ 0:00 /sbin/getty 38400 tty1
6676 pts/0 Ss 0:00 -bash
8194 pts/0 R+ 0:00 ps a
student@vm1:/etc$ ps ax
PID TTY STAT TIME COMMAND
50
1?
Ss 0:16 init [2]
--- skipped --- skipped --- skipped --691 ?
Ss 0:00 /sbin/portmap
703 ?
Ss 0:00 /sbin/rpc.statd
862 ?
Sl 0:00 /usr/sbin/rsyslogd -c4
886 ?
Ss 0:00 /usr/sbin/atd
971 ?
Ss 0:00 /usr/sbin/acpid
978 ?
Ss 0:01 /usr/sbin/cron
1177 ?
Ss 0:00 /usr/sbin/sshd
1191 ?
Ss 0:00 /usr/sbin/exim4 -bd -q30m
1210 tty2 Ss+ 0:00 /sbin/getty 38400 tty2
1211 tty3 Ss+ 0:00 /sbin/getty 38400 tty3
1212 tty4 Ss+ 0:00 /sbin/getty 38400 tty4
1213 tty5 Ss+ 0:00 /sbin/getty 38400 tty5
1214 tty6 Ss+ 0:00 /sbin/getty 38400 tty6
6216 tty1 Ss+ 0:00 /sbin/getty 38400 tty1
6671 ?
Ss 0:00 sshd: student [priv]
6675 ?
S 0:00 sshd: student@pts/0
6676 pts/0 Ss 0:00 -bash
8198 pts/0 R+ 0:00 ps ax
student@vm1:/etc$ ps axue --forest
USER
PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
--- skipped --- skipped --- skipped --root
1 0.0 0.0 8356 820 ?
Ss Jun06 0:16 init [2]
root
297 0.0 0.0 16976 1000 ?
S<s Jun06 0:00 udevd --daemon
root
392 0.0 0.0 16872 840 ?
S< Jun06 0:00 \_ udevd --daemon
root
399 0.0 0.0 16872 836 ?
S< Jun06 0:00 \_ udevd --daemon
daemon 691 0.0 0.0 8096 532 ?
Ss Jun06 0:00 /sbin/portmap
statd 703 0.0 0.0 14384 868 ?
Ss Jun06 0:00 /sbin/rpc.statd
root
862 0.0 0.1 54296 1664 ?
Sl Jun06 0:00 /usr/sbin/rsyslogd -c4
daemon 886 0.0 0.0 18716 436 ?
Ss Jun06 0:00 /usr/sbin/atd
root
971 0.0 0.0 3920 644 ?
Ss Jun06 0:00 /usr/sbin/acpid
root
978 0.0 0.0 22400 880 ?
Ss Jun06 0:01 /usr/sbin/cron
root 1177 0.0 0.1 49176 1136 ?
Ss Jun06 0:00 /usr/sbin/sshd
root 6671 0.0 0.3 70496 3284 ?
Ss Jun26 0:00 \_ sshd: student [priv]
student 6675 0.0 0.1 70496 1584 ?
S Jun26 0:00 \_ sshd: student@pts/0
student 6676 0.0 0.6 23644 6536 pts/0 Ss Jun26 0:00
\_ -bash LANG=en_US.UTF-8 USER=student
LOGNAME=student HOM
student 8199 0.0 0.1 16312 1088 pts/0 R+ 17:07 0:00
\_ ps axue --forest TERM=screen-bce
SHELL=/bin/bas
101
1191 0.0 0.1 44148 1076 ?
Ss Jun06 0:00 /usr/sbin/exim4 -bd -q30m
root 1210 0.0 0.0 5932 616 tty2 Ss+ Jun06 0:00 /sbin/getty 38400 tty2
root 1211 0.0 0.0 5932 612 tty3 Ss+ Jun06 0:00 /sbin/getty 38400 tty3
root 1212 0.0 0.0 5932 612 tty4 Ss+ Jun06 0:00 /sbin/getty 38400 tty4
root 1213 0.0 0.0 5932 612 tty5 Ss+ Jun06 0:00 /sbin/getty 38400 tty5
root 1214 0.0 0.0 5932 616 tty6 Ss+ Jun06 0:00 /sbin/getty 38400 tty6
root 6216 0.0 0.0 5932 612 tty1 Ss+ Jun14 0:00 /sbin/getty 38400 tty1
student@vm1:/etc$ dd if=/dev/zero of=~/test.img bs=1 count=$((1024*1024*1024)) &
[1] 8200
student@vm1:/etc$ kill -s USR1 $!
student@vm1:/etc$ 1455424+0 records in
1455424+0 records out
1455424 bytes (1.5 MB) copied, 1.76646 s, 824 kB/s
student@vm1:/etc$ kill -s USR1 $!
student@vm1:/etc$ 3263060+0 records in
3263060+0 records out
51
3263060 bytes (3.3 MB) copied, 3.94237 s, 828 kB/s
student@vm1:/etc$ kill -s TERM $!
student@vm1:/etc$
[1]+ Terminated
dd if=/dev/zero of=~/test.img bs=1 count=$((1024*1024*1024))
student@vm1:/etc$
Explanation
Prints out those processes owned (started by) you.
Prints out only processes associated with a terminal (tty) and those owned (started
by) you.
Prints out all processes currently running.
Prints out all running processes in tree form and include additional information such
as associated username and environment where available. Notice that this
information is available only for processes owned (started by) you. To view
environment information for all process type in sudo ps axue –forest instead.
Starts creating a zero-filled file (filled with null characters, do not bother for now) and
is sent to background by specifying & in the end.
Queries dd for status.
Because bash is only able to print out something in response for your input, you
need to press <ENTER> (issue empty command).
Queries dd for status again.
Again you need to press <ENTER> to see the output.
Sends dd termination signal, so dd quits.
To see that this indeed had happened you need to press <ENTER> once again.
Extra credit
Read man ps, man kill.
Read The Life Cycle of Processes and study this picture Process flow.
Print and fill in Signal table. You may use Documentation from kernel.org.
52
Exercise 17. Job schedulers: cron, at
Often a need arises to execute a program on schedule. For example let us imagine
that you need to make a copy of your work every midnight. To accomplish this in
Linux there is a special program called cron. It is a demon, which means that is
starts when computer is booted up and sits silently in the background, executing
other programs for you when time comes. Cron has several configuration files,
system-wide, and one per each user. By default users do not have crontabs,
because nothing is scheduled for them. This are cron configuration file locations:
/etc/crontab — system-wide cron configuration file.
/var/spool/cron/crontabs/ — directory for storing user configuration files.
Now let us talk about cron configuration file format. If you run cat /etc/crontab you
will see this:
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
25 6 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7 root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6 1 * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
Its syntax is simple enough. Let us take the line
47 6
* * 7 root
test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly
and take it apart:
17
# On 17-minute of every hour
*
# Every day of month
*
# Every month of the year
*
# Every weekday
root
# As user root
cd /
# Execute command 'cd /'
&&
# If 'cd /' completed successfully, then
run-parts --report /etc/cron.hourly # Execute command 'run-parts --report /etc/cron.hourly'
Now I will sum up cron format:
* * * * * user
command to be executed
T T T T T (for system
| | | | |
crontab only)
| | | | |
| | | | '----- day of week (0 - 6) (0 is Sunday, or use names)
| | | '---------- month of year (1 - 12)
| | '--------------- day of month (1 - 31)
| '-------------------- hour (0 - 23)
'------------------------- min (0 - 59)
This is abbreviated list of possible characters for time specification:
Asterisk (*) — all values in the field, e.g. * in minutes field means every minute.
Slash (/) — defines increments of ranges. For example, 30-40/3 means run program
on 30-th minute and every 3 minutes thereafter until 40-th minute.
Percent (%) — in command field, all data after percent will be sent to the command
as standard input. Do not bother with this for now.
53
Comma (,) — specify a list, e.g. 30,40 in minutes field means 30th and 40th minute.
Hyphen (-) — a range. For example, 30-40 in minutes field means every minute
between 30th and 40th minute.
L — specify last something, for example it allows you specify last day of month.
Now I will give you more some examples:
#m
h dom mon dow user
command
# Every minute, every hour, every day of month, every month of year, every day of week
*
* * * * root
/bin/false
# Every minute in interval of 30-40 minutes, every hour, every day of month, every month of year,
every day of week
30-40 * * * * root
/bin/false
# Every 5 minutes in interval of 30-40 minutes, every hour, every day of month, every month of year,
every day of week
30-40/5 * * * * root
/bin/false
# Every 5 minutes in interval of 0-59 minutes, every hour, every day of month, every month of year,
every day of week
*/5
* * * * user
command to be executed
# Every minute, every hour, last day of month, every month of year, every day of week
*
* L * * root
/bin/false
# Every minute, every hour, every day of month, every month of year, Monday and Thursday
*
* * * 0,3 root
/bin/false
Ok, but how to install a crontab? This is list of the cron commands:
crontab -l — print out current crontab.
crontab -e — edit crontab for current user.
crontab -r — remove crontab for current user.
crontab /path/to/file — install crontab for the current user, overwriting existing one
in the process.
crontab > /path/to/file — save crontab to a file.
Well, that was about using cron system daemon. But there is one more option to
schedule program execution. It is via at utility. The difference between them is that
cron is designed to run tasks repetitively, many times, and at is designed for
scheduling one-time tasks. This are relevant commands:
at — executes commands at a specified time.
atq — lists pending jobs.
atrm — removes a job.
batch — executes commands then system in idling.
As if this infodump is not enough, now I will give you a table of possible time
specification for at, taken from http://content.hccfl.edu/pollock/unix/atdemo.htm In the
examples below assume that the date and time currently is 10:00 AM Tuesday,
September 18, 2001
Example
Meaning
at noon
12:00 PM September 18, 2001
at midnight
12:00 AM September 19, 2001
at teatime
4:00 PM September 18, 2001
at tomorrow
10:00 AM September 19, 2001
at noon tomorrow
12:00 PM September 19, 2001
at next week
10:00 AM September 25, 2001
at next monday
10:00 AM September 24, 2001
at fri
10:00 AM September 21, 2001
at OCT
10:00 AM October 18, 2001
54
at 9:00 AM
9:00 AM September 19, 2001
at 2:30 PM
2:30 PM September 18, 2001
at 1430
2:30 PM September 18, 2001
at 2:30 PM tomorrow 2:30 PM September 19, 2001
at 2:30 PM next month 2:30 PM October 18, 2001
at 2:30 PM Fri
2:30 PM September 21, 2001
at 2:30 PM 9/21
2:30 PM September 21, 2001
at 2:30 PM Sept 21
2:30 PM September 21, 2001
at 2:30 PM 9/21/2010 2:30 PM September 21, 2010
at 2:30 PM 9.21.10
2:30 PM September 21, 2010
at now + 30 minutes 10:30 AM September 18, 2001
at now + 1 hour
11:00 AM September 18, 2001
at now + 2 days
10:00 AM September 20, 2001
at 4 PM + 2 days
4:00 PM September 20, 2001
at now + 3 weeks
10:00 AM October 9, 2001
at now + 4 months
10:00 AM January 18, 2002
at now + 5 years
10:00 AM September 18, 2007
Now you will learn how to add, view and remove at and crontab jobs.
Do this
1: echo 'echo Here I am, sitting in ur at, staring at ur date: $(date) | write student' | at now + 1 minutes
2: atq
Wait for your message to appear, press <ENTER> and type some more:
3: echo '* * * * * echo Here I am, sitting in ur crontab, staring at ur date: $(date) | write student' >
~/crontab.tmp
4: crontab -l
5: crontab ~/crontab.tmp
6: crontab -l
Now wait for this one message to appear and remove it:
7: crontab -r
8: crontab -l
What you should see
student@vm1:~$ echo 'echo Here I am, sitting in ur at, staring at ur date: $(date) | write student' | at now + 1
minutes
warning: commands will be executed using /bin/sh
job 13 at Thu Jun 28 14:43:00 2012
student@vm1:~$ atq
14 Thu Jun 28 14:45:00 2012 a student
student@vm1:~$
Message from student@vm1 on (none) at 14:43 ...
Here I am, sitting in ur at, staring at ur date: Thu Jun 28 14:43:00 MSK 2012
EOF
student@vm1:~$ crontab -l
no crontab for student
student@vm1:~$ echo '* * * * * echo Here I am, sitting in ur crontab, staring at ur date: $(date) | write
student' > ~/crontab.tmp
student@vm1:~$ crontab -l
* * * * * echo Here I am, sitting in ur crontab, staring at ur date: $(date) | write student
55
student@vm1:~$
Message from student@vm1 on (none) at 14:47 ...
Here I am, sitting in ur crontab, staring at ur date: Thu Jun 28 14:47:01 MSK 2012
EOF
student@vm1:~$ crontab -r
student@vm1:~$ crontab -l
no crontab for student
student@vm1:~$
Explanation
Makes at execute the command echo Here I am, sitting in ur at, staring at ur
date: $(date) | write student when next minute starts.
Prints out at job queue.
Writes line echo '* * * * * echo Here I am, sitting in ur crontab, staring at ur date:
$(date) | write student to the file crontab.tmp in your home direcroty.
Prints out your current crontab, but there is none currently so it just tells this to you.
Loads contents of crontab.tmp to your personal crontab file.
Prints out your current crontab. Now there is something in it.
Removes your current crontab.
Tells you that you do not have a crontab once again.
Extra credit
Read man crontab, man at, man write.
Make your system tell you current time every 5 minutes.
Make your system tell you current hour at the start of every hour.
56
Exercise 18. Logging, /var/log, rsyslog,
logger
Daemon are those programs which run in the background. Because of this a
question arises: how do they tell you how they are doing? And how do they tell you
that something got wrong? This problem is solved by log files, in which daemons
write their status and operations. In Debian this files reside in /var/log directory.
But who writes those files? The most obvious answer, The daemons themselves, is
actually often wrong. In some cases daemons do indeed write log files themselves,
but usually they do it through the daemon called rsyslogd, which is called a logging
daemon. It writes logs to different files for simplifying searching and analyzing them.
Do distinguish between this files it has a concept called facilities. This is list of
standard facilities:
Facility Facility Description
Facility Facility Description
auth
Authorization-related messages
local0 local use 0
authpriv Security information of sensitive nature
local1 local use 1
cron
Cron information
local2 local use 2
daemon System daemons
local3 local use 3
ftp
FTP demon messagestion messages
local4 local use 4
kern
Kernel messages
local5 local use 5
lpr
Line printer subsystem
local6 local use 6
mail
Mail subsystem
local7 local use 7
news
News subsystem
security Depreacated name for auth
syslog Messages generated internally by syslogd
user
uucp
UUCP subsystem
Every entry is also marked with severity status for ease of analyzing what happaned:
Code
Severity
Description
General Description
Name
Should be corrected immediately, therefore
Action must be
notify staff who can fix the problem. An
alert
Alert
taken
example would be the loss of a backup ISP
immediately.
connection.
Should be corrected immediately, but
Critical
crit
Critical
indicates failure in a primary system, an
conditions.
example is a loss of primary ISP connection.
Debug-level
Info useful to developers for debugging the
debug Debug
messages.
application, not useful during operations.
A “panic” condition usually affecting multiple
System is
emerg Emergency
apps/servers/sites. At this level it would
unusable.
usually notify all tech staff on call.
Non-urgent failures, these should be relayed
err
Error
Error conditions.
to developers or admins; each item must be
57
resolved within a given time.
Non-urgent failures, these should be relayed
Deprecated
error
Error
to developers or admins; each item must be
name for err
resolved within a given time.
Normal operational messages - may be
Informational
info
Informational
harvested for reporting, measuring
messages.
throughput, etc. - no action required.
Events that are unusual but not error
Normal but
conditions - might be summarized in an
notice Notice
significant
email to developers or admins to spot
condition.
potential problems - no immediate action
required.
A “panic” condition usually affecting multiple
Deprecated
panic
Emergency
apps/servers/sites. At this level it would
name for emerg
usually notify all tech staff on call.
Warning messages, not an error, but
Warning
indication that an error will occur if action is
warning Warning
conditions.
not taken, e.g. file system 85% full - each
item must be resolved within a given time.
Warning messages, not an error, but
Deprecated
indication that an error will occur if action is
warn
Warning
name for
not taken, e.g. file system 85% full - each
warning
item must be resolved within a given time.
Because if log files are left to themselves they tend to grow really big and consume
all available disk space, there is a mechanism called rotation. This mechanism by
default usually keeps only seven last log files, for last 7 days, including today.
Rotation is performed by logrotate daemon, to help you understand what this
daemon does I wrote it out for you:
Day 0
log.0 is created
Day 1
mv log.0 log.1
log.0 is created
Day 2
mv log.1 log.2
mv log.0 log.1
log.0 is created
Day 3
mv log.2 log.3
mv log.1 log.2
mv log.0 log.1
log.0 is created
Day 4
mv log.3 log.4
mv log.2 log.3
mv log.1 log.2
mv log.0 log.1
log.0 is created
Day 5
mv log.4 log.5
mv log.3 log.4
mv log.2 log.3
mv log.1 log.2
58
mv log.0 log.1
log.0 is created
Day 6
mv log.5 log.6
mv log.4 log.5
mv log.3 log.4
mv log.2 log.3
mv log.1 log.2
mv log.0 log.1
log.0 is created
Day 7
rm log.6
mv log.5 log.6
mv log.4 log.5
mv log.3 log.4
mv log.2 log.3
mv log.1 log.2
mv log.0 log.1
log.0 is created
Let me reiterate for you:
Logging is the process of recording events, with an automated computer program, in
a certain scope in order to provide an audit trail that can be used to understand the
activity of the system and to diagnose problems.
Logging daemon is a program which other programs may ask to write something
down in a log file.
Every log entry has facility (logging category) and severity (how important it is)
attributes.
Rotation is a process of keeping only limited number of log files to avoid disks filling
up.
In Debian, log files are usually found in /var/log directory.
This are useful commands to work with logs (remember to open relevant man pages
and find out what those program options are for):
logger Hello, I have a kitty! — write a custom log message.
ls -altr /var/log — list log directory in such a way that lastly modified files are in the
end.
grep student /var/log/auth.log — list all lines in a file which contain student.
grep -irl student /var/log — list all files which contain student anywhere.
find /var/log -mmin -10 — find any files which are modified in last 10 minutes.
tail /var/log/auth.log — print out last 10 lines of a log file.
tail -f /var/log/auth.log — follow a log file in real time. It is very useful when
configuring daemons.
No you will learn how to view logs and write something to system log.
Do this
1: sudo -s
2: cd /var/log
3: ls -altr | tail
4: tail auth.log
5: grep student auth.log | tail
6: /etc/init.d/exim4 restart
7: find /var/log -mmin -5
8: tail /var/log/exim4/mainlog
9: grep -irl rcconf .
10: tail ./dpkg.log
11: last
12: lastlog
59
13: logger local0.alert I am a kitty, sittin in ur system watchin u work ^^
14: ls -altr | tail
15: tail messages
What you should see
student@vm1:~$ sudo -s
root@vm1:/home/student# cd /var/log
root@vm1:/var/log# ls -altr | tail
-rw-r----- 1 root
adm 46955 Jun 29 12:28 messages
-rw-r----- 1 root
adm 19744 Jun 29 12:28 dmesg
-rw-r----- 1 root
adm 696 Jun 29 12:28 daemon.log
drwxr-xr-x 7 root
root 4096 Jun 29 12:28 .
-rw-r----- 1 root
adm 60738 Jun 29 12:28 syslog
-rw-r----- 1 root
adm 58158 Jun 29 12:28 kern.log
-rw-r----- 1 root
adm 12652 Jun 29 12:28 debug
-rw-rw-r-- 1 root
utmp 75264 Jun 29 12:28 wtmp
-rw-rw-r-- 1 root
utmp 292584 Jun 29 12:28 lastlog
-rw-r----- 1 root
adm 38790 Jun 29 12:40 auth.log
root@vm1:/var/log# tail auth.log
Jun 29 12:28:22 vm1 sshd[983]: Server listening on 0.0.0.0 port 22.
Jun 29 12:28:22 vm1 sshd[983]: Server listening on :: port 22.
Jun 29 12:28:44 vm1 sshd[1214]: Accepted password for student from 194.85.195.183 port 53775 ssh2
Jun 29 12:28:44 vm1 sshd[1214]: pam_unix(sshd:session): session opened for user student by (uid=0)
Jun 29 12:30:49 vm1 sudo: student : TTY=pts/0 ; PWD=/home/student ; USER=root ; COMMAND=/bin/bash
Jun 29 12:30:53 vm1 login[1260]: pam_securetty(login:auth): unexpected response from failed conversation
function
Jun 29 12:30:53 vm1 login[1260]: pam_securetty(login:auth): cannot determine username
Jun 29 12:35:08 vm1 sudo: student : TTY=pts/0 ; PWD=/home/student ; USER=root ; COMMAND=/bin/bash
Jun 29 12:35:14 vm1 sudo: student : TTY=pts/0 ; PWD=/home/student ; USER=root ; COMMAND=/bin/bash
Jun 29 12:40:32 vm1 sudo: student : TTY=pts/0 ; PWD=/home/student ; USER=root ; COMMAND=/bin/bash
root@vm1:/var/log# tail auth.log | grep student
Jun 29 12:28:44 vm1 sshd[1214]: Accepted password for student from 194.85.195.183 port 53775 ssh2
Jun 29 12:28:44 vm1 sshd[1214]: pam_unix(sshd:session): session opened for user student by (uid=0)
Jun 29 12:30:49 vm1 sudo: student : TTY=pts/0 ; PWD=/home/student ; USER=root ; COMMAND=/bin/bash
Jun 29 12:35:08 vm1 sudo: student : TTY=pts/0 ; PWD=/home/student ; USER=root ; COMMAND=/bin/bash
Jun 29 12:35:14 vm1 sudo: student : TTY=pts/0 ; PWD=/home/student ; USER=root ; COMMAND=/bin/bash
Jun 29 12:40:32 vm1 sudo: student : TTY=pts/0 ; PWD=/home/student ; USER=root ; COMMAND=/bin/bash
root@vm1:/var/log# grep student auth.log | tail
Jun 29 12:26:33 vm1 sshd[1302]: Accepted password for student from 194.85.195.183 port 53008 ssh2
Jun 29 12:26:33 vm1 sshd[1302]: pam_unix(sshd:session): session opened for user student by (uid=0)
Jun 29 12:26:38 vm1 sudo: student : TTY=pts/0 ; PWD=/home/student ; USER=root ; COMMAND=/bin/bash
Jun 29 12:28:02 vm1 sshd[1302]: pam_unix(sshd:session): session closed for user student
Jun 29 12:28:44 vm1 sshd[1214]: Accepted password for student from 194.85.195.183 port 53775 ssh2
Jun 29 12:28:44 vm1 sshd[1214]: pam_unix(sshd:session): session opened for user student by (uid=0)
Jun 29 12:30:49 vm1 sudo: student : TTY=pts/0 ; PWD=/home/student ; USER=root ; COMMAND=/bin/bash
Jun 29 12:35:08 vm1 sudo: student : TTY=pts/0 ; PWD=/home/student ; USER=root ; COMMAND=/bin/bash
Jun 29 12:35:14 vm1 sudo: student : TTY=pts/0 ; PWD=/home/student ; USER=root ; COMMAND=/bin/bash
Jun 29 12:40:32 vm1 sudo: student : TTY=pts/0 ; PWD=/home/student ; USER=root ; COMMAND=/bin/bash
root@vm1:/home/student# /etc/init.d/exim4 restart
Stopping MTA for restart: exim4_listener.
Restarting MTA: exim4.
root@vm1:/home/student# find /var/log -mmin -5
/var/log/exim4/mainlog
/var/log/auth.log
root@vm1:/home/student# tail /var/log/exim4/mainlog
2012-06-29 12:24:11 exim 4.72 daemon started: pid=1159, -q30m, listening for SMTP on [127.0.0.1]:25 [::1]:25
2012-06-29 12:24:11 Start queue run: pid=1165
60
2012-06-29 12:24:11 End queue run: pid=1165
2012-06-29 12:28:22 exim 4.72 daemon started: pid=1190, -q30m, listening for SMTP on [127.0.0.1]:25 [::1]:25
2012-06-29 12:28:22 Start queue run: pid=1196
2012-06-29 12:28:22 End queue run: pid=1196
2012-06-29 12:41:18 exim 4.72 daemon started: pid=1622, -q30m, listening for SMTP on [127.0.0.1]:25 [::1]:25
2012-06-29 12:41:18 Start queue run: pid=1624
2012-06-29 12:41:18 End queue run: pid=1624
2012-06-29 12:42:28 exim 4.72 daemon started: pid=1886, -q30m, listening for SMTP on [127.0.0.1]:25 [::1]:25
root@vm1:/home/student# grep -irl rcconf .
./aptitude
./apt/history.log
./apt/term.log
./dpkg.log
./auth.log
root@vm1:/home/student# tail ./dpkg.log
2012-06-26 19:27:40 status unpacked rcconf 2.5
2012-06-26 19:27:40 status unpacked rcconf 2.5
2012-06-26 19:27:40 trigproc man-db 2.5.7-8 2.5.7-8
2012-06-26 19:27:40 status half-configured man-db 2.5.7-8
2012-06-26 19:27:40 status installed man-db 2.5.7-8
2012-06-26 19:27:41 startup packages configure
2012-06-26 19:27:41 configure rcconf 2.5 2.5
2012-06-26 19:27:41 status unpacked rcconf 2.5
2012-06-26 19:27:41 status half-configured rcconf 2.5
2012-06-26 19:27:41 status installed rcconf 2.5
root@vm1:/var/log# last
student pts/0
sis.site Fri Jun 29 12:26 still logged in
student pts/0
sis.site Fri Jun 29 12:14 - down (00:09)
student pts/0
sis.site Thu Jun 28 19:40 - 11:25 (15:45)
student pts/0
sis.site Wed Jun 27 19:14 - 17:04 (21:50)
student pts/0
sis.site Tue Jun 26 13:54 - 18:18 (1+04:23)
student pts/0
sis.site Thu Jun 21 15:23 - 13:11 (4+21:47)
student pts/0
sis.site Fri Jun 15 19:34 - 12:01 (5+16:26)
student pts/0
sis.site Fri Jun 15 19:11 - 19:34 (00:22)
reboot system boot 2.6.32-5-amd64 Fri Jun 29 12:24 - 12:26 (00:02)
student pts/0
sis.site Fri Jun 29 12:14 - down (00:09)
root@vm1:/var/log# lastlog
Username
Port From
Latest
root
**Never logged in**
daemon
**Never logged in**
bin
**Never logged in**
sys
**Never logged in**
sync
**Never logged in**
games
**Never logged in**
man
**Never logged in**
lp
**Never logged in**
mail
**Never logged in**
news
**Never logged in**
uucp
**Never logged in**
proxy
**Never logged in**
www-data
**Never logged in**
backup
**Never logged in**
list
**Never logged in**
irc
**Never logged in**
gnats
**Never logged in**
nobody
**Never logged in**
libuuid
**Never logged in**
61
Debian-exim
**Never logged in**
statd
**Never logged in**
sshd
**Never logged in**
student
pts/0 sis.site Fri Jun 29 12:28:45 +0400 2012
root@vm1:/var/log# logger local0.alert I am a kitty, sittin in ur system watchin u work ^^
root@vm1:/var/log# ls -altr | tail
-rw-r----- 1 root
adm 696 Jun 29 12:28 daemon.log
drwxr-xr-x 7 root
root 4096 Jun 29 12:28 .
-rw-r----- 1 root
adm 58158 Jun 29 12:28 kern.log
-rw-r----- 1 root
adm 12652 Jun 29 12:28 debug
-rw-rw-r-- 1 root
utmp 75264 Jun 29 12:28 wtmp
-rw-rw-r-- 1 root
utmp 292584 Jun 29 12:28 lastlog
-rw-r----- 1 root
adm 38971 Jun 29 13:17 auth.log
-rw-r----- 1 root
adm 229 Jun 29 13:19 user.log
-rw-r----- 1 root
adm 60932 Jun 29 13:19 syslog
-rw-r----- 1 root
adm 47047 Jun 29 13:19 messages
root@vm1:/var/log# tail messages
Jun 29 12:28:21 vm1 kernel: [ 1.846975] processor LNXCPU:00: registered as cooling_device0
Jun 29 12:28:21 vm1 kernel: [ 1.868828] usbcore: registered new interface driver hiddev
Jun 29 12:28:21 vm1 kernel: [ 1.895676] input: QEMU 0.14.1 QEMU USB Tablet as
/devices/pci0000:00/0000:00:01.2/usb1/1-1/1-1:1.0/input/input4
Jun 29 12:28:21 vm1 kernel: [ 1.895743] generic-usb 0003:0627:0001.0001: input,hidraw0: USB HID v0.01
Pointer [QEMU 0.14.1 QEMU USB Tablet] on usb-0000:00:01.2-1/input0
Jun 29 12:28:21 vm1 kernel: [ 1.895762] usbcore: registered new interface driver usbhid
Jun 29 12:28:21 vm1 kernel: [ 1.895765] usbhid: v2.6:USB HID core driver
Jun 29 12:28:21 vm1 kernel: [ 2.373061] EXT3 FS on vda1, internal journal
Jun 29 12:28:21 vm1 kernel: [ 2.394992] loop: module loaded
Jun 29 12:28:21 vm1 kernel: [ 2.413478] input: ImExPS/2 Generic Explorer Mouse as
/devices/platform/i8042/serio1/input/input5
Jun 29 13:19:11 vm1 student: local0.alert I am a kitty, sittin in ur system watchin u work ^^
root@vm1:/var/log#
Explanation
Opens root (superuser) shell. This is because you are not allowed to read all log files
due security considerations when working as student.
Changes directory to /var/log.
Prints out all files sorted by date, with last modified ones at the bottom.
Prints out last 10 lines from auth.log, which contains information about logging into
the system.
Prints out last 10 lines from auth.log which contain student.
Restars exim4 mail server.
Prints out files changes in last 5 minutes. Now you can easily spot in which file
exim4 logs its operation.
Prints out last 10 lines from exim4 log.
Searches for rcconf through all files in current directory. Now you can easily spot
where Debian package system logs its operations.
Pritns out last 10 lines from dpkg.log, which contain information about package
installation and removal.
Prints out information about last logins of users.
Prints out information about the most recent logins of all users.
Passes your message to rsyslogd daemon.
Prints out all files sorted by date, with last modified ones at the bottom, again. Now
you may see there did your message go.
62
Prints out last 10 lines from messages, you are able to see that your message is
indeed logged.
Extra credit
Read man pages for rsyslogd and logger.
Find out the difference between last and lastlog by reading corresponding man
pages.
Read logrotate man page and remember that it exists.
Execute tail -f /var/log/auth.log and make second connection to vm1 (with putty if
you are working on Windows). Nice, huh?
63
Exercise 19. Filesystems: mounting,
mount, /etc/fstab
I hope you are familiar with concept of partitions. In case if you are not I will
introduce you briefly to it. First, quote from Wikipedia:
Disk partitioning is the act of dividing a hard disk drive into multiple logical storage
units referred to as partitions, to treat one physical disk drive as if it were multiple
disks.
Take a look:
student@vm1:~$ sudo parted /dev/vda
GNU Parted 2.3
Using /dev/vda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) unit GB
(parted) p
Model: Virtio Block Device (virtblk)
Disk /dev/vda: 17.2GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Number Start End Size Type
File system Flags
1
0.00GB 13.3GB 13.3GB extended
5
0.00GB 1.02GB 1.02GB logical ext3
boot
6
1.03GB 2.05GB 1.02GB logical linux-swap(v1)
7
2.05GB 3.07GB 1.02GB logical ext3
8
3.07GB 5.12GB 2.05GB logical ext3
9
5.12GB 9.22GB 4.09GB logical ext3
10
9.22GB 13.3GB 4.09GB logical ext3
(parted)
This is one physical hard disk which is divided in 7 different partitions. The reasons
to do do are numerous, but best understood as an application of “divide and
conquer” principle. When divided in such a way one rogue program can not bring
whole sever down by consuming all disk space, this program will be limited to its
partition. I will not talk about partitioning disks just just yet, but I will continue taking
about file systems, by quoting Wikipedia again:
A file system (or filesystem) is a means to organize data expected to be retained
after a program terminates by providing procedures to store, retrieve and update
data, as well as manage the available space on the device(s) which contain it. A file
system organizes data in an efficient manner and is tuned to the specific
characteristics of the device. A tight coupling usually exists between the operating
system and the file system. Some file systems provide mechanisms to control
access to the data and metadata. Ensuring reliability is a major responsibility of a file
system. Some file systems allow multiple programs to update the same file at nearly
the same time.
Unix-like operating systems create a virtual file system, which makes all the files on
all the devices appear to exist in a single hierarchy. This means, in those systems,
there is one root directory, and every file existing on the system is located under it
somewhere. Unix-like systems can use a RAM disk or network shared resource as
its root directory.
What this means is that all file systems are integrated in one big tree. For those
familiar with Microsoft Windows this means that instead C:, D:, and so on naming
64
scheme there is a single root, /, to which all other partitions connect. The process of
connecting a file system to existing directory is called mounting. A directory to which
a file system is connected is called a mount point. Again, take a look:
student@vm1:~$ mount
/dev/vda5 on / type ext3 (rw,errors=remount-ro)
tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)
/dev/vda10 on /home type ext3 (rw)
/dev/vda7 on /tmp type ext3 (rw)
/dev/vda9 on /usr type ext3 (rw)
/dev/vda8 on /var type ext3 (rw)
This are the same partitions I showed you earlier in this list you their mount points.
Ones which do not start with /dev/vda are virtual file systems, which allow to access
different system facilities, but they are not relevant for this exercise. Now let us take
a look at /etc/fstab file:
student@vm1:~$ cat /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options>
<dump> <pass>
proc
/proc
proc defaults 0
0
# / was on /dev/vda5 during installation
UUID=128559db-a2e0-4983-91ad-d4f43f27da49 /
ext3 errors=remount-ro 0
1
# /home was on /dev/vda10 during installation
UUID=32852d29-ddee-4a8d-9b1e-f46569a6b897 /home ext3 defaults
0
2
# /tmp was on /dev/vda7 during installation
UUID=869db6b4-aea0-4a25-8bd2-f0b53dd7a88e /tmp
ext3 defaults
0
2
# /usr was on /dev/vda9 during installation
UUID=0221be16-496b-4277-b131-2371ce097b44 /usr
ext3 defaults
0
2
# /var was on /dev/vda8 during installation
UUID=2db00f94-3605-4229-8813-0ee23ad8634e /var
ext3 defaults
0
2
# swap was on /dev/vda6 during installation
UUID=3a936af2-2c04-466d-b98d-09eacc5d104c none
swap sw
0
0
/dev/scd0
/media/cdrom0 udf,iso9660 user,noauto 0
0
Looks scary, but let us take one line:
# <file system>
<mount point> <type> <options>
<dump> <pass>
UUID=128559db-a2e0-4983-91ad-d4f43f27da49 /
ext3 errors=remount-ro 0
1
And take it apart field by field:
UUID=128559db-a2e0-4983-91ad-d4f43f27da49 # Filesystem to mount. This UUID is synonim for
/dev/vda5
/
# This is root filesystem, mount it to /
ext3
# This is ext3 filesystem. There are many different filesystems out there
errors=remount-ro # If any errors encountered during mounting filesystem should be remounted
read-only
0
# This filesystem should not be backed up by dump utility
1
# This filesystem should be checked first by fsck utility
As always, this information is available to you via man fstab. Now I will show you
several commands for working with existing file systems:
mount — print out all mounted filesystems.
mount -a — mount all filesystem described in /etc/fstab.
65
mount /dev/sda<N> /<mount point> — mount a partition.
umount /dev/sda<N> /<mount point> — mount a partition.
mount -h — print out short help about using mount.
fsck — check partition for errors.
blkid — print out unique partition identifiers.
Now you will learn how to list mounted partitions, mount and unmount them.
Do this
1: cat /etc/fstab
2: mount
3: sudo blkid
4: sudo umount /tmp
5: mount
6: sudo fsck /tmp
7: sudo mount -a
8: mount
What you should see
student@vm1:~$ cat /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options>
<dump> <pass>
proc
/proc
proc defaults
0
0
# / was on /dev/sda1 during installation
UUID=05d469bb-dbfe-4d5a-9bb2-9c0fe9fa8577 /
ext3 errors=remount-ro 0
# /home was on /dev/sda9 during installation
UUID=a1b936a0-df38-4bf5-b095-6220ffdfc63c /home
ext3 defaults
0
2
# /tmp was on /dev/sda8 during installation
UUID=d0a86453-0dbb-4f33-a023-6c09fe9fa202 /tmp ext3 defaults 0 2
# /usr was on /dev/sda5 during installation
UUID=b9544cbb-cdb6-4f3b-89e7-a339f52bfac7 /usr
ext3 defaults
0
2
# /var was on /dev/sda6 during installation
UUID=e15e713b-5850-4bc3-b99e-ab6f1d037caa /var
ext3 defaults
0
2
# swap was on /dev/sda7 during installation
UUID=4d516f09-80ff-4956-8a75-e9757697f6b1 none
swap sw
0
0
/dev/scd0
/media/cdrom0 udf,iso9660 user,noauto 0
0
student@vm1:~$ mount
/dev/sda1 on / type ext3 (rw,errors=remount-ro)
tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)
/dev/sda9 on /home type ext3 (rw)
/dev/sda5 on /usr type ext3 (rw)
/dev/sda6 on /var type ext3 (rw)
/dev/sda8 on /tmp type ext3 (rw)
/dev/sda8 on /tmp type ext3 (rw)
student@vm1:~$ sudo blkid
/dev/sda1: UUID="05d469bb-dbfe-4d5a-9bb2-9c0fe9fa8577" TYPE="ext3"
/dev/sda5: UUID="b9544cbb-cdb6-4f3b-89e7-a339f52bfac7" TYPE="ext3"
66
1
/dev/sda6: UUID="e15e713b-5850-4bc3-b99e-ab6f1d037caa" TYPE="ext3"
/dev/sda7: UUID="4d516f09-80ff-4956-8a75-e9757697f6b1" TYPE="swap"
/dev/sda8: UUID="d0a86453-0dbb-4f33-a023-6c09fe9fa202" TYPE="ext3"
/dev/sda9: UUID="a1b936a0-df38-4bf5-b095-6220ffdfc63c" TYPE="ext3"
student@vm1:~$ sudo umount /tmp
student@vm1:~$ mount
/dev/sda1 on / type ext3 (rw,errors=remount-ro)
tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)
/dev/sda9 on /home type ext3 (rw)
/dev/sda5 on /usr type ext3 (rw)
/dev/sda6 on /var type ext3 (rw)
student@vm1:~$ sudo fsck /tmp
fsck from util-linux-ng 2.17.2
e2fsck 1.41.12 (17-May-2010)
/dev/sda8: clean, 11/61752 files, 13973/246784 blocks
student@vm1:~$ sudo mount -a
student@vm1:~$ mount
/dev/sda1 on / type ext3 (rw,errors=remount-ro)
tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)
/dev/sda9 on /home type ext3 (rw)
/dev/sda5 on /usr type ext3 (rw)
/dev/sda6 on /var type ext3 (rw)
/dev/sda8 on /tmp type ext3 (rw)
student@vm1:~$
Explanation
Prints out contents of your /etc/fstab file which contains information about your
partitions and where to mount them.
Prints out currently mounted partitions.
Prints out UUIDs of all partitions in your system.
Unmounts /tmp partition so you will be able to check it.
Prints out currently mounted partitions once again. /tmp is now absent from this list.
Check /tmp partition for errors. fsck knows which partition to check by reading
corresponding /etc/fstab entry.
Mounts all partitions described in /etc/fstab.
Prints out currently mounted partitions yet another time. /tmp has returned to this list.
Extra credit
Read man fstab, man mount.
Read http://tldp.org/LDP/sag/html/filesystems.html
67
Exercise 20. Filesystems: modifying
and creating filesystems, tune2fs, mkfs
Let me introduce you to filesystem-related terminology:
Filesystem — a means to organize data expected to be retained after a program
terminates by providing procedures to store, retrieve and update data, as well as
manage the available space on the device(s) which contain it.
Inode — an Index Node, is a structure which store all the information about a file
system object (file, directory, etc.) except data content and file name.
Block — a minimum chunk of disk space which can be allocated. It usually defaults
to 4096 bytes, or 4 Kilobytes.
Journal — a structure which allows the filesystem track of what was written and
when. This allows to quickly understand what was not properly written in case of
power outage or similar problem.
Next, let me give you an outline explaining in broad strokes how a filesystem works.
To access file by name Linux kernel:
Finds file name in directory containing the file.
Gets file Inode number.
Finds Inode by its number in Inodes area.
Reads locations of blocks containing the data from this Inode.
Using this locations reads file from this blocks in data area.
Now, every file system has many options associated with it. These options may be
viewed and changed via tune2fs program. Here is an annotated output of tune2fs -l
/dev/sda8:
student@vm1:~$ sudo tune2fs -l /dev/sda8
tune2fs 1.41.12 (17-May-2010)
# Just a label. Can be anything or nothing.
Filesystem volume name: <none>
# Here should be last mount point.
Last mounted on:
<not available>
# Unique file system identifier.
Filesystem UUID:
869db6b4-aea0-4a25-8bd2-f0b53dd7a88e
# A special number at known place, which defines FS type. Try this:
# sudo dd if=/dev/sda8 of=/dev/stdout bs=1 skip=1080 count=2 | hexdump -C
Filesystem magic number: 0xEF53
# FS version
Filesystem revision #: 1 (dynamic)
# Enabled FS features
Filesystem features:
# It is a journaling file system. A journaling file system is a file system that
# keeps track of the changes that will be made in a journal (usually a circular log in
# a dedicated area of the file system) before committing them to the main file system.
# In the event of a system crash or power failure, such file systems are quicker to bring
# back online and less likely to become corrupted.
# http://en.wikipedia.org/wiki/Journaling_file_system
has_journal
# Has extended attributes like extended ACL.
ext_attr
# Reserves space for system information, which allows FS resizing.
resize_inode
# Use indexes to speed up look-ups in large directories.
dir_index
# Store file type information in directory entries.
68
filetype
# Means that fsck needs to be run.
needs_recovery
# Fewer superblock backup copies, saves space on large FS.
sparse_super
# Can contain files > 2GB. Kernel sets this up automatically on >2GB file creation.
large_file
# Which hash to use in dir_index.
Filesystem flags:
signed_directory_hash
# Which options to use when mounting.
Default mount options: (none)
# Need to run fsck?
Filesystem state:
clean
# What to do on error? Continue, remount read-only or panic?
Errors behavior:
Continue
# Which OS uses this FS
Filesystem OS type:
Linux
# Number of inodes total. Inode means "Index Node" and is a structure which
# store all the information about a file system object (file, directory, etc.) execpt
# data content and file name. The implication of this is that you can not have more files
# than you have Inodes.
# This is Inode structure which describes what information which is stored in Inode:
#/* Inode structure as it appears on an Inode table. */
#struct dinode
#{ ushort di_mode; /* mode and type of file */
# short di_nlink; /* number of links to file */
# ushort di_uid;
/* owner's user id
*/
# ushort di_gid;
/* owner's group id
*/
# off_t di_size; /* number of bytes in file */
# char di_addr[39]; /* disk block addresses */
# char di_gen;
/* file generation number */
# time_t di_atime; /* time last accessed
*/
# time_t di_mtime; /* time last modified
*/
# time_t di_ctime; /* time created
*/
#};
# This is also a good explanation:
# http://support.tux4u.nl/dokuwiki/lib/exe/fetch.php?media=linux:disk_bestandssysteem:inode.pdf
Inode count:
62464
# How many inodes are currently free.
Free inodes:
62452
# First block on device. Because each partition is represented as a separate device,
# this is set to 0.
First block:
0
# This is the Inode number of the first Inode in the file system.
First inode:
11
# Inode size in bytes. This is sometimes increased by default in newer Linux distributions,
# to permit storage of extended attributes in file, for example nanosecond timestamps.
Inode size:
256
# Requred space for additional Inode fields.
Required extra isize: 28
# Desired space for additional Inode fields. Does not matter because this size is
# requred anyway.
Desired extra isize:
28
# An invisible inode which stores file system journal.
Journal inode:
8
# Number of blocks total. A block is a minimum chunk of disk space which can be allocated.
# You can calculate partition size in GB with the following formula:
# Block count * Block size
# -----------------------#
1024^3
69
Block count:
249856
# How many blocks are reserved for superuser only. Ordinary users cannot use this
# reserved space. This is done for system remain operational in case some rogue
# program decides to fill up all available disk space.
Reserved block count: 12492
# How many blocks are currently free.
Free blocks:
241518
# An algorithm used for directory index, dir_index.
Default directory hash: half_md4
# As far as I can tell this is a seed value for dir_index hashing algorithm.
Directory Hash Seed:
d02c6099-bd06-4d29-a3d7-779df2aa2410
# Journal backup options.
Journal backup:
inode blocks
#
# Block size, in bytes. 4096 bytes means 4 KB here.
Block size:
4096
# Not implemented in ext3 FS. It is a feature which would allow to write several small files
# in one block to conserve space.
Fragment size:
4096
# Reserved space so Group Descriptor Table may grow in the future.
Reserved GDT blocks:
60
# Number of blocks per block group. Block groups contain a redundant copy of crucial filesystem
# control information (superblock and the FS descriptors) and also contains a
# part of the filesystem (a block bitmap, an Inode bitmap, a piece of the Inode table,
# and data blocks). The structure of a block group is represented in this table:
#,---------+---------+---------+---------+---------+---------,
#| Super | FS
| Block | Inode | Inode | Data |
#| block | desc. | bitmap | bitmap | table | blocks |
#`---------+---------+---------+---------+---------+---------'
# http://tldp.org/HOWTO/Filesystems-HOWTO-6.html
Blocks per group:
32768
# Number of fragments per group. Because there are no fragments in ext3 FS this is
# equal to Blocks per group.
Fragments per group:
32768
# Number of inodes per group.
Inodes per group:
7808
# The Inode blocks per group. Inode blocks an index into a teable that describe
# all file properties except the file name. It has references to the data blocks
# that contain the actual contents of the file.
# http://www.porcupine.org/forensics/forensic-discovery/chapter3.html
Inode blocks per group: 488
# FS Creation time.
Filesystem created:
Mon Jul 2 06:16:24 2012
# Last FS mount time.
Last mount time:
Mon Jul 2 06:57:21 2012
# Last FS write time.
Last write time:
Mon Jul 2 06:57:21 2012
# Number of times this FS was mounted.
Mount count:
6
# Number of counts before automatic checking. FS will be automatically checked if
# filesystem was mounted this number of times, or if check interval has come.
Maximum mount count:
34
# Last fsck run time
Last checked:
Mon Jul 2 06:16:24 2012
# Next FS check interval. FS will be checked if this interval has come,
# or if Maximum mount count is reached.
Check interval:
15552000 (6 months)
# Next FS check interval in human readable format.
Next check after:
Sat Dec 29 05:16:24 2012
# User ID for user which is able to user reserved space.
# It is root user (superuser) by default.
70
Reserved blocks uid:
0 (user root)
# Group ID for group which is able to user reserved space.
# It is root group by default.
Reserved blocks gid:
0 (group root)
Scary, huh? In practice you will find that only several parameters from this
description are actually useful, which are:
Reserved block count.
Maximum mount count.
Check interval.
Usually you would not want to modify other parameters, they are sane by default.
Here is a list of commands for working with file systems:
mkfs.ext3 — create an ext3 file system. If this command is executed on a device
with existing file system, this file system will be destroyed, so proceed with caution.
mkfs.ext4 — create an ext4 file system. This is actually the same program, try sudo
find /sbin -samefile sbin/mkfs.ext3.
tune2fs — print out and change file system parameters.
Now you will learn how to create new filesystem and modify its parameters.
Do this
1: sudo -s
2: umount /tmp
3: blkid | grep /dev/sda8
4: mkfs.ext3 /dev/sda8
5: blkid | grep /dev/sda8
6: blkid | grep /dev/sda8 >> /etc/fstab
7: vim /etc/fstab
Now you must replace UUID in line for /tmp:
# /tmp was on /dev/sda8 during installation
UUID=869db6b4-aea0-4a25-8bd2-f0b53dd7a88e /tmp
ext3
defaults
0
2
With one that you appended to the end of file:
/dev/sda8: UUID="53eed507-18e8-4f71-9003-bcea8c4fd2dd" TYPE="ext3" SEC_TYPE="ext2"
Because UUID are unique by definition yours will differ from mine. After replacing
this UUID, write file, quit and continue to type:
8: mount /tmp
9: tune2fs -c 2 /dev/sda8
10: unmount /tmp
11: fsck /tmp
12: for ((i=1;i<=4;i++)); do mount /tmp ; umount /tmp ; cat /var/log/messages | tail -n 4 ; done
13: fsck /tmp
14: mount -a
What you should see
student@vm1:~$ sudo -s
root@vm1:/home/student# umount /tmp
root@vm1:/home/student# blkid | grep /dev/sda8
/dev/sda8: UUID="869db6b4-aea0-4a25-8bd2-f0b53dd7a88e" TYPE="ext3" SEC_TYPE="ext2"
root@vm1:/home/student# mkfs.ext3 /dev/sda8
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
62464 inodes, 249856 blocks
12492 blocks (5.00%) reserved for the super user
First data block=0
71
Maximum filesystem blocks=255852544
8 block groups
32768 blocks per group, 32768 fragments per group
7808 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 28 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
root@vm1:/home/student# blkid | grep /dev/sda8
/dev/sda8: UUID="53eed507-18e8-4f71-9003-bcea8c4fd2dd" TYPE="ext3" SEC_TYPE="ext2"
root@vm1:/home/student# blkid | grep /dev/sda8 >> /etc/fstab
root@vm1:/home/student# vim /etc/fstab
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options>
<dump> <pass>
proc
/proc
proc defaults
0
0
# / was on /dev/vda5 during installation
UUID=128559db-a2e0-4983-91ad-d4f43f27da49 /
ext3 errors=re
# /home was on /dev/vda10 during installation
UUID=32852d29-ddee-4a8d-9b1e-f46569a6b897 /home
ext3 defaults
# /tmp was on /dev/sda8 during installation
UUID=869db6b4-aea0-4a25-8bd2-f0b53dd7a88e /tmp
ext3 defaults
# /usr was on /dev/vda9 during installation
UUID=0221be16-496b-4277-b131-2371ce097b44 /usr
ext3 defaults
# /var was on /dev/vda8 during installation
UUID=2db00f94-3605-4229-8813-0ee23ad8634e /var
ext3 defaults
# swap was on /dev/vda6 during installation
UUID=3a936af2-2c04-466d-b98d-09eacc5d104c none
swap sw
/dev/scd0
/media/cdrom0 udf,iso9660 user,noauto 0
0
/dev/sda8: UUID="53eed507-18e8-4f71-9003-bcea8c4fd2dd" TYPE="ext3" SEC_TYPE
22,1
Bot
#
# <file system> <mount point> <type> <options>
<dump> <pass>
proc
/proc
proc defaults
0
0
# / was on /dev/vda5 during installation
UUID=128559db-a2e0-4983-91ad-d4f43f27da49 /
ext3 errors=re
# /home was on /dev/vda10 during installation
UUID=32852d29-ddee-4a8d-9b1e-f46569a6b897 /home
ext3 defaults
# /tmp was on /dev/sda8 during installation
UUID=53eed507-18e8-4f71-9003-bcea8c4fd2dd /tmp
ext3 defaults
# /usr was on /dev/vda9 during installation
UUID=0221be16-496b-4277-b131-2371ce097b44 /usr
ext3 defaults
# /var was on /dev/vda8 during installation
UUID=2db00f94-3605-4229-8813-0ee23ad8634e /var
ext3 defaults
# swap was on /dev/vda6 during installation
UUID=3a936af2-2c04-466d-b98d-09eacc5d104c none
/dev/scd0
/media/cdrom0 udf,iso9660 user,noauto
"/etc/fstab" 22L, 1277C written
root@vm1:/home/student# mount /tmp
root@vm1:/home/student# tune2fs -c 2 /dev/sda8
72
0
swap sw
0
tune2fs 1.41.12 (17-May-2010)
Setting maximal mount count to 2
root@vm1:/home/student# unmount /tmp
root@vm1:/home/student# fsck /tmp
fsck from util-linux-ng 2.17.2
e2fsck 1.41.12 (17-May-2010)
/dev/sda8: clean, 11/62464 files, 8337/249856 blocks (check in 2 mounts)
root@vm1:/home/student# for ((i=1;i<=4;i++)); do mount /tmp ; umount /tmp ; cat /var/log/messages | tail -n
4 ; done
Jul 2 12:11:43 vm1 kernel: [21080.920658] EXT3-fs: mounted filesystem with ordered data mode.
Jul 2 12:11:58 vm1 kernel: [21096.363787] kjournald starting. Commit interval 5 seconds
Jul 2 12:11:58 vm1 kernel: [21096.364167] EXT3 FS on sda8, internal journal
Jul 2 12:11:58 vm1 kernel: [21096.364171] EXT3-fs: mounted filesystem with ordered data mode.
Jul 2 12:11:58 vm1 kernel: [21096.364171] EXT3-fs: mounted filesystem with ordered data mode.
Jul 2 12:11:58 vm1 kernel: [21096.381372] kjournald starting. Commit interval 5 seconds
Jul 2 12:11:58 vm1 kernel: [21096.381539] EXT3 FS on sda8, internal journal
Jul 2 12:11:58 vm1 kernel: [21096.381542] EXT3-fs: mounted filesystem with ordered data mode.
Jul 2 12:11:58 vm1 kernel: [21096.396152] kjournald starting. Commit interval 5 seconds
Jul 2 12:11:58 vm1 kernel: [21096.396158] EXT3-fs warning: maximal mount count reached, running e2fsck is
recommended
Jul 2 12:11:58 vm1 kernel: [21096.396344] EXT3 FS on sda8, internal journal
Jul 2 12:11:58 vm1 kernel: [21096.396348] EXT3-fs: mounted filesystem with ordered data mode.
Jul 2 12:11:58 vm1 kernel: [21096.412434] kjournald starting. Commit interval 5 seconds
Jul 2 12:11:58 vm1 kernel: [21096.412441] EXT3-fs warning: maximal mount count reached, running e2fsck is
recommended
Jul 2 12:11:58 vm1 kernel: [21096.412610] EXT3 FS on sda8, internal journal
Jul 2 12:11:58 vm1 kernel: [21096.412612] EXT3-fs: mounted filesystem with ordered data mode.
root@vm1:/home/student# fsck /tmp
fsck from util-linux-ng 2.17.2
e2fsck 1.41.12 (17-May-2010)
/dev/sda8 has been mounted 4 times without being checked, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sda8: 11/62464 files (0.0% non-contiguous), 8337/249856 blocks
root@vm1:/home/student# mount -a
root@vm1:/home/student#
Explanation
Executes root (superuser) shell.
Unmounts /tmp, reading its location from /etc/fstab.
Prints out /dev/sda8 UUID, /dev/sda8 being the file system which mounts on /tmp.
Makes a new file system on /dev/sda8.
Prints out /dev/sda8 UUID one again, notice how it changed because you created a
new file system.
Appends this UUID to /etc/fstab.
Opens /etc/fstab for editing.
Mounts newly created file system. This is actually a check if you had replaced UUID
correctly, if not there will be an error message.
Sets checking /dev/sda8 every 2 mounts.
Unmounts /dev/sda8.
Checks /dev/sda8.
73
Mounts, unmounts /dev/sda8 and shows you last 4 lines from /var/log/messages
four times in a row. Notice how starting from 3-rd mount system notifies you that
e2fsck needs to be run. If you reboot your system, it would run e2fsck for you.
Checks /dev/sda8. fsck determines file system type and calls e2fsck for you
automatically.
Mounts all file systems. If there is no error, you successfully finished this exercise.
Extra credit
Read man mkfs, man mkfs.ext3, man tune2fs.
Read tune2fs -l listing at top of the page and read magic numbers for all your file
systems.
Calculate size of your file systems by hand using formula provided in block
description of tune2fs -l listing.
Read this presentation and do what is shown it in:
http://mcgrewsecurity.com/training/extx.pdf
74
Exercise 21. Filesystems: changing
root directory, chroot
Let me start with another Wikipedia quote:
A chroot on Unix operating systems is an operation that changes the apparent root
directory for the current running process and its children. A program that is run in
such a modified environment cannot name (and therefore normally not access) files
outside the designated directory tree. The term chroot may refer to the chroot(2)
system call or the chroot(8) wrapper program. The modified environment is called a
chroot jail.
What this means is that you can create a directory (for example /opt/root), copy
necessary program there and execute this program. For such program /opt/root/ will
be the root directory /. To understand why you would want that, read Wikipedia
chroot article.
It is practice time. You will do now create a minimal chroot environment with bash.
To do this you will create a directory structure and copy bash and its dependencies
into it.
Now you will learn how to create a chroot environment and enter into it.
Type this
1: sudo -s
2: ldd /bin/bash
3: mkdir -vp /opt/root/bin
4: mkdir -v /opt/root/lib
5: mkdir -v /opt/root/lib64
6: cp -v /bin/bash /opt/root/bin/
7: cp -v /lib/libncurses.so.5 /opt/root/lib/
8: cp -v /lib/libdl.so.2 /opt/root/lib
9: cp -v /lib/libc.so.6 /opt/root/lib
10: cp -v /lib64/ld-linux-x86-64.so.2 /opt/root/lib64
11: chroot /opt/root/
Wohoo, you just created yourself a Linux! Sort of.
What you should see
student@vm1:/opt~ sudo -s
root@vm1:/opt# ldd /bin/bash
linux-vdso.so.1 => (0x00007fff17bff000)
libncurses.so.5 => /lib/libncurses.so.5 (0x00007f4b1edc6000)
libdl.so.2 => /lib/libdl.so.2 (0x00007f4b1ebc2000)
libc.so.6 => /lib/libc.so.6 (0x00007f4b1e85f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4b1f012000)
root@vm1:/opt# mkdir -vp /opt/root/bin
mkdir: created directory `/opt/root'
mkdir: created directory `/opt/root/bin'
root@vm1:/opt# mkdir -v /opt/root/lib
mkdir: created directory `/opt/root/lib'
root@vm1:/opt# mkdir -v /opt/root/lib64
mkdir: created directory `/opt/root/lib64'
root@vm1:/opt# cp -v /bin/bash /opt/root/bin/
`/bin/bash' -> `/opt/root/bin/bash'
root@vm1:/opt# cp -v /lib/libncurses.so.5 /opt/root/lib/
`/lib/libncurses.so.5' -> `/opt/root/lib/libncurses.so.5'
root@vm1:/opt# cp -v /lib/libdl.so.2 /opt/root/lib
75
`/lib/libdl.so.2' -> `/opt/root/lib/libdl.so.2'
root@vm1:/opt# cp -v /lib/libc.so.6 /opt/root/lib
`/lib/libc.so.6' -> `/opt/root/lib/libc.so.6'
root@vm1:/opt# cp -v /lib64/ld-linux-x86-64.so.2 /opt/root/lib64
`/lib64/ld-linux-x86-64.so.2' -> `/opt/root/lib64/ld-linux-x86-64.so.2'
root@vm1:/opt# chroot /opt/root/
Explanation
Executes bash as superuser (root).
Prints out libraries which bash needs to run.
Creates /opt/root/ and /opt/root/bin/ directories in one command. Neat, eh?
Creates /opt/root/lib directory.
Creates /opt/root/lib64 directory.
Copies /bin/bash to /opt/root/bin/.
Copies /lib/libncurses.so.5 to /opt/root/lib/.
Copies /lib/libdl.so.2 to /opt/root/lib/.
Copies /lib/libc.so.6 to /opt/root/lib/.
Copies /lib64/ld-linux-x86-64.so.2 to /opt/root/lib64/.
Changes root directory to /opt/root/.
Extra credit
Read man chroot, man ldd.
Copy ls command to your chroot and make it work.
A hard one: copy vim to your chroot and make it work.
Exercise 22. Filesystems: moving data
around: tar, dd
Time to see for yourself how everything in Linux is just a file.
This exercise is a big one, but its time to see what you have learned. After you will
make it through look up all purposefully unexplained program parameters in the
man, and try to explain to yourself what each command does.
Now you will learn how to juggle with data.
Do this
1: tar -czvf root.tgz /opt/root/
2: tar -tzvf root.tgz
3: cd /tmp
4: tar -zxvf ~/root.tgz
5: ls -al
6: dd_if=$(mount | grep /tmp | cut -d ' ' -f 1) && echo $dd_if
7: sudo dd if=$dd_if of=~/tmp.img bs=10M
8: cd && ls -alh
9: sudo losetup /dev/loop1 ~/tmp.img && sudo mount /dev/loop1 /mnt/
10: ls -al /mnt
11: sudo umount /mnt && sudo losetup -d /dev/loop1
12: sudo umount $dd_if && sudo mkfs.ext3 $dd_if
13: new_uuid=$(sudo tune2fs -l $dd_if | awk '/UUID/{print $3}') && echo $new_uuid
14: grep '/tmp' /etc/fstab
15: sed "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp ext3
defaults 0 2/" /etc/fstab
76
Now check the output using sudo tune2fs -l and sudo blkid. If replacement of
UUID in /etc/fstab looks sane, perform the actual replacement:
16: sudo sed -i'.bak' "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp
ext3 defaults 0 2/" /etc/fstab
17: sudo mount -a && ls /tmp
18: sudo umount /tmp && pv ~/tmp.img | sudo dd of=$dd_if bs=10M
19: new_uuid=$(sudo tune2fs -l $dd_if | awk '/UUID/{print $3}') && echo $new_uuid
20: sudo sed -i'.bak' "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp
ext3 defaults 0 2/" /etc/fstab
21: sudo mount -a
22: rm -v tmp.img
Type in y and press <ENTER>.
What you should see
student@vm1:~$ tar -czvf root.tgz /opt/root/
tar: Removing leading '/' from member names
/opt/root/
/opt/root/bin/
/opt/root/bin/bash
/opt/root/lib64/
/opt/root/lib64/ld-linux-x86-64.so.2
/opt/root/lib/
/opt/root/lib/libdl.so.2
/opt/root/lib/libncurses.so.5
/opt/root/lib/libc.so.6
student@vm1:~$ tar -tzvf root.tgz
drwxr-xr-x root/root
0 2012-07-05 03:14 opt/root/
drwxr-xr-x root/root
0 2012-07-05 03:14 opt/root/bin/
-rwxr-xr-x root/root 926536 2012-07-05 03:14 opt/root/bin/bash
drwxr-xr-x root/root
0 2012-07-05 03:14 opt/root/lib64/
-rwxr-xr-x root/root 128744 2012-07-05 03:14 opt/root/lib64/ld-linux-x86-64.so.2
drwxr-xr-x root/root
0 2012-07-05 03:14 opt/root/lib/
-rw-r--r-- root/root 14696 2012-07-05 03:14 opt/root/lib/libdl.so.2
-rw-r--r-- root/root 286776 2012-07-05 03:14 opt/root/lib/libncurses.so.5
-rwxr-xr-x root/root 1437064 2012-07-05 03:14 opt/root/lib/libc.so.6
student@vm1:~$ cd /tmp
student@vm1:/tmp$ tar -zxvf ~/root.tgz
opt/root/
opt/root/bin/
opt/root/bin/bash
opt/root/lib64/
opt/root/lib64/ld-linux-x86-64.so.2
opt/root/lib/
opt/root/lib/libdl.so.2
opt/root/lib/libncurses.so.5
opt/root/lib/libc.so.6
student@vm1:/tmp$ ls -al
total 19
drwxrwxrwt 6 root root 1024 Jul 5 04:17 .
drwxr-xr-x 22 root root 1024 Jul 3 08:29 ..
drwxrwxrwt 2 root root 1024 Jul 3 08:41 .ICE-unix
drwx------ 2 root root 12288 Jul 3 07:47 lost+found
drwxr-xr-x 3 student student 1024 Jul 5 03:24 opt
-rw-r--r-- 1 root root 489 Jul 3 10:14 sources.list
-r--r----- 1 root root 491 Jul 3 10:21 sudoers
drwxrwxrwt 2 root root 1024 Jul 3 08:41 .X11-unix
student@vm1:/tmp$ dd_if=$(mount | grep /tmp | cut -d ' ' -f 1) && echo $dd_if
77
/dev/sda8
student@vm1:~$ cd && ls -alh
total 243M
drwxr-xr-x 3 student student 4.0K Jul 5 04:27 .
drwxr-xr-x 4 root root 4.0K Jul 3 08:39 ..
-rw------- 1 student student 22 Jul 3 10:45 .bash_history
-rw-r--r-- 1 student student 220 Jul 3 08:39 .bash_logout
-rw-r--r-- 1 student student 3.2K Jul 3 08:39 .bashrc
-rw------- 1 student student 52 Jul 5 04:12 .lesshst
drwxr-xr-x 3 student student 4.0K Jul 5 03:23 opt
-rw-r--r-- 1 student student 675 Jul 3 08:39 .profile
-rw-r--r-- 1 student student 1.3M Jul 5 04:25 root.tgz
-rw-r--r-- 1 root root 241M Jul 5 04:36 tmp.img
student@vm1:~$ sudo losetup /dev/loop1 ~/tmp.img && sudo mount /dev/loop1 /mnt/
student@vm1:~$ ls -al /mnt
total 19
drwxrwxrwt 6 root root 1024 Jul 5 04:17 .
drwxr-xr-x 22 root root 1024 Jul 3 08:29 ..
drwxrwxrwt 2 root root 1024 Jul 3 08:41 .ICE-unix
drwx------ 2 root root 12288 Jul 3 07:47 lost+found
drwxr-xr-x 3 student student 1024 Jul 5 03:24 opt
-rw-r--r-- 1 root root 489 Jul 3 10:14 sources.list
-r--r----- 1 root root 491 Jul 3 10:21 sudoers
drwxrwxrwt 2 root root 1024 Jul 3 08:41 .X11-unix
student@vm1:~$ sudo umount /mnt && sudo losetup -d /dev/loop1
student@vm1:~$ sudo umount $dd_if && sudo mkfs.ext3 $dd_if
mke2fs 1.41.12 (17-May-2010)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
61752 inodes, 246784 blocks
12339 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67371008
31 block groups
8192 blocks per group, 8192 fragments per group
1992 inodes per group
Superblock backups stored on blocks:
8193, 24577, 40961, 57345, 73729, 204801, 221185
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 27 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.
student@vm1:~$ new_uuid=$(sudo tune2fs -l $dd_if | awk '/UUID/{print $3}') && echo $new_uuid
f8288adc-3ef9-4a6e-aab2-92624276b8ba
student@vm1:~$ grep '/tmp' /etc/fstab
# /tmp was on /dev/sda8 during installation
UUID=011b4530-e4a9-4d13-926b-48d9e33b64bf /tmp ext3 defaults 0 2
student@vm1:~$ sed "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp
ext3 defaults 0 2/" /etc/fstab
# /etc/fstab: static file system information.
#
78
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options>
<dump> <pass>
proc
/proc
proc defaults
0
0
# / was on /dev/sda1 during installation
UUID=91aacf33-0b35-474c-9c61-311e04b0bed1 /
ext3 errors=remount-ro 0
1
# /home was on /dev/sda9 during installation
UUID=e27b0efb-8cf0-439c-9ebe-d59c927dd590 /home
ext3 defaults
0
2
# /tmp was on /dev/sda8 during installation
UUID=f8288adc-3ef9-4a6e-aab2-92624276b8ba /tmp ext3 defaults 0 2
# /usr was on /dev/sda5 during installation
UUID=9f49821b-7f94-4915-b9a9-ed9f12bb6847 /usr
ext3 defaults
0
2
# /var was on /dev/sda6 during installation
UUID=b7e908a1-a1cd-4d5c-bc79-c3a99d003e7c /var
ext3 defaults
0
2
# swap was on /dev/sda7 during installation
UUID=292981d7-5a17-488f-8d9a-176b65f45d46 none
swap sw
0
0
/dev/scd0
/media/cdrom0 udf,iso9660 user,noauto 0
0
sudo sed -i'.bak' "s/^UUID=.*\/tmp\s\+ext3\s\+defaults\s\+[0-9]\s\+[0-9]\s\?/UUID=$new_uuid \/tmp ext3
defaults 0 2/" /etc/fstab
sudo mount -a && ls /tmp
student@vm1:~$ sudo umount /tmp && pv ~/tmp.img | sudo dd of=$dd_if bs=10M
241MB 0:00:04 [54.2MB/s]
[=========================================================================================
======================>] 100%
0+1928 records in
0+1928 records out
252706816 bytes (253 MB) copied, 5.52494 s, 45.7 MB/s
student@vm1:~$ rm -v tmp.img
rm: remove write-protected regular file `tmp.img'? y
removed `tmp.img'
student@vm1:~$
Explanation
Creates in archive or /opt/root/ in your home directory. Archive file has extension
.tgz because this archive actually consists of two parts, like a matryoshka doll. First
part is designated by letter t and is one big file in which all archived files are merged
by program tar. Second part is designated by letters gz and means that tar called
gzip program for you to compress it.
Tests this archive.
Changes directory to /tmp.
Extracts your archive.
Prints out directory contents.
Extracts name of a partition which is mounted on /tmp, stores it in dd_if variable,
and if extraction was successful prints out dd_if value. if stands for input file.
Copies whole partition to tmp.img in your home directory. dd is called as superuser
because you are accessing file /dev/sda8 representing your partition which is not
accessible for normal users.
Changes directory to your home directory and prints out its content.
Tells Linux to use tmp.img file as a physical partition (sort of) and mounts it.
Prints out content of tmp.img. You are able to see that it really is exact copy of /tmp.
Unmounts tmp.img and tells Linux to stop treating is as partition.
79
Unmounts /tmp and creates new filesystem there, deleting everything which was
there in the process.
Extracts UUID of your new /tmp filesystem, stores it in new_uuid and prints it out.
Prints out a line describing old /tmp partition from /etc/fstab.
Shows you how modified /etc/fstab will look. It is done by using regular expression,
which work as a mask which define this line:
UUID=f8288adc-3ef9-4a6e-aab2-92624276b8ba /tmp ext3 defaults 0 2
After you finish this book I will give you a link which will allow you to learn how to
create such regular expressions.
Makes actual replacement of /tmp old UUID with new UUID.
Mounts all filesystems described in /etc/fstab and lists contents of your new /tmp
Unmounts new /tmp and restores old /tmp from tmp.img.
Gets old /tmp UUID, which is actually the same as it was before you created a new
filesystem, because tmp.img is perfect copy of your old /tmp.
Replaces new UUID with old UUID in your /etc/fstab.
Mounts all filesystems from /etc/fstab. If this command does not result in error,
chances are you did everything right. Congratulations.
Removes tmp.img from your home directory.
Extra credit
Try to explain in detail what each command does. Take a list of paper and write it all
out. Look up all not well understood commands and parameters in the man.
It is a bit early for this, but why you were able to remove tmp.img from your home
directory issuing removal command as student, considering that tmp.img was
created as root?
80
Exercise 23. Filesystems: security
permissions, chown, chmod, umask
It is time to understand Linux filesystems security model. Let us start with quoting
Wikipedia article on permissions:
Most current file systems have methods of administering permissions or access
rights to specific users and groups of users. These systems control the ability of the
users to view or make changes to the contents of the filesystem.
Permissions on Unix-like systems are managed in three distinct classes. These
classes are known as user, group, and others. In effect, Unix permissions are a
simplified form of access control lists (ACLs).
When a new file is created on a Unix-like system, its permissions are determined
from the umask of the process that created it.
For each file in Linux there are three permission classes associated with it. For each
permission class there are three permissions.
This are permission classes:
Class Description
user One system user. The file is said to be owned by this user.
group One group of users
others Any other users or groups
This are permissions, assignable for each class:
Symbolic
Permission
Description
notation
r-read
Ability to read the file
-wwrite
Ability to write to the file
Ability to execute file as a program,
--x
execute
for example a shell script should have this set
This two tables can be summed up:
Owner Group Others
r w x r w x r w
x
This permissions are represented as numbers. Consider the following output:
student@vm1:~$ ls -al tmp.img
-rw-r--r-- 1 root root 252706816 Jul 6 07:54 tmp.img
student@vm1:~$ stat tmp.img
File: 'tmp.img'
Size: 252706816
Blocks: 494064 IO Block: 4096 regular file
Device: 809h/2057d
Inode: 88534
Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2012-07-06 07:56:58.000000000 -0400
Modify: 2012-07-06 07:54:54.000000000 -0400
Change: 2012-07-06 07:54:54.000000000 -0400
student@vm1:~$
Here we are able to see that tmp.img is owned by user root and group root and has
the following permissions: -rw-r–r–. Let us learn to read them.
-rw
r-r-1
# Owner can read and write to the file
# Group can only read the file
# Others can also only read the file
#
81
root
# Owner is user root
root
# Group is root (but remember not to confuse this with user)
252706816 #
Jul
#
6
#
07:54
#
tmp.img #
Here are the same permissions is octal notation:
Access:
(
0
6 -rw
4 r-4 r-)
Uid: ( 0/
Gid: ( 0/
root)
root)
And this is the table for translating from octal to symbolic notation:
Symbolic Octal Binary . Symbolic Octal Binary
--0
000
4
101
. r---x
1
001
5
100
. r-x
-w2
010
6
110
. rw-wx
3
011
7
111
. rwx
Notice that resulting permissions are obtained with simple addition. For example, let
us take r-x permission. r in octal notation is 4, x is 1, 1+4 is 5 which is r-x.
Now lets talk about zero in stat output 0644. This is for setting up something called
SUID, SGID and Sticky bit. I will not cover it in detail, but I will give you an Extra
Credit task for this and translation tables.
Special bits:
Symbolic
Mode
Description
notataion
SUID u-Set User ID upon execution.
SGID -gSet Group ID upon execution.
Works only for directories, when set, files in that directory may only
Sticky --s
be unlinked or renamed by root or their owner.
Translating special bits from symbolic to octal notation:
Symbolic Octal Binary . Symbolic Octal Binary
--0
000
4
101
. u---s
1
001
5
100
. u-s
-g2
010
6
110
. ug-gs
3
011
7
111
. ugs
Now what about newly created file? For example, you created a file with touch
umask.test, which permissions will it have? It turns out that you are able to control
this with file mode creation mask, umask. Is a mechanism to define which
permissions assign to files when you are creating it. The umask works by masking
out, that is substracting permissions from default ones, which for bash are 777 for
directories and 666 for files. Umask is define for user, group and others also.
Mapping betweend umask values and permissions:
Symbolic Octal Binary . Symbolic Octal Binary
82
4
101
. -wc
rw1
001
5
100
. -wr-x
2
010
6
110
. --x
r-3
011
7
111
. --To understand more clearly, here is another table. Remember that this permissions
are masked out, that is they are removed. For simplicity in this example user, group
and others permissions are the same.
Effective
permissions
Umask
Masked out (removed)
for a new file with Notes
value
permisssions
default
permissions 666
666 write, read and All default permissions
000
none
execute
are preserved
666 write, read and Because new files are
111
execute only
execute
not executable
555 read and
222
write only
execute
333
write and execute
444 read only
333 write and
444
read only
execute
555
read and execute
222 write
666
read and write
111 execute
No permissions are
777
read, write and execute
000 nothing
preserved
Another umask example:
Octal Symbolic
022
--- -w- -wumask
New files
666
rw- rw- rwInitial file permission
022
--- -w- -wCompliment of umask
644
rw- r-- r-Resultant file permission
New directory
777
rwx rwx rwx
Initial directory permission
022
--- -w- -wComplement of umask
rwx r-x r-x
Resultant directory permission 655
Let us summarize this infodump:
Permissions, or access rights — mechanism for controlling access to files and
directories.
Permission modes — types of permissions which allow actions with files.
Read, r — ability to read the file.
Write, w — ability to write to the file.
Execute, x — ability to execute the file as a program. For directories this has a
special meaning, namely it allows directory to be listed.
Classes of users — entities to which permissions are applied.
rwx
0
000
83
User/owner class, u — owner of file or directory, often is is the one who created
them.
Group class, g — group is a collections of users.
Others class, o — everyone else except owner and group.
Umask — a mechanism for controlling access to newly created files.
And the commands to manage permissions:
chmod — change file permissions.
chown — change owner permissions.
umask — change mask for assigning permissions to new files.
Now you will learn how to change file permissions, file owner and umask.
Do this
1: umask
2: echo 'test' > perms.022
3: ls -l perms.022
4: stat perms.022 | grep 'Access: ('
5: chmod 000 perms.022
6: ls -al perms.0022
7: echo 'test' > perms.022
8: rm -v perms.022
Remember question from Extra Credit of previous exercise? You are in similar
situation now, because you are not allowed to do anything with this file. But why you
are allowed to remove it? That is because when removing file, you are actually
removing information about this file from directory, doing nothing with file itself. I
have nice extra credit for you on this topic.
9: umask 666
10: echo 'test' > perms.000
11: ls -l perms.000
12: cat perms.000
13: chmod 600 perms.000
14: cat perms.000
15: rm -v perms.000
16: umask 027
17: echo 'test' > perms.027
18: ls -l perms.027
19: sudo chown root perms.027
20: echo 'test1' >> perms.027
21: chown student perms.027
22: sudo chown student perms.027
23: echo 'test1' >> perms.027
24: rm -v perms.027
25: umask 022
What you should see
student@vm1:~$ umask
0027
student@vm1:~$ echo 'test' > perms.022
student@vm1:~$ ls -l perms.022
-rw-r----- 1 student student 5 Jul 9 10:23 perms.022
student@vm1:~$ stat perms.022 | grep 'Access: ('
Access: (0640/-rw-r-----) Uid: ( 1000/ student) Gid: ( 1000/ student)
student@vm1:~$ chmod 000 perms.022
student@vm1:~$ ls -al perms.0022
ls: cannot access perms.0022: No such file or directory
student@vm1:~$ echo 'test' > perms.022
-bash: perms.022: Permission denied
84
student@vm1:~$ rm -v perms.022
rm: remove write-protected regular file `perms.022'? y
removed `perms.022'
student@vm1:~$ umask 666
student@vm1:~$ echo 'test' > perms.000
student@vm1:~$ ls -l perms.000
---------- 1 student student 5 Jul 9 10:23 perms.000
student@vm1:~$ cat perms.000
cat: perms.000: Permission denied
student@vm1:~$ chmod 600 perms.000
student@vm1:~$ cat perms.000
test
student@vm1:~$ rm -v perms.000
removed `perms.000'
student@vm1:~$ umask 027
student@vm1:~$ echo 'test' > perms.027
student@vm1:~$ ls -l perms.027
-rw-r----- 1 student student 5 Jul 9 10:24 perms.027
student@vm1:~$ sudo chown root perms.027
student@vm1:~$ echo 'test1' >> perms.027
-bash: perms.027: Permission denied
student@vm1:~$ chown student perms.027
chown: changing ownership of `perms.027': Operation not permitted
student@vm1:~$ sudo chown student perms.027
student@vm1:~$ echo 'test1' >> perms.027
student@vm1:~$ rm -v perms.027
removed `perms.027'
student@vm1:~$ umask 022
Explanation
Prints current umask.
Creates file perms.022 containing line test.
Prints out information about this file.
Prints out permission information about this file in octal notation.
Changes permissions on this file, forbidding anyone to do anything with it.
Prints out information about this file.
Tries to replace this file contents with line 'test', failing because of absent
permissions.
Removes this file. This is is possible because file itself is not being touched, only an
entry from directory /home/student is.
Changes umask to assign none permissions by default.
Creates file perms.000 containing line test.
Prints out information about this file.
Tries to print out this file content, which obviously results in error.
Changes file permissions to allow owner to read and write it.
Prints this file contents, this time successfully.
Removes this file.
Changes umask once more.
Creates file perms.027 containing line test.
Prints out information about this file.
Changes file owner to root.
Tries to append line test1 to this file, what results in error.
Tries to change file owner back to student, failing this because information about file
owner is contained in file itself, more precisely in its index node.
85
Changes file owner back to student, this time succeeding because run as root.
Adds line test1 to our file, this time successfully.
Removes perms.027.
Returns umask to its default value.
Extra credit
Read man chmod, man chown, man umask.
Reread man chmod on setuid, setgid and sticky bits. Set your directory setuid bit
in such a way that when doing umask 002 && echo test | sudo tee perms.root
student was the resulting group of perms.root.
Find out why umask 002 did not work.
Try this:
student_block0=$(echo 'stat /student' | sudo debugfs /dev/sda9 2>/dev/null | grep '(0)' | cut -d':' -f2)
echo $student_block0
sudo dd if=/dev/sda9 bs=4096 skip=$student_block0 count=1 | hexdump -C
Cool, huh? You have just read the directory contents directly from raw partition. Well,
when you are deleting a file, an entry is deleted from here, and you have
permissions to modify this entries because this is what directory (a special file)
actually is.
86
Exercise 24. Networking: interface
configuration, ifconfig, netstat,
iproute2, ss, route
This exercise is a big one in terms of info dumped on you, and if you are not familiar
with networking this is gonna hurt. If you feel absolutely lost, skip to the Do This part
right away and be done with it. To understand this part properly you should be at
least superfluously familiar with the following basic concepts of networking:
Communications protocol — a communications protocol which is a system of
digital message formats and rules for exchanging those messages in or between
computing systems and in telecommunications.
Ethernet — family of computer networking technologies for local area networks
(LANs).
MAC address — an unique identifier assigned to network interfaces for
communications on the physical network segment. Example: 08:00:27:d4:45:68.
TCP/IP — the Internet protocol suite is the set of communications protocols used for
the Internet and similar networks, and generally the most popular protocol stack for
wide area networks. It is commonly known as TCP/IP, because of its most important
protocols: Transmission Control Protocol (TCP) and Internet Protocol (IP)
IP — the Internet Protocol (IP) is the principal communications protocol used for
relaying datagrams (also known as network packets) across an internetwork using
the Internet Protocol Suite.
IP address — an Internet Protocol address. Example: 10.0.2.15
Port — application-specific or process-specific software construct serving as a
communications endpoint in a computer's host operating system. Example: 22
Network socket — an endpoint of an inter-process communication flow across a
computer network. Today, most communication between computers is based on the
Internet Protocol; therefore most network sockets are Internet sockets.
Local socket address — local IP address and port number, example: 10.0.2.15:22.
Remote socket address — remote IP address and port number, only for
established TCP sockets. Example: 10.0.2.2:52173.
Socket pair — communicating local and remote sockets, only TCP protocol.
Example: (10.0.2.15:22, 10.0.2.2:52173).
Subnet mask — logically visible subdivision of an IP network. Example: /24 or, in
another notation, 255.255.255.0.
Routing — the process of selecting paths in a network along which to send network
traffic.
Default gateway — in computer networking, a gateway is a node (a router) on a
TCP/IP network that serves as an access point to another network. A default
gateway is the node on the computer network that the network software uses when
an IP address does not match any other routes in the routing table. Example:
10.0.2.2.
Broadcast address — logical address at which all devices connected to a multipleaccess communications network are enabled to receive datagrams. A message sent
to a broadcast address is typically received by all network-attached hosts, rather
than by a specific host. Example: 10.0.2.255.
ICMP — Internet Control Message Protocol, example usage: ping 10.0.2.2.
87
TCP — Transmission Control Protocol. Establishes connection before data can be
exchanged, therefore reliable by design. Example users: SSH, HTTP.
UDP — User Datagram Protocol. Transfers data without establishing connection,
therefore unreliable by design. Example users: DNS.
If some of this concepts are not familiar to you, no worries.
Read corresponding Wikipedia articles until you achieve at least superfluous
understanding (but good old hardcore grinding is of course better).
Watch this videos from http://www.visualland.net.cn/:
Expand IP Address tree node in the left of the site and work you way through it.
Expand TCP tree node and do the same.
Read Linux networking concepts introduction. This guide is good because it even
acknowledges that The Internet is for porn.
Let us continue. This is list of Linux network-related commands:
ifconfig — configure and view status of network interface.
netstat — print network connections, routing tables, interface statistics, masquerade
connections, and multicast memberships.
ip — show / manipulate routing, devices, policy routing and tunnels.
ss — another utility to investigate sockets.
Now let us examine what information each command can show us. We will start with
ifconfig.
student@vm1:~$ sudo ifconfig
eth0
Link encap:Ethernet HWaddr 08:00:27:d4:45:68
# (1), (2), (3)
inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0 # (4), (5), (6), (7)
inet6 addr: fe80::a00:27ff:fed4:4568/64 Scope:Link
# (8), (9), (10)
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
# (11), (12), (13), (14),
(15), (16)
RX packets:35033 errors:0 dropped:0 overruns:0 frame:0
# (17), (18), (19), (20), (21), (22)
TX packets:28590 errors:0 dropped:0 overruns:0 carrier:0 # (23), (24), (25), (26), (27), (28)
collisions:0 txqueuelen:1000
# (29), (30)
RX bytes:6360747 (6.0 MiB) TX bytes:21721365 (20.7 MiB) # (31), (32)
lo
Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:560 (560.0 B) TX bytes:560 (560.0 B)
We can see that there are two network interfaces in vm1, eth0 and lo. lo is a
loopback interface, which is used to connect to client-server programs on the same
machine.
Let us see what information we have on eth0, which is a VirtualBox pseudo network
interface:
Field
Description
Field
Description
(1) Link
Physical options
(17) RX
Receive (abbreviation)
(2) encap
Encapsulation type
(18) packets Total number of packets
Total number of packets
(3) Hwaddr
MAC-address
(19) errors
with errors
Dropped packets (low
(4) inet
Address family (IPv4)
(20) dropped
system memory?)
88
(5) addr
IPv4 address
(6) Bcast
(7) Mask
(8) inet6
Broadcast address
Network mask
Address family (IPv6)
(9) addr
IPv6 address
(10) Scope
Address scope (host,
link, global)
(11) UP
Interface is functioning
(21)
overruns
(22) frame
(23) TX
(24) packets
Packets come faster than
they can be processed
Invalid frames received
Transmit (abbreviation)
Total number of packets
Total number of packets
(25) errors
with errors
Dropped packets (low
(26) dropped
system memory?)
(27)
An app sends packes very
overruns
fast? (I am not sure)
(12)
BROADCAST
It can send traffic to all
(28) carrier Loss of link carrier wave
hosts at once
It is ready to accept data (29)
(13) RUNNING
Packed collision did occur
(I am not sure)
collisions
(14)
It can send and receive (30)
Transmin queue length for
MULTICAST
multicast packets
txqueuelen outgoing packets
Its Maximum transfer
(31) RX
(15) MTU
Total received bytes
unit
bytes
Route cost (not used in (32) TX
(16) Metric
Total sent bytes
Linux)
bytes
That sure is a lot. But then again, for now only important fields are:
(5) addr — IPv4 address.
(6) Bcast — Broadcast address.
(7) Mask — Network mask.
(11) UP — Interface is functioning.
(13) RUNNING — It is ready to accept data.
(19) errors and (25) errors — if there is something different from zero here, we have
problems.
Now let us see what netstat can show us.
student@vm1:~$ sudo netstat -ap
Active Internet connections (servers and established)
#(1) (2) (3) (4)
(5)
(6)
(7)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address
Foreign Address
State
PID/Program name
tcp
0
0 *:sunrpc
*:*
LISTEN
580/portmap
tcp
0
0 *:ssh
*:*
LISTEN
900/sshd
tcp
0
0 localhost:smtp
*:*
LISTEN
1111/exim4
tcp
0
0 *:36286
*:*
LISTEN
610/rpc.statd
tcp
0
0 10.0.2.15:ssh
10.0.2.2:52191
ESTABLISHED 12023/sshd: student [
tcp
0
0 10.0.2.15:ssh
10.0.2.2:48663
ESTABLISHED 11792/sshd: student [
tcp6
0
0 [::]:ssh
[::]:*
LISTEN
900/sshd
tcp6
0
0 ip6-localhost:smtp
[::]:*
LISTEN
1111/exim4
udp
0
0 *:bootpc
*:*
843/dhclient
udp
0
0 *:sunrpc
*:*
580/portmap
udp
0
0 *:52104
*:*
610/rpc.statd
udp
0
0 *:786
*:*
610/rpc.statd
#(8) (9) (10)
(11)
(12)
(13) (14)
(15)
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags
Type
State
I-Node PID/Program name Path
unix 2
[ ACC ] STREAM LISTENING 3452 786/acpid
/var/run/acpid.socket
89
unix
unix
unix
unix
unix
unix
unix
unix
unix
unix
unix
unix
unix
6
2
2
3
3
2
3
3
2
2
2
3
3
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
[]
DGRAM
DGRAM
DGRAM
STREAM
STREAM
DGRAM
STREAM
STREAM
DGRAM
DGRAM
DGRAM
DGRAM
DGRAM
3407
1940
88528
CONNECTED
CONNECTED
68563
CONNECTED
CONNECTED
66680
3465
3448
1945
1944
751/rsyslogd
/dev/log
214/udevd
@/org/kernel/udev/udevd
30939/sudo
68565 12023/sshd: student [
68564 12026/1
12023/sshd: student [
66682 11792/sshd: student [
66681 11794/0
11792/sshd: student [
843/dhclient
786/acpid
214/udevd
214/udevd
I used two parameters to modify netstat output. -a parameter told netstat to show us
all connections, both established, like your current ssh session through which your
are typing, and listening, like sshd daemon waiting for new connections. -p told
netstat to show which program owns each connection.
Active Internet Connections (servers and established)
Field
Description
(1) Proto
The protocol (tcp, udp, raw) used by the socket.
The count of bytes not copied by the user program connected to this
(2) Recv-Q
socket.
(3) Send-Q The count of bytes not acknowledged by the remote host.
(4) Local
Address and port number of the local end of the socket.
Address
(5) Foreign
Address and port number of the remote end of the socket.
Address
ESTABLISHED, SYN_SENT, SYN_RECV, FIN_WAIT1, FIN_WAIT2,
(6) State
TIME_WAIT, CLOSE, CLOSE_WAIT, LAST_ACK, LISTEN,
CLOSING, UNKNOWN
Slash-separated pair of the process id (PID) and process name of the
(7) PID
process that owns the socket.
Active UNIX domain sockets (servers and established)
Field
Description
(8) Proto
The protocol (usually unix) used by the socket.
(9) RefCnt
The reference count (i.e. attached processes via this socket).
The flags displayed is SO_ACCEPTON (displayed as ACC),
(10) Flags
SO_WAITDATA (W) or SO_NOSPACE (N).
SOCK_DGRAM, SOCK_STREAM, SOCK_RAW, SOCK_RDM,
(11) Type
SOCK_SEQPACKET, SOCK_PACKET, UNKNOWN.
FREE, LISTENING, CONNECTING, CONNECTED,
(12) State
DISCONNECTING, (empty), UNKNOWN.
(13) I-Node I-Node of socket file.
Process ID (PID) and process name of the process that has the socket
(14) PID
open.
This is the path name as which the corresponding processes attached
(15) Path
to the socket.
90
Not all fields are actually important. Usually you have to look only in Active Internet
Connections (servers and established) section, and use this fields:
(1) Proto — The protocol (tcp, udp, raw) used by the socket.
(4) Local Address — address and port number of the local end of the socket.
(5) Foreign Address — address and port number of the remote end of the socket,
only for socket pairs.
(6) State — for now you should know only two states: LISTEN and ESTABLISHED.
First means that you may connect to this socket, second means that this socket
already is connected, and in this cases netstat shows you socket pair.
ip is a program similar to ifconfig with extended capabilities. It is from iproute2 suite
which is intended to replace ifconfig some day. Example output:
student@vm1:~$ sudo ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
#
(1)
(2)
(3) (4)
(5)
(6)
(8)
(9)
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:d4:45:68 brd ff:ff:ff:ff:ff:ff
# (9), (10), (11)
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
# (12), (13), (14)
inet6 fe80::a00:27ff:fed4:4568/64 scope link
# (15), (16)
valid_lft forever preferred_lft forever
# (17), (18), (19)
Again, let us see what information we have on eth0:
Field
Description
(1) BROADCAST It can send traffic to all hosts at once
(2) MULTICAST It can send and receive multicast packets
(3) UP
It is functioning, logical state
(4) LOWER_UP Driver signals L1 up (since Linux 2.6.17)
(5) MTU
Maximum transfer unit
(6) qdisc
Queueing discipline, basically traffic scheduler policy
(8) State
Physical state (carrier sense?)
(9) qlen
Transmin queue length for outgoing packets
(10) link
Physical options
(11) ether
Encapsulation type, MAC-address
(12) brd
Data Link Layer (physical) broadcast address
(13) inet
IPv4 address family address
(14) brd
IPv4 boradcast
(15) scope
IPv4 Address scope (host, link, global)
(16) inet6
IPv6 address family address
(17) scope
IPv6 Address scope (host, link, global
(18) valid_lft
IPv6 source address selection policy
(19) preffered_lft IPv6 source address selection policy
You already know which parameters are important (the same as in ifconfig).
ss is basically contemporary netstat with extended capabilities. This is its example
output, interpretation of which is left as exercise for you:
student@vm1:~$ sudo ss -ap | cut -c1-200
State
Recv-Q Send-Q Local Address:Port
Peer Address:Port
91
LISTEN 0
128
*:sunrpc
LISTEN 0
128
:::ssh
LISTEN 0
128
*:ssh
LISTEN 0
20
::1:smtp
LISTEN 0
20
127.0.0.1:smtp
LISTEN 0
128
*:36286
ESTAB
0
0
10.0.2.15:ssh
users:(("sshd",12023,3),("sshd",12026,3))
ESTAB
0
0
10.0.2.15:ssh
users:(("sshd",11792,3),("sshd",11794,3))
*:*
users:(("portmap",580,5))
:::*
users:(("sshd",900,4))
*:*
users:(("sshd",900,3))
:::*
users:(("exim4",1111,4))
*:*
users:(("exim4",1111,3))
*:*
users:(("rpc.statd",610,7))
10.0.2.2:52191
10.0.2.2:48663
This is for working with interface, connetctions and interface addresses. But what
about network routes? You can get information about them using several commands
as well:
student@vm1:~$ sudo route -n
Kernel IP routing table
# (1)
(2)
(3)
(4) (5) (6) (7) (8)
Destination Gateway
Genmask
Flags Metric Ref Use Iface
10.0.2.0
*
255.255.255.0 U 0
0
0 eth0
default
10.0.2.2
0.0.0.0
UG 0
0
0 eth0
student@vm1:~$ sudo netstat -nr
Kernel IP routing table #
(9)
Destination Gateway
Genmask
Flags MSS Window irtt Iface
10.0.2.0
0.0.0.0
255.255.255.0 U
00
0 eth0
0.0.0.0
10.0.2.2
0.0.0.0
UG
00
0 eth0
student@vm1:~$ sudo ip route show
# (10)
(11)
(12)
(13)
(14)
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
#(15)
(16)
default via 10.0.2.2 dev eth0
Let us work through fields onece more:
Field
Description
(1)
The destination network or destination host.
Destination
(2) Gateway The gateway address or '*' if none set.
The netmask for the destination net; '255.255.255.255' for a host
(3) Genmask
destination and '0.0.0.0' for the default route.
Up, Host, Gateway, Reinstate, Dynamically installed, Modified,
(4) Flags
Addrconf, Cache entry, ! reject.
The 'distance' to the target (usually counted in hops). It is not used by
(5) Metric
recent kernels, but may be needed by routing daemons.
(6) Ref
Number of references to this route. (Not used in the Linux kernel.)
(7) Use
Count of lookups for the route.
(8) Iface
Interface to which packets for this route will be sent.
Initial RTT (Round Trip Time). The kernel uses this to guess about the
(9) irtt
best TCP protocol parameters
without waiting on (possibly slow) answers.
(10)
The destination network or destination host.
Net/Mask
(11) dev
Interface to which packets for this route will be sent.
(12) proto
man ip /RTPROTO: redirect, kernel, boot, static, ra
(13) scope man ip /SCOPE_WALUE: global, site, link, host
92
The source address to prefer when sending to the destinations
covered by the route prefix.
Gateway address for all addresses without explicitly assigned
(15) default
gateways
(15) dev
Interface to which packets for this route will be sent.
The important field for now:
(1) Destination — The destination network or destination host.
(2) Gateway — The gateway address or '*' if none set. Default means that packets
will be sent via this gateway if there is no explicitly specified gateway for packet
destination address.
(3) Genmask — The netmask for the destination net; '255.255.255.255' for a host
destination and '0.0.0.0' for the default route.
(8) Iface — Interface to which packets for this route will be sent.
Which field from netstat and route correspond to which from ip route show is left
as an exercise for you once more. Well, that was awfully big! Take a deep breath
and let us move to the practice.
Now you will learn how to create pseudo-interface, assign address to it and change it
state.
(14) src
Do this
1: sudo aptitude install uml-utilities
2: sudo tunctl -t tap0 -u student
3: ls -al /sys/devices/virtual/net/tap0
4: sudo ifconfig tap0 10.1.1.1 netmask 255.255.255.0
5: sudo ifconfig
6: sudo route
7: ping 10.1.1.1 -c 2
8: sudo ifconfig tap0 down
9: ping 10.1.1.1 -c 2
10: sudo ifconfig tap0 up
11: sudo ip a a 10.2.2.2/24 brd + dev tap0
12: sudo ifconfig
13: sudo route
14: ip a s
15: ip r s
16: ping 10.2.2.2 -c 2
17: sudo ip link set dev tap0 down
18: ip a s
19: ip r s
20: ping 10.2.2.2 -c 2
21: sudo tunctl -d tap0
22: ip a s
23: ls -al /sys/devices/virtual/net/tap0
What you should see
student@vm1:~$ sudo aptitude install uml-utilities
The following NEW packages will be installed:
libfuse2{a} uml-utilities
0 packages upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/205 kB of archives. After unpacking 737 kB will be used.
Do you want to continue? [Y/n/?]
Selecting previously deselected package libfuse2.
(Reading database ... 39616 files and directories currently installed.)
Unpacking libfuse2 (from .../libfuse2_2.8.4-1.1_amd64.deb) ...
Selecting previously deselected package uml-utilities.
Unpacking uml-utilities (from .../uml-utilities_20070815-1.1_amd64.deb) ...
93
Processing triggers for man-db ...
Setting up libfuse2 (2.8.4-1.1) ...
Setting up uml-utilities (20070815-1.1) ...
Starting User-mode networking switch: uml_switch.
student@vm1:~$ sudo tunctl -t tap0 -u student
Set 'tap0' persistent and owned by uid 1000
student@vm1:~$ ls -al /sys/devices/virtual/net/tap0
total 0
drwxr-xr-x 4 root root 0 Jul 11 05:33 .
drwxr-xr-x 4 root root 0 Jul 11 05:33 ..
-r--r--r-- 1 root root 4096 Jul 11 05:33 address
-r--r--r-- 1 root root 4096 Jul 11 05:33 addr_len
-r--r--r-- 1 root root 4096 Jul 11 05:33 broadcast
-r--r--r-- 1 root root 4096 Jul 11 05:33 carrier
-r--r--r-- 1 root root 4096 Jul 11 05:33 dev_id
-r--r--r-- 1 root root 4096 Jul 11 05:33 dormant
-r--r--r-- 1 root root 4096 Jul 11 05:33 duplex
-r--r--r-- 1 root root 4096 Jul 11 05:33 features
-rw-r--r-- 1 root root 4096 Jul 11 05:33 flags
-r--r--r-- 1 root root 4096 Jul 11 05:33 group
-rw-r--r-- 1 root root 4096 Jul 11 05:33 ifalias
-r--r--r-- 1 root root 4096 Jul 11 05:33 ifindex
-r--r--r-- 1 root root 4096 Jul 11 05:33 iflink
-r--r--r-- 1 root root 4096 Jul 11 05:33 link_mode
-rw-r--r-- 1 root root 4096 Jul 11 05:33 mtu
-r--r--r-- 1 root root 4096 Jul 11 05:33 operstate
-r--r--r-- 1 root root 4096 Jul 11 05:33 owner
drwxr-xr-x 2 root root 0 Jul 11 05:33 power
-r--r--r-- 1 root root 4096 Jul 11 05:33 speed
drwxr-xr-x 2 root root 0 Jul 11 05:33 statistics
lrwxrwxrwx 1 root root 0 Jul 11 05:33 subsystem -> ../../../../class/net
-r--r--r-- 1 root root 4096 Jul 11 05:33 tun_flags
-rw-r--r-- 1 root root 4096 Jul 11 05:33 tx_queue_len
-r--r--r-- 1 root root 4096 Jul 11 05:33 type
-rw-r--r-- 1 root root 4096 Jul 11 05:33 uevent
student@vm1:~$ sudo ifconfig tap0 10.1.1.1 netmask 255.255.255.0
student@vm1:~$ sudo ifconfig
eth0
Link encap:Ethernet HWaddr 08:00:27:d4:45:68
inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:fed4:4568/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:64040 errors:0 dropped:0 overruns:0 frame:0
TX packets:44578 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:19663646 (18.7 MiB) TX bytes:25043918 (23.8 MiB)
lo
Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:76 errors:0 dropped:0 overruns:0 frame:0
TX packets:76 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:6272 (6.1 KiB) TX bytes:6272 (6.1 KiB)
tap0
Link encap:Ethernet HWaddr ee:d8:2e:f6:bc:f1
inet addr:10.1.1.1 Bcast:10.1.1.255 Mask:255.255.255.0
inet6 addr: fe80::ecd8:2eff:fef6:bcf1/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
94
TX packets:0 errors:0 dropped:1 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
student@vm1:~$ sudo route
Kernel IP routing table
Destination Gateway
Genmask
Flags Metric Ref Use Iface
10.0.2.0
*
255.255.255.0 U 0
0
0 eth0
10.1.1.0
*
255.255.255.0 U 0
0
0 tap0
default
10.0.2.2
0.0.0.0
UG 0
0
0 eth0
student@vm1:~$ ping 10.1.1.1 -c 2
PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_req=1 ttl=64 time=0.070 ms
64 bytes from 10.1.1.1: icmp_req=2 ttl=64 time=0.027 ms
--- 10.1.1.1 ping statistics --2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.027/0.048/0.070/0.022 ms
student@vm1:~$ sudo ifconfig tap0 down
student@vm1:~$ ping 10.1.1.1 -c 2
PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_req=1 ttl=64 time=0.030 ms
64 bytes from 10.1.1.1: icmp_req=2 ttl=64 time=0.024 ms
--- 10.1.1.1 ping statistics --2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.024/0.027/0.030/0.003 ms
student@vm1:~$ sudo ifconfig tap0 up
student@vm1:~$ sudo ip a a 10.2.2.2/24 brd + dev tap0
student@vm1:~$ sudo ifconfig
eth0
Link encap:Ethernet HWaddr 08:00:27:d4:45:68
inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:fed4:4568/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:64088 errors:0 dropped:0 overruns:0 frame:0
TX packets:44609 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:19667480 (18.7 MiB) TX bytes:25049771 (23.8 MiB)
lo
Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:84 errors:0 dropped:0 overruns:0 frame:0
TX packets:84 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:6944 (6.7 KiB) TX bytes:6944 (6.7 KiB)
tap0
Link encap:Ethernet HWaddr ee:d8:2e:f6:bc:f1
inet addr:10.1.1.1 Bcast:10.1.1.255 Mask:255.255.255.0
inet6 addr: fe80::ecd8:2eff:fef6:bcf1/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:9 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
student@vm1:~$ sudo route
Kernel IP routing table
Destination Gateway
Genmask
Flags Metric Ref Use Iface
10.2.2.0
*
255.255.255.0 U 0
0
0 tap0
95
10.0.2.0
*
255.255.255.0 U 0
0
0 eth0
10.1.1.0
*
255.255.255.0 U 0
0
0 tap0
default
10.0.2.2
0.0.0.0
UG 0
0
0 eth0
student@vm1:~$ ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:d4:45:68 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
inet6 fe80::a00:27ff:fed4:4568/64 scope link
valid_lft forever preferred_lft forever
12: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN
qlen 500
link/ether ee:d8:2e:f6:bc:f1 brd ff:ff:ff:ff:ff:ff
inet 10.1.1.1/24 brd 10.1.1.255 scope global tap0
inet 10.2.2.2/24 brd 10.2.2.255 scope global tap0
inet6 fe80::ecd8:2eff:fef6:bcf1/64 scope link
valid_lft forever preferred_lft forever
student@vm1:~$ ip r s
10.2.2.0/24 dev tap0 proto kernel scope link src 10.2.2.2
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
10.1.1.0/24 dev tap0 proto kernel scope link src 10.1.1.1
default via 10.0.2.2 dev eth0
student@vm1:~$ ping 10.2.2.2 -c 2
PING 10.2.2.2 (10.2.2.2) 56(84) bytes of data.
64 bytes from 10.2.2.2: icmp_req=1 ttl=64 time=0.081 ms
64 bytes from 10.2.2.2: icmp_req=2 ttl=64 time=0.025 ms
--- 10.2.2.2 ping statistics --2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.025/0.053/0.081/0.028 ms
student@vm1:~$ sudo ip link set dev tap0 down
student@vm1:~$ ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:d4:45:68 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
inet6 fe80::a00:27ff:fed4:4568/64 scope link
valid_lft forever preferred_lft forever
12: tap0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN qlen 500
link/ether ee:d8:2e:f6:bc:f1 brd ff:ff:ff:ff:ff:ff
inet 10.1.1.1/24 brd 10.1.1.255 scope global tap0
inet 10.2.2.2/24 brd 10.2.2.255 scope global tap0
student@vm1:~$ ip r s
10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15
default via 10.0.2.2 dev eth0
student@vm1:~$ ping 10.2.2.2 -c 2
PING 10.2.2.2 (10.2.2.2) 56(84) bytes of data.
64 bytes from 10.2.2.2: icmp_req=1 ttl=64 time=0.037 ms
64 bytes from 10.2.2.2: icmp_req=2 ttl=64 time=0.024 ms
--- 10.2.2.2 ping statistics --2 packets transmitted, 2 received, 0% packet loss, time 999ms
96
rtt min/avg/max/mdev = 0.024/0.030/0.037/0.008 ms
student@vm1:~$ sudo tunctl -d tap0
Set 'tap0' nonpersistent
student@vm1:~$ ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:d4:45:68 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
inet6 fe80::a00:27ff:fed4:4568/64 scope link
valid_lft forever preferred_lft forever
student@vm1:~$ ls -al /sys/devices/virtual/net/tap0
ls: cannot access /sys/devices/virtual/net/tap0: No such file or directory
student@vm1:~$
Explanation
Install package for working with pseudo-(virtual)-interfaces.
Create pseudo-interface tap0.
Prints out contents of virtual directory created for this interfaces, containing its
settings and statistics.
Add to tap0 an IP address 10.1.1.1/24.
Print out current interface status.
Print out current routing table entries. Notice that Linux automatically added new
route for tap0.
Tests tap0 by sending ICMP echo request packet to it.
Brings tap0 to DOWN state.
Tests tap0 by sending ICMP echo request packet to it again. There will be an Extra
credit for you to explain why this still works despite intercase being down?
Brings tap0 to UP state.
Adds additional IP address 10.2.2.2/24 to tap0. ip a a is abbreviated version of ip
addr add. What this little + means you will find out on your own in Extra credit.
Prints out current interface status. Notice how ifconfig is unable to list new IP
address added using ip utility. Why? More Extra credit.
Print out current routing table. Notice that Linux automatically added one more route
for tap0.
Prints out current interface status using ip utility. You are able to see newly added
address here.
Prints our routing tables using ip utility.
Tests net tap0 IP address by sending ICMP echo request packet to it.
Brings tap0 to DOWN state.
Prints out current interface status.
Print out current routing table entries. Notice that tap0 routes are remove
automatically.
Tests net tap0 IP address by sending ICMP echo request packet to it. This works.
Why?
Removes pseudo-interface tap0.
Prints out current interface status. tap0 is absent.
Shows us that tap0 virtual directory is now gone as well.
Extra Credit
97
Familiarize yourself with man ifconfig, man ip, man netstat, man ss.
Why ping worked when tap0 was is in down state?
What brd + means?
Why ifconfig is unable to list new address you added using ip?
Exercise 25. Networking: configuration
files, /etc/network/interfaces
Configuring network interfaces from command line is all well, but now it is time to
learn how to tell vm1 to configure them automatically. For this you will learn about
the /etc/network/interfaces configuration file:
student@vm1:~$ cat /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
#(1) (2)
auto lo
#(3) (4)(5) (6)
iface lo inet loopback
# The primary network interface
#(7)
(8)
allow-hotplug eth0
#(9) (10) (11) (12)
iface eth0 inet dhcp
As usual, fields and their descriptions:
Field Description
(1) Automatically configure interface.
(2) Interface name.
(3) Start of interface configuration.
(4) Name of interface being configured.
(5) This interface uses TCP/IP networking, IPv4.
It is loopback interface. Default loopback address will be assigned to it
(6)
automatically.
Configure interface automatically when it becomes available (think usb-modem
(7)
here).
(8) Interface name.
(9) Start of interface configuration.
(10) Name of interface being configured.
(11) This interface uses TCP/IP networking, IPv4.
(12) This interface gets its parameters automatically via DHCP.
Other important files which contain network configuration, but we will not touch them
for here:
/etc/hosts — a computer file used in an operating system to map hostnames to IP
addresses. The hosts file is a plain text file and is conventionally named hosts.
98
/etc/hostname — a label that is assigned to a device connected to a computer
network and that is used to identify the device in various forms of electronic
communication.
/etc/resolv.conf — a computer file used in various operating systems to configure
the Domain Name System (DNS) resolver library. The file is a plain-text file usually
created by the network administrator or by applications that manage the
configuration tasks of the system. The resolvconf program is one such program on
linux machines which manages the resolv.conf file.
Let us remember tap0 from previous exercise. If you reboot vm1 it is gone. Of
course you can enable it by retyping relevant commands, but let us imagine that you
need it to become available automatically after reboot.
Now you will learn how to configure an interface using /etc/network/interfaces file.
Do this
1: ip a s
2: sudo vim /etc/network/interfaces
Now add this lines to the end of configuration file:
3: auto tap0
4: iface tap0 inet static
5:
address 10.2.2.2
6:
netmask 255.255.255.0
7:
tunctl_user uml-net
8:
9: allow-hotplug tap1
10: iface tap1 inet static
11:
address 10.3.3.3
12:
netmask 255.255.255.0
Now type :wq<ENTER> and continue:
13: sudo /etc/init.d/networking start
14: ip a s
15: sudo tunctl -t tap1 -u uml-net
16: ip a s
What you should see
student@vm1:~$ ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:d4:45:68 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
inet6 fe80::a00:27ff:fed4:4568/64 scope link
valid_lft forever preferred_lft forever
student@vm1:~$ sudo vim /etc/network/interfaces
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
allow-hotplug eth0
iface eth0 inet dhcp
auto tap0
99
iface tap0 inet static
address 10.2.2.2
netmask 255.255.255.0
tunctl_user uml-net
allow-hotplug tap1
iface tap1 inet static
address 10.3.3.3
netmask 255.255.255.0
~
"/etc/network/interfaces" 21L, 457C written
21,1-8
Bot
student@vm1:~$ sudo /etc/init.d/networking start
Configuring network interfaces...Set 'tap0' persistent and owned by uid 104 done.
student@vm1:~$ ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:d4:45:68 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
inet6 fe80::a00:27ff:fed4:4568/64 scope link
valid_lft forever preferred_lft forever
3: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN
qlen 500
link/ether 46:63:30:70:b5:21 brd ff:ff:ff:ff:ff:ff
inet 10.2.2.2/24 brd 10.2.2.255 scope global tap0
inet6 fe80::4463:30ff:fe70:b521/64 scope link
valid_lft forever preferred_lft forever
student@vm1:~$ sudo tunctl -t tap1 -u uml-net
Set 'tap1' persistent and owned by uid 104
student@vm1:~$ ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 08:00:27:d4:45:68 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
inet6 fe80::a00:27ff:fed4:4568/64 scope link
valid_lft forever preferred_lft forever
3: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN
qlen 500
link/ether 46:63:30:70:b5:21 brd ff:ff:ff:ff:ff:ff
inet 10.2.2.2/24 brd 10.2.2.255 scope global tap0
inet6 fe80::4463:30ff:fe70:b521/64 scope link
valid_lft forever preferred_lft forever
4: tap1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN
qlen 500
link/ether 8a:ed:90:33:93:55 brd ff:ff:ff:ff:ff:ff
inet 10.3.3.3/24 brd 10.3.3.255 scope global tap1
inet6 fe80::88ed:90ff:fe33:9355/64 scope link
valid_lft forever preferred_lft forever
student@vm1:~$
Explanation
Print out current interface configuration.
Edit /etc/network/interfaces.
100
Automatically configure tap0.
Set the following IPv4 static parameters fop tap0.
Add IP address 10.2.2.2 to tap0.
Specify netmask for this IP address. Parameters broadcast and network are derived
from this netmask automatically.
Specify user who will own tap0 interface.
Empty line for readability.
Add the following parameters to tap1 interface when it appears in the system.
Set the following IPv4 static parameters fop tap1.
Add IP address 10.3.3.3 to tap0.
Specify netmask for this IP address.
Applies changes in network configuration.
Prints out current interface configuration. You are able to see that tap0 is add to the
list of interfaces.
Adds tap1 pseudo-interface.
Prints out current interface configuration. You are able to see that its parameters
specified in /etc/network/interfaces are applied to it automatically.
Extra credit
Explain how network and broadcast parameters are derived.
Try this: ping kitty. Failure is expected. Now add an entry to /etc/hosts so that you
will be able to successfully ping.
Exercise 26. Networking: packet filter
configuration, iptables
Let me start with quoting Wikipedia on iptables:
Iptables is a user space application program that allows a system administrator to
configure the tables provided by the Linux kernel firewall (implemented as different
Netfilter modules) and the chains and rules it stores. Different kernel modules and
programs are currently used for different protocols; iptables applies to IPv4, ip6tables
to IPv6, arptables to ARP, and ebtables to Ethernet frames.
To use it you must understand the following concepts:
LINKTYPE_LINUX_SLL — tcpdump pseudo link layer protocol.
Ethernet frame header — A data packet on an Ethernet link is called an Ethernet
frame. A frame begins with preamble and start frame delimiter. Following which,
each Ethernet frame continues with an Ethernet header featuring destination and
source MAC addresses. The middle section of the frame is payload data including
any headers for other protocols (e.g. Internet Protocol) carried in the frame. The
frame ends with a 32-bit cyclic redundancy check which is used to detect any
corruption of data in transit.
IPv4 header — An IP packet consists of a header section and a data section. The
IPv4 packet header consists of 14 fields, of which 13 are required. The 14th field is
optional and aptly named: options.
TCP segment structure — Transmission Control Protocol accepts data from a data
stream, segments it into chunks, and adds a TCP header creating a TCP segment.
The TCP segment is then encapsulated into an Internet Protocol (IP) datagram. A
101
TCP segment is “the packet of information that TCP uses to exchange data with its
peers.”
I remind you about guides to get them:
Read corresponding Wikipedia articles until you achieve at least superficial
understanding (but good old hardcore grinding is of course better).
Watch this videos from http://www.visualland.net/ (another link
www.visualland.net.cn):
Expand IP Address tree node in the left of the site and work you way through it.
Expand TCP tree node and do the same.
Read Linux networking concepts introduction. This guide is good because it even
acknowledges that The Internet is for porn.
I am not able to describe iptables any better than Peter Harrison's excellent guide. If
you never used it, you should check this guide first.
But what I will, however, put theory into practice and show what happens inside of
iptalbes step-by-step in a very simple scenario of data exchange. First things first,
main concepts:
iptables — program which is used to set up, maintain, and inspect the tables of IPv4
packet filter rules in the Linux kernel. Several different tables may be defined. Each
table contains a number of built-in chains and may also contain user-defined chains.
ip6tables — same for IPv6.
chain — list of rules which can match a set of packets. Each rule specifies what to
do with a packet that matches. This is called a target, which may be a jump to a
user-defined chain in the same table.
target — A firewall rule specifies criteria for a packet and a target. If the packet does
not match, the next rule in the chain is the examined; if it does match, then the next
rule is specified by the value of the target, which can be the name of a user-defined
chain or one of the special values:
ACCEPT — let the packet through.
DROP — drop the packet on the floor.
QUEUE — pass the packet to userspace.
RETURN — stop traversing this chain and resume at the next rule in the previous
(calling) chain. If the end of a built-in chain is reached or a rule in a built-in chain with
target RETURN is matched, the target specified by the chain policy determines the
fate of the packet.
Now let us see what default tables and built-in chains there are:
Table
Built-in chains Description
name
This table is used mainly for configuring exemptions from
connection tracking in combination with the NOTRACK
target. It registers at the netfilter hooks with higher priority
and is thus called before ip_conntrack, or any other IP
raw
tables.
PREROUTING For packets arriving via any network interface.
OUTPUT
For packets generated by local processes.
This table is used for specialized packet alteration.
PREROUTING For altering incoming packets before routing.
mangle
OUTPUT
For altering locally-generated packets before routing.
INPUT
For packets coming into the box itself.
102
FORWARD
For altering packets being routed through the box.
POSTROUTING For altering packets as they are about to go out.
This table is consulted when a packet that creates a new
connection is encountered.
PREROUTING For altering packets as soon as they come in.
nat
OUTPUT
For altering locally-generated packets before routing.
POSTROUTING For altering packets as they are about to go out.
This is the default table (if no -t option is passed).
INPUT
For packets destined to local sockets.
filter
FORWARD
For packets being routed through the box.
OUTPUT
For locally-generated packets.
Okay, we are ready to see how this works in real life. I will send a string Hello world!
to vm1 from my home computer using TCP protocol and netcat utility which is just
like cat, but over the network. The setup:
1. I forwarded another port, 80, to my home PC running Linux so am able to connect
like this:
(My home PC) --> vm1:80
2. I added this rules to iptables to log all what happens with network packets inside
iptables:
sudo iptables -t raw -A PREROUTING -p tcp -m tcp --dport 80 -j TRACE
sudo iptables -t raw -A INPUT -p tcp -m tcp --sport 80 -j TRACE
This is my exact iptables ruleset on vm1:
root@vm1:/home/student# for i in raw mangle nat filter ; do echo -e "\n-----" TABLE: $i '-----' ; iptables t $i -L ; done
----- TABLE: raw ----Chain PREROUTING (policy ACCEPT) target prot opt source
destination
TRACE
tcp -- anywhere
anywhere
tcp dpt:www
Chain OUTPUT (policy ACCEPT)
target prot opt source
destination
TRACE
tcp -- anywhere
anywhere
tcp spt:www
----- TABLE: mangle ----Chain PREROUTING (policy ACCEPT) target prot opt source
destination
Chain INPUT (policy ACCEPT)
target prot opt source
destination
Chain FORWARD (policy ACCEPT) target prot opt source
destination
Chain OUTPUT (policy ACCEPT)
target prot opt source
destination
Chain POSTROUTING (policy ACCEPT) target prot opt source
destination
----- TABLE: nat ----Chain PREROUTING (policy ACCEPT) target prot opt source
Chain POSTROUTING (policy ACCEPT) target prot opt source
Chain OUTPUT (policy ACCEPT)
target prot opt source
----- TABLE: filter ----Chain INPUT (policy ACCEPT)
target prot opt source
Chain FORWARD (policy ACCEPT) target prot opt source
Chain OUTPUT (policy ACCEPT)
target prot opt source
destination
destination
destination
destination
destination
destination
As you can see, there are no other rules. Another way to look at iptables rules is to
use iptables-save utility:
root@vm1:/home/student# iptables-save
# Generated by iptables-save v1.4.8 on Fri Jul 13 08:09:04 2012
#(1)
*mangle
#(2)
(3) (4) (5)
103
:PREROUTING ACCEPT [15662:802240]
:INPUT ACCEPT [15662:802240]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [12756:3671974]
:POSTROUTING ACCEPT [12756:3671974]
COMMIT
# Completed on Fri Jul 13 08:09:04 2012
# Generated by iptables-save v1.4.8 on Fri Jul 13 08:09:04 2012
*nat
:PREROUTING ACCEPT [18:792]
:POSTROUTING ACCEPT [42:2660]
:OUTPUT ACCEPT [42:2660]
COMMIT
# Completed on Fri Jul 13 08:09:04 2012
# Generated by iptables-save v1.4.8 on Fri Jul 13 08:09:04 2012
*raw
:PREROUTING ACCEPT [15854:814892]
:OUTPUT ACCEPT [12855:3682054]
-A PREROUTING -p tcp -m tcp --dport 80 -j TRACE
-A OUTPUT -p tcp -m tcp --sport 80 -j TRACE
COMMIT
# Completed on Fri Jul 13 08:09:04 2012
# Generated by iptables-save v1.4.8 on Fri Jul 13 08:09:04 2012
*filter
:INPUT ACCEPT [35107:2459066]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [26433:10670628]
COMMIT
# Completed on Fri Jul 13 08:09:04 2012
The iptables-save fiels are as follows:
Field Description
(1) Table name
(2) Chain name
(3) Chain policy
(4) Packet counter
(5) Byte counter
3. I set up nc to listen on port 80:
nc -l 80
4. I sent a string to vm1 using nc:
echo 'Hello, world!' | nc localhost 80
The following exchange between my home pc and vm1 happaned:
08:00:05.655339 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [S], seq 4164179969, win 65535, options
[mss 1460], length 0
08:00:05.655653 IP 10.0.2.15.80 > 10.0.2.2.51534: Flags [S.], seq 4149908960, ack 4164179970,
win 5840, options [mss 1460], length 0
08:00:05.655773 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [.], ack 1, win 65535, length 0
08:00:05.655868 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [P.], seq 1:15, ack 1, win 65535, length 14
08:00:05.655978 IP 10.0.2.15.80 > 10.0.2.2.51534: Flags [.], ack 15, win 5840, length 0
08:00:10.037978 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [F.], seq 15, ack 1, win 65535, length 0
08:00:10.038287 IP 10.0.2.15.80 > 10.0.2.2.51534: Flags [F.], seq 1, ack 16, win 5840, length 0
08:00:10.038993 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [.], ack 2, win 65535, length 0
Let us remember how data is transfered. To do this, let us take apart first packet:
#
(13) (15) (14)
(16)
(20) (17)
(25)
08:00:05.655339 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [S], seq 4164179969, win 65535,
#
(8)
(9)
options [mss 1460], length 0
104
#
#
#
#
#
#
#
#
(1) (2) (3) (4)
(5)
____ ____ ____ ___________________ ____
0x0000: 0000 0001 0006 5254 0012 3502 0000 0800 ......RT..5.....
(6) (7) (8) (9)(10,11)(12) (13)
____ ____ ____ ____ /\/\ ____ _________
0x0010: 4500 002c a006 0000 4006 c2b5 0a00 0202 E..,....@.......
(14)
(15) (16) (17)
(18)
_________ ____ ____ _________ __________
0x0020: 0a00 020f c94e 0050 f834 5801 0000 0000 .....N.P.4X.....
(19,20)(21) (22) (23) (24) (25)
/\/\ ____ ____ ____ ____ ____
0x0030: 6002 ffff 6641 0000 0204 05b4 0000
`...fA........
`
Field and descriptions in our packet:
DOD
OSI model
model
Field in
layer
layer
Link
Physical/Data LINUX_SLL
link
header
Field Description
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
Internet
Network
IPv4 header
(9)
(10)
(11)
(12)
(13)
(14)
(15)
(16)
(17)
(18)
Transport
Transport
TCP header
(19)
(20)
(21)
(22)
(23)
(24)
105
Packet type.
ARPHRD_ type.
Link-layer (MAC) address length.
Linkk-layer (MAC) source address.
Protocol type (IP).
Version, Internet Header Length,
Differentiated Services Code Point,
Explicit Congestion Notification.
Total Length.
Identification, is primarily used for
uniquely identifying fragments of an
original IP datagram.
Flags, Fragment offset.
Time to live (TTL).
Protocol number.
Header checksum.
Source IP address.
Destination IP address.
Source TCP port.
Destination TCP port.
TCP initial sequence number.
ACK number field (empty because it
is first packet).
SYN TCP flag.
TCP window size.
TCP checksum.
Urgent pointer.
Options field start
TCP maximum segment size
(maximum transfer unit - 40 bytes).
And now let us see what happens to this packet in iptables:
(25)
#(1)(2)
(3) (4) (5) (6) (7) (8)
(9)
(10) (11)
(12)
raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
#
(13) (14) (15)
(16) (17) (18)
(19)
(20)
LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534
DPT=80
#
(21)
(22) (23)
(24) (25)(26) (27)
SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT
(020405B4)
mangle:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT
(020405B4)
nat:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT
(020405B4)
mangle:INPUT:policy:1
IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT
(020405B4)
filter:INPUT:policy:1
IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT
(020405B4)
Fields and descrptions of iptables log:
Field Description
(1) Table name.
(2) Chain name.
(3) Type (policy for the policy of the built in chains.
(4) Rule number.
(5) Intput interface.
(6) Output interface (empty, because packet is destinied for vm1 itself)
(7) MAC addresses
(8) Destination (vm1) MAC
(9) Source MAC
(10) Protocol type IP.
(11) Source IP address
(12) Destination IP address
(13) IP packet length in bytes (excluding Link Layer header)
(14) IP type of Service.
106
(15) IP precedence.
(16) IP time to live.
(17) IP packet ID.
(18) Protocol type TCP.
(19) TCP source port.
(20) TCP destination port.
(21) TCP sequence number.
(22) TCP acknoledgement number.
(23) TCP window size.
(24) TCP reserved bits.
(25) TCP SYN flag is set.
(25) TCP urgent pointer is not set.
(25) TCP options.
Now I will show you this exchange side-by-side (more like paragraph by paragraph)
using tcpdump output and iptables log. You task will be to go through this exchange
line by line and understand what happens. I recommend you to print this exchange
and work through it using pen and paper, you can print it from special page. The
questions you need to answer are this:
What does each field mean? Take a pencil and connect field from tcpdump trace to
raw packet data in hex to iptables log.
In what order packets are processed? Which table first, which last, why?
Why only first packet is processed through nat table?
This is the output, behold:
08:00:05.655339 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [S], seq 4164179969, win 65535, options
[mss 1460], length 0
0x0000: 0000 0001 0006 5254 0012 3502 0000 0800 ......RT..5.....
0x0010: 4500 002c a006 0000 4006 c2b5 0a00 0202 E..,....@.......
0x0020: 0a00 020f c94e 0050 f834 5801 0000 0000 .....N.P.4X.....
0x0030: 6002 ffff 6641 0000 0204 05b4 0000
`...fA........
`
raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT
(020405B4)
mangle:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT
(020405B4)
nat:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT
(020405B4)
mangle:INPUT:policy:1
IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534
DPT=80
107
SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT
(020405B4)
filter:INPUT:policy:1
IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=40966 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179969 ACK=0 WINDOW=65535 RES=0x00 SYN URGP=0 OPT
(020405B4)
08:00:05.655653 IP 10.0.2.15.80 > 10.0.2.2.51534: Flags [S.], seq 4149908960, ack 4164179970,
win 5840, options [mss 1460], length 0
0x0000: 0004 0001 0006 0800 27d4 4568 0000 0800 ........'.Eh....
0x0010: 4500 002c 0000 4000 4006 22bc 0a00 020f E..,..@.@.".....
0x0020: 0a00 0202 0050 c94e f75a 95e0 f834 5802 .....P.N.Z...4X.
0x0030: 6012 16d0 c224 0000 0204 05b4
`....$......
'
raw:OUTPUT:policy:2
IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2
LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80
DPT=51534
SEQ=4149908960 ACK=4164179970 WINDOW=5840 RES=0x00 ACK SYN
URGP=0 OPT (020405B4) UID=0 GID=0
mangle:OUTPUT:policy:1
IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2
LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80
DPT=51534
SEQ=4149908960 ACK=4164179970 WINDOW=5840 RES=0x00 ACK SYN
URGP=0 OPT (020405B4) UID=0 GID=0
filter:OUTPUT:policy:1
IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2
LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80
DPT=51534
SEQ=4149908960 ACK=4164179970 WINDOW=5840 RES=0x00 ACK SYN
URGP=0 OPT (020405B4) UID=0 GID=0
mangle:POSTROUTING:policy:1 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2
LEN=44 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80
DPT=51534
SEQ=4149908960 ACK=4164179970 WINDOW=5840 RES=0x00 ACK SYN
URGP=0 OPT (020405B4) UID=0 GID=0
08:00:05.655773 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [.], ack 1, win 65535, length 0
0x0000: 0000 0001 0006 5254 0012 3502 0000 0800 ......RT..5.....
0x0010: 4500 0028 a007 0000 4006 c2b8 0a00 0202 E..(....@.......
0x0020: 0a00 020f c94e 0050 f834 5802 f75a 95e1 .....N.P.4X..Z..
0x0030: 5010 ffff f0b1 0000 0000 0000 0000
P.............
raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40967 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK URGP=0
mangle:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40967 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK URGP=0
mangle:INPUT:policy:1
IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40967 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK URGP=0
filter:INPUT:policy:1
IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
108
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40967 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK URGP=0
08:00:05.655868 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [P.], seq 1:15, ack 1, win 65535, length 14
0x0000: 0000 0001 0006 5254 0012 3502 0000 0800 ......RT..5.....
0x0010: 4500 0036 a008 0000 4006 c2a9 0a00 0202 E..6....@.......
0x0020: 0a00 020f c94e 0050 f834 5802 f75a 95e1 .....N.P.4X..Z..
0x0030: 5018 ffff af45 0000 4865 6c6c 6f2c 2077 P....E..Hello,.w
0x0040: 6f72 6c64 210a
orld!.
raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=54 TOS=0x00 PREC=0x00 TTL=64 ID=40968 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK PSH
URGP=0
mangle:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=54 TOS=0x00 PREC=0x00 TTL=64 ID=40968 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK PSH
URGP=0
mangle:INPUT:policy:1
IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=54 TOS=0x00 PREC=0x00 TTL=64 ID=40968 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK PSH
URGP=0
filter:INPUT:policy:1
IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=54 TOS=0x00 PREC=0x00 TTL=64 ID=40968 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179970 ACK=4149908961 WINDOW=65535 RES=0x00 ACK PSH
URGP=0
08:00:05.655978 IP 10.0.2.15.80 > 10.0.2.2.51534: Flags [.], ack 15, win 5840, length 0
0x0000: 0004 0001 0006 0800 27d4 4568 0000 0800 ........'.Eh....
0x0010: 4500 0028 377c 4000 4006 eb43 0a00 020f E..(7|@.@..C....
0x0020: 0a00 0202 0050 c94e f75a 95e1 f834 5810 .....P.N.Z...4X.
0x0030: 5010 16d0 d9d3 0000
P.......
'
raw:OUTPUT:policy:2
IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14204 DF PROTO=TCP SPT=80
DPT=51534
SEQ=4149908961 ACK=4164179984 WINDOW=5840 RES=0x00 ACK URGP=0
mangle:OUTPUT:policy:1
IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14204 DF PROTO=TCP SPT=80
DPT=51534
SEQ=4149908961 ACK=4164179984 WINDOW=5840 RES=0x00 ACK URGP=0
filter:OUTPUT:policy:1
IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14204 DF PROTO=TCP SPT=80
DPT=51534
SEQ=4149908961 ACK=4164179984 WINDOW=5840 RES=0x00 ACK URGP=0
mangle:POSTROUTING:policy:1 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14204 DF PROTO=TCP SPT=80
DPT=51534
SEQ=4149908961 ACK=4164179984 WINDOW=5840 RES=0x00 ACK URGP=0
08:00:10.037978 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [F.], seq 15, ack 1, win 65535, length 0
109
0x0000:
0x0010:
0x0020:
0x0030:
0000 0001 0006 5254 0012 3502 0000 0800 ......RT..5.....
4500 0028 a00e 0000 4006 c2b1 0a00 0202 E..(....@.......
0a00 020f c94e 0050 f834 5810 f75a 95e1 .....N.P.4X..Z..
5011 ffff f0a2 0000 0000 0000 0000
P.............
raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40974 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179984 ACK=4149908961 WINDOW=65535 RES=0x00 ACK FIN
URGP=0
mangle:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40974 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179984 ACK=4149908961 WINDOW=65535 RES=0x00 ACK FIN
URGP=0
mangle:INPUT:policy:1
IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40974 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179984 ACK=4149908961 WINDOW=65535 RES=0x00 ACK FIN
URGP=0
filter:INPUT:policy:1
IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40974 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179984 ACK=4149908961 WINDOW=65535 RES=0x00 ACK FIN
URGP=0
08:00:10.038287 IP 10.0.2.15.80 > 10.0.2.2.51534: Flags [F.], seq 1, ack 16, win 5840, length 0
0x0000: 0004 0001 0006 0800 27d4 4568 0000 0800 ........'.Eh....
0x0010: 4500 0028 377d 4000 4006 eb42 0a00 020f E..(7}@.@..B....
0x0020: 0a00 0202 0050 c94e f75a 95e1 f834 5811 .....P.N.Z...4X.
0x0030: 5011 16d0 d9d1 0000
P.......
'
raw:OUTPUT:policy:2
IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14205 DF PROTO=TCP SPT=80
DPT=51534
SEQ=4149908961 ACK=4164179985 WINDOW=5840 RES=0x00 ACK FIN
URGP=0 UID=0 GID=0
mangle:OUTPUT:policy:1
IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14205 DF PROTO=TCP SPT=80
DPT=51534
SEQ=4149908961 ACK=4164179985 WINDOW=5840 RES=0x00 ACK FIN
URGP=0 UID=0 GID=0
filter:OUTPUT:policy:1
IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14205 DF PROTO=TCP SPT=80
DPT=51534
SEQ=4149908961 ACK=4164179985 WINDOW=5840 RES=0x00 ACK FIN
URGP=0 UID=0 GID=0
mangle:POSTROUTING:policy:1 IN= OUT=eth0 SRC=10.0.2.15 DST=10.0.2.2
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=14205 DF PROTO=TCP SPT=80
DPT=51534
SEQ=4149908961 ACK=4164179985 WINDOW=5840 RES=0x00 ACK FIN
URGP=0 UID=0 GID=0
08:00:10.038993 IP 10.0.2.2.51534 > 10.0.2.15.80: Flags [.], ack 2, win 65535, length 0
0x0000: 0000 0001 0006 5254 0012 3502 0000 0800 ......RT..5.....
0x0010: 4500 0028 a00f 0000 4006 c2b0 0a00 0202 E..(....@.......
110
0x0020: 0a00 020f c94e 0050 f834 5811 f75a 95e2 .....N.P.4X..Z..
0x0030: 5010 ffff f0a1 0000 0000 0000 0000
P.............
raw:PREROUTING:policy:2 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40975 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179985 ACK=4149908962 WINDOW=65535 RES=0x00 ACK URGP=0
mangle:PREROUTING:policy:1 IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40975 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179985 ACK=4149908962 WINDOW=65535 RES=0x00 ACK URGP=0
mangle:INPUT:policy:1
IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40975 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179985 ACK=4149908962 WINDOW=65535 RES=0x00 ACK URGP=0
filter:INPUT:policy:1
IN=eth0 OUT= MAC=08:00:27:d4:45:68:52:54:00:12:35:02:08:00
SRC=10.0.2.2 DST=10.0.2.15
LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=40975 PROTO=TCP SPT=51534
DPT=80
SEQ=4164179985 ACK=4149908962 WINDOW=65535 RES=0x00 ACK URGP=0
Now you will learn how to set up basic iptables rules and enable iptables logging.
Do this
1: sudo iptables-save
2: sudo iptables -t filter -A INPUT -i lo -j ACCEPT
3: sudo iptables -t filter -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
4: sudo iptables -t filter -P INPUT DROP
5: sudo iptables -nt filter -L --line-numbers
6: ping -c 2 -W 1 10.0.2.2
7: sudo iptables -t filter -A INPUT --match state --state ESTABLISHED -j ACCEPT
8: sudo iptables -nt filter -L --line-numbers
9: ping -c 2 -W 1 10.0.2.2
10: sudo modprobe ipt_LOG
11: sudo iptables -nt raw -L --line-numbers
12: sudo iptables -t raw -A PREROUTING -p udp -m udp --dport 1024 -j TRACE
13: sudo iptables -t raw -A OUTPUT -p udp -m udp --sport 1024 -j TRACE
14: sudo tail -n0 -f /var/log/kern.log | cut -c52-300 &
15: nc -ulp 1024 &
16: echo 'Hello there!' | nc -u localhost 1000
17: <CTRL+C>
18: fg
19: <CTRL+C>
20: fg
21: <CTRL+C>
What you should see
student@vm1:~$ sudo iptables-save
# Generated by iptables-save v1.4.8 on Mon Jul 16 09:01:32 2012
*mangle
:PREROUTING ACCEPT [45783:3411367]
:INPUT ACCEPT [45783:3411367]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [30409:9552110]
:POSTROUTING ACCEPT [30331:9543294]
111
COMMIT
# Completed on Mon Jul 16 09:01:32 2012
# Generated by iptables-save v1.4.8 on Mon Jul 16 09:01:32 2012
*nat
:PREROUTING ACCEPT [24:1056]
:POSTROUTING ACCEPT [755:41247]
:OUTPUT ACCEPT [817:45207]
COMMIT
# Completed on Mon Jul 16 09:01:32 2012
# Generated by iptables-save v1.4.8 on Mon Jul 16 09:01:32 2012
*raw
:PREROUTING ACCEPT [3171:197900]
:OUTPUT ACCEPT [1991:1294054]
-A PREROUTING -p udp -m udp --dport 80 -j TRACE
-A OUTPUT -p udp -m udp --sport 80 -j TRACE
COMMIT
# Completed on Mon Jul 16 09:01:32 2012
# Generated by iptables-save v1.4.8 on Mon Jul 16 09:01:32 2012
*filter
:INPUT ACCEPT [54:3564]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [28:2540]
COMMIT
# Completed on Mon Jul 16 09:01:32 2012
student@vm1:~$ sudo iptables -t filter -A INPUT -i lo -j ACCEPT
student@vm1:~$ sudo iptables -t filter -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
student@vm1:~$ sudo iptables -t filter -P INPUT DROP
student@vm1:~$ sudo iptables -nt filter -L --line-numbers
Chain INPUT (policy DROP)
num target prot opt source
destination
1 ACCEPT all -- 0.0.0.0/0
0.0.0.0/0
2 ACCEPT tcp -- 0.0.0.0/0
0.0.0.0/0
tcp dpt:22
Chain FORWARD (policy ACCEPT)
num target prot opt source
destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source
destination
student@vm1:~$ ping -c 2 -W 1 10.0.2.2
PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data.
--- 10.0.2.2 ping statistics --2 packets transmitted, 0 received, 100% packet loss, time 1008ms
student@vm1:~$ sudo iptables -t filter -A INPUT --match state --state ESTABLISHED -j ACCEPT
student@vm1:~$ sudo iptables -nt filter -L --line-numbers
Chain INPUT (policy DROP)
num target prot opt source
destination
1 ACCEPT all -- 0.0.0.0/0
0.0.0.0/0
2 ACCEPT tcp -- 0.0.0.0/0
0.0.0.0/0
tcp dpt:22
3 ACCEPT all -- 0.0.0.0/0
0.0.0.0/0
state ESTABLISHED
Chain FORWARD (policy ACCEPT)
num target prot opt source
destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source
destination
student@vm1:~$ ping -c 2 -W 1 10.0.2.2
112
PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data.
64 bytes from 10.0.2.2: icmp_req=1 ttl=63 time=0.385 ms
64 bytes from 10.0.2.2: icmp_req=2 ttl=63 time=0.142 ms
--- 10.0.2.2 ping statistics --2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.142/0.263/0.385/0.122 ms
student@vm1:~$ sudo iptables -nt raw -L --line-numbers
Chain PREROUTING (policy ACCEPT)
num target prot opt source
destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source
destination
student@vm1:~$ sudo iptables -t raw -A PREROUTING -p udp -m udp --dport 1024 -j TRACE
student@vm1:~$ sudo iptables -t raw -A OUTPUT -p udp -m udp --sport 1024 -j TRACE
student@vm1:~$ sudo iptables -nt raw -L --line-numbers
Chain PREROUTING (policy ACCEPT)
num target prot opt source
destination
1 TRACE
udp -- 0.0.0.0/0
0.0.0.0/0
udp dpt:1024
Chain OUTPUT (policy ACCEPT)
num target prot opt source
destination
1 TRACE
udp -- 0.0.0.0/0
0.0.0.0/0
udp spt:1024
student@vm1:~$ sudo tail -n0 -f /var/log/kern.log | cut -c52-300 &
[1] 10249
student@vm1:~$ nc -ulp 1024 &
[2] 10251
student@vm1:~$ echo 'Hello there!' | nc -u localhost 1024
Hello there!
raw:PREROUTING:policy:2 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00
SRC=127.0.0.1 DST=127.0.0.1 LEN=41 TOS=0x00 PREC=0x00 TTL=64 ID=57898 DF
PROTO=UDP SPT=50407 DPT=1024 LEN=21
mangle:PREROUTING:policy:1 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00
SRC=127.0.0.1 DST=127.0.0.1 LEN=41 TOS=0x00 PREC=0x00 TTL=64 ID=57898 DF
PROTO=UDP SPT=50407 DPT=1024 LEN=21
mangle:INPUT:policy:1 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00
SRC=127.0.0.1 DST=127.0.0.1 LEN=41 TOS=0x00 PREC=0x00 TTL=64 ID=57898 DF
PROTO=UDP SPT=50407 DPT=1024 LEN=21
filter:INPUT:rule:1 IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1
DST=127.0.0.1 LEN=41 TOS=0x00 PREC=0x00 TTL=64 ID=57898 DF PROTO=UDP SPT=50407
DPT=1024 LEN=21
^C
[2]+ Stopped
nc -ulp 1024
student@vm1:~$ fg
nc -ulp 1024
^C
student@vm1:~$ fg
sudo tail -n0 -f /var/log/kern.log | cut -c52-300
^C
student@vm1:~$
Explanation
Prints out all iptables rules from all tables. You can see that there are none.
Allows all incoming traffic on lo (loopback) interface.
Allows all incoming traffic to TCP port 22, which is ssh.
Changes default INPUT policy to DROP, forbidding all incoming connections except
explicitly allowed to TCP port 22. If you loss connection to vm1 here, it means you
did something wrong, reboot it in VirtualBox and try again.
113
Lists current filter rules. Note: you can delete rules by number, like this: sudo
iptables -t filter -D INPUT 2. Notice how policy is totally not the same as rule.
Tries to ping your default gateway, failing to do this. Why it is so if outgoing
connections are allowed (Chain OUTPUT (policy ACCEPT))? Well, outgoing
packets are being sent to gateway, but reply from gateway is not able to get in.
Adds a rule telling iptables to allow all packets which belong to already established
connections, for example to all connections originating from vm1.
Lists current filter rules. You are able to see our new rule.
Pings vm1 default gateway, this time successfully.
Loads Linux kernel module which allows to use packet filter logging facility.
Adds rule to log all incoming packets which are destined to UDP port 1024 of any
interface of vm1.
Adds rule to log all outgoing packets which originate from UDP port 1024 of any
interface of vm1.
Lists raw table rules.
Starts tail in the background which will print all new lines written to
/var/log/kern.log. cut will remove unnecessary prefix of log entries in the beginning.
Notice how background process is able to write to your terminal.
Starts nc in server mode, listening on UDP port 1024 on all interfaces of vm1.
Starts nc in client mode, sending string Hello there! to our server mode nc. tail
prints out all new lines in kern.log and you are able to see how our single UDP
packet goes from table to table inside of Linux kernel packet filter. There is no reply,
so only one single packet is being sent and processed.
Kills client mode nc.
Brings server mode nc to foreground.
Kills server mode nc.
Bring sudo tail -n0 -f /var/log/kern.log | cut -c52-300 & to foreground.
Kills it.
Extra credit
This was big by itself. Just print out this log and work through it using pencil until you
really understand what is going on in every field of every line. If you will stuck, ask
away here. http://nixsrv.com/llthw/ex26/log
Exercise 27. Networking: secure shell,
ssh, sshd, scp
You may already know that SSH is a network protocol which allows you to login into
vm1 over the network. Let us look into in in some detail.
Secure Shell (SSH) is a network protocol for secure data communication, remote
shell services or command execution and other secure network services between
two networked computers that it connects via a secure channel over an insecure
network: a server and a client (running SSH server and SSH client programs,
respectively). The protocol specification distinguishes two major versions that are
referred to as SSH-1 and SSH-2.
The best-known application of the protocol is for access to shell accounts on Unixlike operating systems. It was designed as a replacement for Telnet and other
insecure remote shell protocols such as the Berkeley rsh and rexec protocols, which
114
send information, notably passwords, in plaintext, rendering them susceptible to
interception and disclosure using packet analysis. The encryption used by SSH is
intended to provide confidentiality and integrity of data over an unsecured network,
such as the Internet.
The important SSH programs, concepts and configuration files:
OpenSSH — open source ssh programs implementation.
ssh — the client program which allows you to connect to ssh server. Putty is such
client program for example.
sshd — the server program which allows you to connect to it with ssh.
/etc/ssh/ssh_config — default client program configuration file.
/etc/ssh/sshd_config — default server program configuration file.
Public-key cryptography — a cryptographic system requiring two separate keys,
one of which is secret and one of which is public. Although different, the two parts of
the key pair are mathematically linked. One key locks or encrypts the plaintext, and
the other unlocks or decrypts the cyphertext. Neither key can perform both functions.
One of these keys is published or public and the other is kept private.
SSH keys — SSH uses public-key cryptography to authenticate the remote
computer and allow it to authenticate the user, if necessary. Anyone can produce a
matching pair of different key—s (public and private). The public key is placed on all
computers that must allow access to the owner of the matching private key (the
owner keeps the private key secret). While authentication is based on the private
key, the key itself is never transferred through the network during authentication.
/etc/ssh/moduli — prime numbers and generators for use by sshd(8) in the DiffieHellman Group Exchange key exchange method.
/etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_rsa_key — private host RSA and
DSA keys.
/etc/ssh/ssh_host_dsa_key.pub, /etc/ssh/ssh_host_rsa_key.pub — public host
RSA and DSA keys.
SSH protocol is so important, so widely used and has so many capabilities, that
some understanding of its workings is mandatory. This is some of its uses:
scp — file transfer over ssh.
sftp — ftp-like protocol for managing remote files.
sshfs — remote filesystem mounting over ssh.
ssh tunnelling — a method to transfer almost any data over secure connection.
This is so important because it can be used as a foundation for construction of
protected systems, among many its other uses.
To get some understanding of this protocol let us see what happens during ssh
session. To this we will start with examining the annotated output of connecting from
vm1 to vm1 (yes, it can be done, and it is perfectly valid to do). The outline:
YOU
Type ssh vm1
Control is now passed to SSH client
SSH client
Enters plaintext phase
Reads configuration
Negotiats protocol with SSH server
Enters SSH-transport phase
Negotiates with SSH server
Data encryption chiphers
Data integrity algorithms
Data compression algorithms
Start key exchange using Diffie-Hellman algorithm
115
Resulting shared key is used to establish secured connection
Enters SSH-userauth phase
Asks you to enter password
Control is now passed to you
YOU
Enter you password
Control is now passed to SSH client
SSH client
Authenticates you on SSH server
Enters SSH-connection phase
Allocates pseudo teminal for YOU
Starts a shell for YOU
Control is now passed to YOU
YOU
Do something u(n)useful on vm1
Close shell
Control is now passed to ssh client
SSH client
Closes pseudo terminal
Closes connection
Now read this:
The OpenSSH Protocol under the Hood.
http://www.cs.ust.hk/faculty/cding/COMP581/SLIDES/slide24.pdf SSH - Secure
SHell presentation.
And examine the real output of ssh session:
student@vm1:~$ ssh -vv vm1
Protocol version selection, plaintext
------------------------------------OpenSSH_5.5p1 Debian-6+squeeze2, OpenSSL 0.9.8o 01 Jun 2010
# Speaks for itself, I will mark such entries with -- below
debug1: Reading configuration data /etc/ssh/ssh_config
# Applying default options for all hosts. Additional options for each host may be
# specified in the configuration file
debug1: Applying options for *
debug2: ssh_connect: needpriv 0
debug1: Connecting to vm1 [127.0.1.1] port 22.
debug1: Connection established.
debug1: identity file /home/student/.ssh/id_rsa type -1
# no such files
debug1: identity file /home/student/.ssh/id_rsa-cert type -1
debug1: identity file /home/student/.ssh/id_dsa type -1
debug1: identity file /home/student/.ssh/id_dsa-cert type -1
debug1: Remote protocol version 2.0, remote software version OpenSSH_5.5p1 Debian-6+squeeze2
debug1: match: OpenSSH_5.5p1 Debian-6+squeeze2 pat OpenSSH*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_5.5p1 Debian-6+squeeze2
debug2: fd 3 setting O_NONBLOCK
SSH-transport, binary packet protocol
------------------------------------debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
# Key exchange algorithms
debug2: kex_parse_kexinit: diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchangesha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
# SSH host key types
116
debug2: kex_parse_kexinit: ssh-rsa-cert-v00@openssh.com,ssh-dss-cert-v00@openssh.com,sshrsa,ssh-dss
# Data encryption ciphers
debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se
debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se
# Data integrity algorithms
debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmacripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmacripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
# Data compression algorithms
debug2: kex_parse_kexinit: none,zlib@openssh.com,zlib
debug2: kex_parse_kexinit: none,zlib@openssh.com,zlib
debug2: kex_parse_kexinit:
debug2: kex_parse_kexinit:
debug2: kex_parse_kexinit: first_kex_follows
debug2: kex_parse_kexinit: reserved 0
# Messages back from server
debug2: kex_parse_kexinit: diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchangesha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
debug2: kex_parse_kexinit: ssh-rsa,ssh-dss
debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se
debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se
debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmacripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmacripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: kex_parse_kexinit: none,zlib@openssh.com
debug2: kex_parse_kexinit: none,zlib@openssh.com
debug2: kex_parse_kexinit:
debug2: kex_parse_kexinit:
debug2: kex_parse_kexinit: first_kex_follows 0
debug2: kex_parse_kexinit: reserved 0
# Message authentication code setup
debug2: mac_setup: found hmac-md5
debug1: kex: server->client aes128-ctr hmac-md5 none
debug2: mac_setup: found hmac-md5
debug1: kex: client->server aes128-ctr hmac-md5 none
# Key exchange
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug2: dh_gen_key: priv key bits set: 135/256
debug2: bits set: 498/1024
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
# Server authentication. vm1 host key is not known because it is our first connection
debug2: no key of type 0 for host vm1
debug2: no key of type 2 for host vm1
# Confirmation of host key acceptance
The authenticity of host 'vm1 '(127.0.1.1)' can't be established.
RSA key fingerprint is b6:06:92:5e:04:49:d9:e8:57:90:61:1b:16:87:bb:09.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'vm1' (RSA) to the list of known hosts.
# Key is added to /home/student/.ssh/known_hosts and checked
debug2: bits set: 499/1024
117
debug1: ssh_rsa_verify: signature correct
# Based on shared master key, data encryption key and data integrity key are derived
debug2: kex_derive_keys
debug2: set_newkeys: mode 1
# Information about this is sent to server
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug2: set_newkeys: mode 0
debug1: SSH2_MSG_NEWKEYS received
# IP roaming not enabled? Not sure about this.
debug1: Roaming not allowed by server
SSH-userauth
-----------debug1: SSH2_MSG_SERVICE_REQUEST sent
debug2: service_accept: ssh-userauth
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug2: key: /home/student/.ssh/id_rsa ((nil))
debug2: key: /home/student/.ssh/id_dsa ((nil))
debug1: Authentications that can continue: publickey,password
debug1: Next authentication method: publickey
debug1: Trying private key: /home/student/.ssh/id_rsa
debug1: Trying private key: /home/student/.ssh/id_dsa
debug2: we did not send a packet, disable method
debug1: Next authentication method: password
student@vm1''s password:
debug2: we sent a password packet, wait for reply
debug1: Authentication succeeded (password).
SSH-connection
-------------debug1: channel 0: new [client-session]
debug2: channel 0: send open
# Disable SSH mutiplexing.
# More info: http://www.linuxjournal.com/content/speed-multiple-ssh-connections-same-server
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug2: callback start
debug2: client_session2_setup: id 0
debug2: channel 0: request pty-req confirm 1
# Sending environment variables
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug2: channel 0: request env confirm 0
debug2: channel 0: request shell confirm 1
# Set TCP_NODELAY flag: http://en.wikipedia.org/wiki/Nagle%27s_algorithm
debug2: fd 3 setting TCP_NODELAY
debug2: callback done
# Connection opened
debug2: channel 0: open confirm rwindow 0 rmax 32768
debug2: channel_input_status_confirm: type 99 id 0
# Pseudo terminal allocation
debug2: PTY allocation request accepted on channel 0
debug2: channel 0: rcvd adjust 2097152
debug2: channel_input_status_confirm: type 99 id 0
# Shell is started
debug2: shell request accepted on channel 0
# Loggin in is completed
118
Linux vm1 2.6.32-5-amd64 #1 SMP Sun May 6 04:00:17 UTC 2012 x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
You have mail.
Last login: Thu Jul 19 05:14:40 2012 from 10.0.2.2
student@vm1:~$ debug2: client_check_window_change: changed
debug2: channel 0: request window-change confirm 0
student@vm1:~$ debug2: client_check_window_change: changed
debug2: channel 0: request window-change confirm 0
student@vm1:~$ logout
Ending ssh connection
--------------------debug2: channel 0: rcvd eof # end of file
debug2: channel 0: output open -> drain
debug2: channel 0: obuf empty
debug2: channel 0: close_write
debug2: channel 0: output drain -> closed
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
# signalling that channels are half-closed for writing, through a channel protocol extension
# notification "eow@openssh.com" http://www.openssh.com/txt/release-5.1
debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0
debug2: channel 0: rcvd eow
# Ending connection
debug2: channel 0: close_read
debug2: channel 0: input open -> closed
debug2: channel 0: rcvd close
debug2: channel 0: almost dead
debug2: channel 0: gc: notify user
debug2: channel 0: gc: user detached
debug2: channel 0: send close
debug2: channel 0: is dead
debug2: channel 0: garbage collecting
debug1: channel 0: free: client-session, nchannels 1
Connection to vm1 closed.
Transferred: sent 1928, received 2632 bytes, in 93.2 seconds
Bytes per second: sent 20.7, received 28.2
debug1: Exit status 0
student@vm1:~$
Now you will learn how to start sshd in debug mode, set up public key authentication
and copy files using scp.
Do this
1: mkdir -v ssh_test
2: cd ssh_test
3: cp -v /etc/ssh/sshd_config .
4: sed -i'.bak' 's/^Port 22$/Port 1024/' sshd_config
5: sed -i 's/^HostKey \/etc\/ssh\/ssh_host_rsa_key$/Hostkey
\/home\/student\/ssh_test\/ssh_host_rsa_key/' sshd_config
6: sed -i 's/^HostKey \/etc\/ssh\/ssh_host_dsa_key$/Hostkey
\/home\/student\/ssh_test\/ssh_host_dsa_key/' sshd_config
7: diff sshd_config.bak sshd_config
8: ssh-keygen -b 4096 -t rsa -N '' -v -h -f ssh_host_rsa_key
9: ssh-keygen -b 1024 -t dsa -N '' -v -h -f ssh_host_dsa_key
119
10: ssh-keygen -b 4096 -t rsa -N '' -v -f ~/.ssh/id_rsa
11: cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys
12: /usr/sbin/sshd -Ddf sshd_config > sshd.out 2>&1 &
13: ssh-keyscan -H vm1 127.0.0.1 >> ~/.ssh/known_hosts
14: /usr/sbin/sshd -Ddf sshd_config >> sshd.out 2>&1 &
15: ssh vm1 -v -p 1024 2>ssh.out
16: ps au --forest
17: logout
18: /usr/sbin/sshd -Ddf sshd_config >> sshd.out 2>&1 &
19: scp -v -P 1024 vm1:.bashrc . 2>scp.out
What you should see
student@vm1:~$ mkdir -v ssh_test
mkdir: created directory 'ssh_test'
student@vm1:~$ cd ssh_test
student@vm1:~/ssh_test$ cp -v /etc/ssh/sshd_config .
'/etc/ssh/sshd_config' -> './sshd_config'
student@vm1:~/ssh_test$ sed -i'.bak' 's/^Port 22$/Port 1024/' sshd_config
student@vm1:~/ssh_test$ sed -i 's/^HostKey \/etc\/ssh\/ssh_host_rsa_key$/Hostkey
\/home\/student\/ssh_test\/ssh_host_rsa_key/' sshd_config
student@vm1:~/ssh_test$ sed -i 's/^HostKey \/etc\/ssh\/ssh_host_dsa_key$/Hostkey
\/home\/student\/ssh_test\/ssh_host_dsa_key/' sshd_config
student@vm1:~/ssh_test$ diff sshd_config.bak sshd_config
5c5
< Port 22
--> Port 1024
11,12c11,12
< HostKey /etc/ssh/ssh_host_rsa_key
< HostKey /etc/ssh/ssh_host_dsa_key
--> Hostkey /home/student/ssh_test/ssh_host_rsa_key
> Hostkey /home/student/ssh_test/ssh_host_dsa_key
student@vm1:~/ssh_test$ ssh-keygen -b 4096 -t rsa -N '' -v -h -f ssh_host_rsa_key
Generating public/private rsa key pair.
Your identification has been saved in ssh_host_rsa_key.
Your public key has been saved in ssh_host_rsa_key.pub.
The key fingerprint is:
8c:0a:8d:ae:c7:34:e6:29:9c:c2:14:29:b8:d9:1d:34 student@vm1
'The key's randomart image is:
+--[ RSA 4096]----+
|
|
| E
|
|. .. .
|
|oo o. o
|
|.++.... S
|
|oo=...
|
|+=oo.
|
|o==
|
|oo
|
+-----------------+
student@vm1:~/ssh_test$ ssh-keygen -b 1024 -t dsa -N '' -v -h -f ssh_host_dsa_key
Generating public/private dsa key pair.
Your identification has been saved in ssh_host_dsa_key.
Your public key has been saved in ssh_host_dsa_key.pub.
The key fingerprint is:
cd:6b:2a:a2:ba:80:65:71:85:ef:2e:6a:c0:a7:d9:aa student@vm1
'The key's randomart image is:
120
+--[ DSA 1024]----+
| ..
|
| ..
|
| . ..
|
| o . o
|
|. o . S o
|
|o+ . . . |
|o.= . o
|
|.o..o o o
|
|E=+o o ..
|
+-----------------+
student@vm1:~/ssh_test$ ssh-keygen -b 4096 -t rsa -N '' -v -f ~/.ssh/id_rsa
Generating public/private rsa key pair.
Your identification has been saved in /home/student/.ssh/id_rsa.
Your public key has been saved in /home/student/.ssh/id_rsa.pub.
The key fingerprint is:
50:65:18:61:3f:41:36:07:4f:40:36:a7:4b:6d:64:28 student@vm1
'The key's randomart image is:
+--[ RSA 4096]----+
|
=B&+* |
|
oE=.& |
|
. .= + |
|
..+ |
|
S.
|
|
|
|
|
|
|
|
|
+-----------------+
student@vm1:~/ssh_test$ cat ~/.ssh/id_rsa.pub > ~/.ssh/authorized_keys
student@vm1:~/ssh_test$ /usr/sbin/sshd -Ddf sshd_config > sshd.out 2>&1 &
[2] 26896
student@vm1:~/ssh_test$ ssh-keyscan -H vm1 127.0.0.1 >> ~/.ssh/known_hosts
# 127.0.0.1 SSH-2.0-OpenSSH_5.5p1 Debian-6+squeeze2
# vm1 SSH-2.0-OpenSSH_5.5p1 Debian-6+squeeze2
[2]+ Exit 255
/usr/sbin/sshd -Ddf sshd_config > sshd.out 2>&1
student@vm1:~/ssh_test$ /usr/sbin/sshd -Ddf sshd_config >> sshd.out 2>&1 &
[1] 26957
student@vm1:~/ssh_test$ ssh vm1 -v -p 1024 2>ssh.out
Linux vm1 2.6.32-5-amd64 #1 SMP Sun May 6 04:00:17 UTC 2012 x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
You have mail.
Last login: Fri Jul 20 09:10:30 2012 from vm1.site
Environment:
LANG=en_US.UTF-8
USER=student
LOGNAME=student
HOME=/home/student
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
MAIL=/var/mail/student
SHELL=/bin/bash
SSH_CLIENT=127.0.1.1 47456 1024
SSH_CONNECTION=127.0.1.1 47456 127.0.1.1 1024
SSH_TTY=/dev/pts/0
121
TERM=xterm
student@vm1:~$ ps au --forest
USER
PID %CPU %MEM VSZ RSS TTY
STAT START TIME COMMAND
student 26224 0.0 1.2 23660 6576 pts/2 Ss 09:09 0:01 -bash
student 27020 1.0 0.6 68392 3236 pts/2 S 09:50 0:00 \_ sshd: student [priv]
student 27025 0.0 0.2 68392 1412 pts/2 S 09:50 0:00 | \_ sshd: student@pts/0
student 27026 9.0 1.2 23564 6404 pts/0 Ss 09:50 0:00 |
\_ -bash
student 27051 0.0 0.2 16308 1060 pts/0 R+ 09:50 0:00 |
\_ ps au --forest
student 27021 1.1 0.5 38504 2880 pts/2 S+ 09:50 0:00 \_ ssh vm1 -v -p 1024
root
1107 0.0 0.1 5932 620 tty6 Ss+ Jul18 0:00 /sbin/getty 38400 tty6
root
1106 0.0 0.1 5932 616 tty5 Ss+ Jul18 0:00 /sbin/getty 38400 tty5
root
1105 0.0 0.1 5932 620 tty4 Ss+ Jul18 0:00 /sbin/getty 38400 tty4
root
1104 0.0 0.1 5932 620 tty3 Ss+ Jul18 0:00 /sbin/getty 38400 tty3
root
1103 0.0 0.1 5932 616 tty2 Ss+ Jul18 0:00 /sbin/getty 38400 tty2
root
1102 0.0 0.1 5932 616 tty1 Ss+ Jul18 0:00 /sbin/getty 38400 tty1
student@vm1:~$ logout
student@vm1:~/ssh_test$
[1]+ Exit 255
/usr/sbin/sshd -Ddf sshd_config > sshd.out 2>&1
student@vm1:~/ssh_test$ /usr/sbin/sshd -Ddf sshd_config >> sshd.out 2>&1 &
[1] 27067
student@vm1:~/ssh_test$ scp -v -P 1024 vm1:.bashrc . 2>scp.out
Environment:
LANG=en_US.UTF-8
USER=student
LOGNAME=student
HOME=/home/student
PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games
MAIL=/var/mail/student
SHELL=/bin/bash
SSH_CLIENT=127.0.1.1 47459 1024
SSH_CONNECTION=127.0.1.1 47459 127.0.1.1 1024
.bashrc
100% 3184
3.1KB/s 00:00
[1]+ Exit 255
/usr/sbin/sshd -Ddf sshd_config >> sshd.out 2>&1
Explanation
Creates /home/student/ssh_test directory.
Make it current working directory.
Copies sshd_config to this directory.
Changes sshd listen port from 22 to 1024, making copy named sshd_config.bak in
the process.
Replaces RSA host key localtion.
Replaces DSA host key localtion.
Shows difference between old and new versions of sshd_config.
Generates new 4096-bit RSA host key pair with empty pass-phrase, saving it to
/home/student/ssh_test/ssh_host_rsa_key and
/home/student/ssh_test/ssh_host_rsa_key.pub.
The same, but for DSA key.
Generates new authentication key pair, saving it to /home/student/.ssh/id_rsa and
/home/student/.ssh/id_rsa.pub.
Copies id_rsa.pub to /home/student/.ssh/authorized_keys to allow passwordless
authentication.
Starts new SSH server on port 1024 in debug mode, saving all output to sshd.log.
Extracts host authentication key for SSH client and puts it to
/home/student/.ssh/known_hosts.
122
Starts new SSH server on port 1024 in debug mode, appending all output to
sshd.log. This is because in debug mode SSH server servers only only one
connection.
Connects to this server using ssh client.
Prints out current running processes in tree format. You are able to see that you are
working in shell bash started by sshd serving your connection which in turn is
started by sshd you started yourself several lines before.
Logs out from ssh session.
Starts SSH server once more.
Copies file .bashrc from your home directory to your current directory.
Extra credit
Watch this videos explaining how encryption works:
http://www.youtube.com/watch?v=3QnD2c4Xovk
Read this: http://docstore.mik.ua/orelly/networking_2ndEd/ssh/ch03_04.htm
Read debug output found in files ssh.out, scp.out and sshd.out. Explain to yourself
what is going on.
Exercise 28. Performance: getting
performance stats, uptime, free, top
This exercise is pretty simple. First, what kind of performance stats do we need?
CPU usage stats:
How much is it loaded?
Which processes are using it?
Memory usage stats:
How much memory is used?
How much memory is free?
How much memory is used for caching?
Which processes consume it?
Disk usage stats:
How many input/output operations are performed?
By which processes?
Network usage stats:
How many data is transferred?
By which processes?
Process stats:
How many processes there are?
What they are doing? Working, waiting for something?
If waiting for something what is it? CPU, disks, network?
To get this stats we can use the following utilities:
uptime — how long the system has been running.
free — display amount of free and used memory in the system.
vmstat — information about processes, memory, paging, block IO, traps, disks and
cpu activity.
top — display Linux tasks in real-time.
Let us examine this programs and their output.
uptime output:
123
student@vm1:~$ uptime
#(1)
(2)
(3)
(4) (5) (6)
03:13:58 up 4 days, 22:45, 1 user, load average: 0.00, 0.00, 0.00
Fields and descriptions:
Field Description
(1) Current time.
(2) Uptime (time passed since boot).
(3) How many users are currently logged in.
CPU load in past 1 minute. This is not normalized, so a load average of 1
(4) means a single CPU system is loaded all the time while on a 4 CPU system it
means it was idle 75% of the time.
(5) CPU load in past 5 minutes.
(6) CPU load in past 15 minutes.
free output:
student@vm1:~$ free -mt
#
(1)
(2)
(3)
(4)
(5)
(6)
total
used
free shared buffers cached
Mem:
496
267
229
0
27
196
#
(7)
(8)
-/+ buffers/cache:
43
453
#9
Swap:
461
0
461
# 10
Total:
958
267
691
Fields and descriptions:
Field Description
(1) Total amount of psysical memory.
(2) Total amount of used physical memory.
(3) Total mount of free physical memory.
(4) Shared memory column should be ignored; it is obsolete.
(5) Total RAM dedicated to cache disk block, and filesystem metadata.
(6) Total RAM dedicated to pages from file reading.
(7) Total amount of physical memory excluding buffers and cache, (2) - (5) - (6)
Total amount of free physical memeory counting buffers and cache as free, (1)
(8)
- (7)
(9) Swap file usage statistics.
(10) Total memory usage statistics, including swap
vmstat output:
student@vm1:~$ vmstat -S M
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---#(1,2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12,13,14,15,16)
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0
0 229 27 196 0 0 0 0 11 6 0 0 100 0
student@vm1:~$ vmstat -S M -a
#
(17) (18)
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---r b swpd free inact active si so bi bo in cs us sy id wa
0 0
0 11 434 19 0 0 24 2 11 6 0 0 100 0
124
student@vm1:~$ vmstat -d
#19 (20) (21) (22) (23) (24) (25) (26) (27) (28) (29)
disk- ------------reads------------ ------------writes----------- -----IO-----total merged sectors
ms total merged sectors
ms cur sec
sda 11706 353 402980 17612 9303 40546 336358 46980
0
sr0
0
0
0
0
0
0
0
0
0
0
loop0
0
0
0
0
0
0
0
0
0
0
19
student@vm1:~$ vmstat -m | head
#(30)
(31) (32) (33) (34)
Cache
Num Total Size Pages
ext3_inode_cache
13700 13700 808 10
ext3_xattr
0
0 88 46
journal_handle
170 170 24 170
journal_head
37 72 112 36
revoke_table
256 256 16 256
revoke_record
128 128 32 128
kmalloc_dma-512
8
8 512
8
ip6_dst_cache
16 24 320 12
UDPLITEv6
0
0 1024
8
Fields and descriptions:
Mode
Stats Field Description
(1) r: The number of processes waiting for run time.
Procs
(2) b: The number of processes in uninterruptible sleep.
(3) swpd: the amount of virtual memory used.
(4) free: the amount of idle memory.
(5) buff: the amount of memory used as buffers.
Memory
(6) cache: the amount of memory used as cache.
(17) inact: the amount of inactive memory.
(18) active: the amount of active memory.
(7) si: Amount of memory swapped in from disk (/s).
Swap
(8) so: Amount of memory swapped to disk (/s).
Virtual
(9) bi: Blocks received from a block device (blocks/s).
I/O
memory
(10) bo: Blocks sent to a block device (blocks/s).
in: The number of interrupts per second, including the
(11)
clock.
System
(12) cs: The number of context switches per second.
us: Time spent running non-kernel code. (user time,
(13)
including nice time)
(14) sy: Time spent running kernel code. (system time)
CPU
id: Time spent idle. Prior to Linux 2.5.41, this includes
(15)
IO-wait time.
wa: Time spent waiting for IO. Prior to Linux 2.5.41,
(16)
included in idle.
Device (19) Device name
(20) total: Total reads completed successfully
Disk, -d
Reads (21) merged: grouped reads (resulting in one I/O)
(22) sectors: Sectors read successfully
125
Writes
I/O
Slab, -m
Slab
(23)
(24)
(25)
(26)
(27)
(28)
(29)
(30)
(31)
(32)
(33)
(34)
ms: milliseconds spent reading
total: Total writes completed successfully
merged: grouped writes (resulting in one I/O)
sectors: Sectors written successfully
ms: milliseconds spent writing
cur: I/O in progress
s: seconds spent for I/O
cache: Cache name
num: Number of currently active objects
total: Total number of available objects
size: Size of each object
pages: Number of pages with at least one active object
top output:
# (1)
(2)
(3)
(4)
top - 03:22:44 up 4 days, 22:54, 1 user, load average: 0.00, 0.00, 0.00
#
(5)
(6)
(7)
(8)
(9)
Tasks: 63 total, 1 running, 62 sleeping, 0 stopped, 0 zombie
#
(10) (11) (12) (13)
(14) (15) (16) (17)
Cpu(s): 0.0%us, 1.1%sy, 0.0%ni, 98.9%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
#
(18)
(19)
(20)
(21)
Mem: 508820k total, 273792k used, 235028k free, 27844k buffers
#
(22)
(23)
(24)
(25)
Swap: 473080k total,
0k used, 473080k free, 201252k cached
#(26) (27) (28)(29) (30) (31) (32,33) (34)(35)
(36) (37)
PID USER
PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root
20 0 8356 804 676 S 0.0 0.2 0:05.99 init
2 root
20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root
RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0
4 root
20 0 0 0 0 S 0.0 0.0 0:00.06 ksoftirqd/0
5 root
RT 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0
6 root
20 0 0 0 0 S 0.0 0.0 0:03.25 events/0
7 root
20 0 0 0 0 S 0.0 0.0 0:00.00 cpuset
<...>
Fields and descriptions:
Section Field
Description
(1)
Current time.
(2)
Uptime (time passed since boot).
(3)
How many users are currently logged in.
Uptime
CPU load in past 1, 5 and 15 minuts. This is not normalized,
so a load average of 1 means a single CPU system is loaded
(4)
all the time while on a 4 CPU system it means it was idle 75%
of the time.
(5)
Total number of running processes.
(6)
Number of processes currently executing.
(7)
Number of processes currently sleeping.
Tasks
Number of processes curretnly stopped (with CTRL+Z for
(8)
example).
(9)
Number of defunct (“zombie”) process, terminated but not
126
reaped by its parent.
The time the CPU has spent running users' processes that are
(10)
not niced.
The time the CPU has spent running the kernel and its
(11)
processes.
The time the CPU has spent running users' proccess that
(12)
have been niced.
(13)
The time the CPU spent idle.
Cpu(s)
(14)
Amount of time the CPU has been waiting for I/O to complete.
The amount of time the CPU has been servicing hardware
(15)
interrupts.
The amount of time the CPU has been servicing software
(16)
interrupts.
The amount of CPU 'stolen' from this virtual machine by the
(17)
hypervisor for other tasks (such as running another virtual
machine).
(18)
Total amount of psysical memory.
(19)
Total amount of used physical memory.
(20)
Total mount of free physical memory.
Mem/swap
Total RAM dedicated to cache disk block, and filesystem
(21)
metadata.
(22,23,24) Total, used and free swap memory.
(25)
Total RAM dedicated to pages from file reading.
The task's unique process ID, which periodically wraps,
(26)
though never restarting at zero.
(27)
The effective user name of the task's owner.
(28)
The priority of the task.
The nice value of the task. A negative nice value means
higher priority, whereas a positive nice value means lower
(29)
priority. Zero in this field simply means priority will not be
adjusted in determining a task's dispatchability.
The total amount of virtual memory used by the task. It
includes all code, data and shared libraries plus pages that
(30)
have been swapped out and pages that have been mapped
Process
but not used.
(31)
The non-swapped physical memory a task has used.
The amount of shared memory used by a task. It simply
(32)
reflects memory that could be potentially shared with other
processes.
The status of the task which can be one of: 'D' =
(33)
uninterruptible sleep, 'R' = running, 'S' = sleeping, 'T' = traced
or stopped, 'Z' = zombie.
The task's share of the elapsed CPU time since the last
(34)
screen update, expressed as a percentage of total CPU time.
(35)
A task's currently used share of available physical memory.
127
CPU Time, hundredths, The same as 'TIME', but reflecting
more granularity through hundredths of a second.
(37)
Command – Command line or Program name
There are lots of fields as you may see. Many of fields are present in several utilities,
which duplicate functionality of each other somewhat. Normally you will need only
small subset of this fields, but you need to know that there is this many (actually, a
lot more) information about system performance available to you, because
sometimes an obscure problem happens and to be able to solve it you need to know
how to read this stats.
Now you will learn how to uses system performance utilities.
(36)
Do this
1: uptime
2: free
3: vmstat
4: ( sleep 5 && dd if=/dev/urandom of=/dev/null bs=1M count=30 && sleep 5 && killall vmstat )&
vmstat 1
5: uptime
6: ( sleep 5 && dd if=/dev/zero of=test.img bs=32 count=$((32*1024*200)) && sleep 5 && killall
vmstat )& vmstat -nd 1 | egrep -v 'loop|sr0'
7: echo 3 | sudo tee /proc/sys/vm/drop_caches
8: free -mt ; find / >/dev/null 2>&1 ; free -mt
9: echo 3 | sudo tee /proc/sys/vm/drop_caches
10: cat test.img /dev/null ; free -mt
What you should see
student@vm1:~$ uptime
05:36:45 up 6 days, 1:08, 1 user, load average: 0.00, 0.00, 0.00
student@vm1:~$ free
total
used
free shared buffers cached
Mem:
508820 239992 268828
0
820 213720
-/+ buffers/cache:
25452 483368
Swap:
473080
0 473080
student@vm1:~$ vmstat
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---r b swpd free buff cache si so bi bo in cs us sy id wa
0 0
0 268828 820 213720 0 0 21 10 14 11 0 0 100 0
student@vm1:~$ ( sleep 5 && dd if=/dev/urandom of=/dev/null bs=1M count=30 && sleep 5 && killall
vmstat )& vmstat 1
[1] 6078
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---r b swpd free buff cache si so bi bo in cs us sy id wa
1 1
0 268556 828 213736 0 0 21 10 14 11 0 0 100 0
0 0
0 268556 828 213772 0 0 16 0 19 10 0 0 100 0
0 0
0 268556 828 213772 0 0 0 0 13 8 0 0 100 0
0 0
0 268556 828 213772 0 0 0 0 15 11 0 0 100 0
0 0
0 268556 828 213772 0 0 0 0 14 10 0 0 100 0
0 0
0 268556 828 213772 0 0 0 0 18 13 0 0 100 0
1 0
0 267316 836 213844 0 0 74 0 267 26 0 99 1 0
1 0
0 267316 836 213844 0 0 0 0 303 7 0 100 0 0
1 0
0 267316 836 213844 0 0 0 0 271 11 0 100 0 0
1 0
0 267316 836 213844 0 0 0 0 257 12 0 100 0 0
30+0 records in
30+0 records out
31457280 bytes (31 MB) copied, 4.95038 s, 6.4 MB/s
0 0
0 267928 860 213860 0 0 27 0 265 29 1 97 2 0
0 0
0 267936 860 213848 0 0 0 0 15 9 0 0 100 0
128
0 0
0 267936 860 213848 0 0 0 0 14 7 0 0 100 0
0 0
0 267936 860 213848 0 0 0 0 14 7 0 0 100 0
0 0
0 267936 860 213848 0 0 0 0 13 11 0 0 100 0
Terminated
student@vm1:~$ uptime
05:22:15 up 6 days, 54 min, 1 user, load average: 0.07, 0.02, 0.00
[1]+ Done
( sleep 5 && dd if=/dev/urandom of=/dev/null bs=1M count=30 && sleep 5 &&
killall vmstat )
student@vm1:~$ uptime
05:22:22 up 6 days, 54 min, 1 user, load average: 0.06, 0.02, 0.00
student@vm1:~$ ( sleep 5 && dd if=/dev/zero of=test.img bs=32 count=$((32*1024*200)) && sleep 5
&& killall vmstat )& vmstat -nd 1 | egrep -v 'loop|sr0'
[1] 6086
disk- ------------reads------------ ------------writes----------- -----IO-----total merged sectors
ms total merged sectors
ms cur sec
sda 146985 2230744 21821320 105848 32190 1343154 10927338 1330144
0 105
sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144
0 105
sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144
0 105
sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144
0 105
sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144
0 105
sda 146995 2230744 21821648 105848 32190 1343154 10927338 1330144
0 105
sda 146999 2230744 21821680 105856 32190 1343154 10927338 1330144
0 105
sda 146999 2230744 21821680 105856 32190 1343154 10927338 1330144
0 105
sda 147000 2230744 21821688 105856 32208 1344160 10935530 1330288
0 105
sda 147000 2230744 21821688 105856 32274 1349214 10976490 1330748
0 105
sda 147000 2230744 21821688 105856 32325 1353259 11009258 1331236
0 105
sda 147000 2230744 21821688 105856 32450 1364657 11101442 1337176
0 105
sda 147000 2230744 21821688 105856 32450 1364657 11101442 1337176
0 105
sda 147001 2230744 21821696 105856 32471 1366301 11114762 1337348
0 105
sda 147001 2230744 21821696 105856 32525 1370529 11149018 1337732
0 105
sda 147001 2230744 21821696 105856 32573 1374577 11181786 1338064
0 105
sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244
0 105
6553600+0 records in
6553600+0 records out
209715200 bytes (210 MB) copied, 11.7088 s, 17.9 MB/s
sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244
0 105
sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244
0 105
sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244
0 105
sda 147001 2230744 21821696 105856 32698 1386562 11278666 1346244
0 105
sda 147001 2230744 21821696 105856 32762 1393910 11337962 1349192
0 105
student@vm1:~$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
[1]+ Done
( sleep 5 && dd if=/dev/zero of=test.img bs=32 count=$((32*1024*200)) &&
sleep 5 && killall vmstat )
student@vm1:~$ free -mt ; find / >/dev/null 2>&1 ; free -mt
total
used
free shared buffers cached
Mem:
496
30
466
0
0
5
-/+ buffers/cache:
24
472
Swap:
461
0
461
Total:
958
30
928
total
used
free shared buffers cached
Mem:
496
64
432
0
22
6
-/+ buffers/cache:
35
461
Swap:
461
0
461
Total:
958
64
894
student@vm1:~$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
student@vm1:~$ cat test.img /dev/null ; free -mt
total
used
free shared buffers cached
Mem:
496
230
265
0
0
205
129
-/+ buffers/cache:
Swap:
461
Total:
958
student@vm1:~$
24
0
230
471
461
727
Explanation
Prints out current uptime.
Prints out free memory information.
This one is interesting. It is better be thought like a sort of experiment. First, we
launch ( sleep 5 && dd if=/dev/urandom of=/dev/null bs=1M count=30 && sleep
5 && killall vmstat )& in the background, and immediately after that we start vmstat
in continuous mode so it will print out its information until interrupted. We are able to
see that after 5 seconds since this command start CPU load increases dramatically
for some time and then decreases, after another 5 seconds vmstat is killed.
Prints out current uptime. Notice changes in load average.
This is another experiment, almost the same as before, but this time with disk writes.
Drops all caches and buffers.
Another experiment. We want to see how reading all file and directory names in the
system affects filesystem cache in memory, and we are able to see that it is cached
in buffers, which is in accordance to theory.
Drops all caches and buffers again.
This time we want to see how reading a file affects filesystem cache in memory. We
are able to see that files which are read are cached in cached section for increasing
time of consequent access.
Extra credit
Why in our first experiment not user, but system CPU usage goes up to 100?
What this means? dd if=/dev/zero of=test.img bs=32 count=$( (32*1024*200) ).
Launch top and press h. Now try sorting its output by CPU, memory and PID.
Exercise 29. Kernel: kernel messages,
dmesg
Well, if you made it this far it is time to talk about kernel. We will start this talk with
Wikipedia definition of an Operating System kernel:
In computing, the kernel (from German Kern, nucleus, core) is the main component
of most computer operating systems; it is a bridge between applications and the
actual data processing done at the hardware level. The kernel's responsibilities
include managing the system's resources (the communication between hardware
and software components). Usually as a basic component of an operating system, a
kernel can provide the lowest-level abstraction layer for the resources (especially
processors and I/O devices) that application software must control to perform its
function. It typically makes these facilities available to application processes through
inter-process communication mechanisms and system calls.
And this is what Wikipedia tells us about Linux Kernel specifically:
The Linux kernel is the operating system kernel used by the Linux family of Unix-like
operating systems. It is one of the most prominent examples of free and open source
software. It supports true preemptive multitasking (both in user mode and kernel
130
mode), virtual memory, shared libraries, demand loading, shared copy-on-write
executables, memory management, the Internet protocol suite, and threading.
Now is a good time to visit corresponding Wikipedia article and spend some time
clicking feverishly on all those scary terms which describe technical features Linux
Kernel has. After doing so, let us talk about much more mundane subject, which is a
way kernel cat tell us something. This happens, for example, if USB-stick is attached
to the computer, or network link becomes down, or filesystem mounting is
performed. To be able to tell you all this things, kernel uses a mechanism known as
display message or driver message, name of which is abbreviated to dmesg.
This mechanism is represented by the buffer of fixed size to which kernel writes its
messages. On Debian Linux distribution information from this buffer are also copied
to /var/log/dmseg after system log daemon is started. This is done to preserve this
messages which would otherwise be overwritten by new ones.
dmesg is also name of utility which allows you to view those messages which are
currently in kernel buffer, and also change this buffer size.
Let me summarize dmesg-related files and programs:
dmesg — print or control the kernel ring buffer
/var/log/dmseg — log file in Debian distribution which contains copy of dmesg
messages during system boot only, without timestamps.
/var/log/kern.log — log file in Debian distribution which contains copy of all dmesg
messages, including timestamps. Notice that this timestamps start ticking after
rsyslog logging daemon is started, which means that all boot time messages before
rsyslog is started will have the same timestamp. This file contains /var/log/dmesg
in itself.
/var/log/messages — log file in Debian distribution which logs all non-debug and
non-critical messages. It contains /var/log/dmesg in itself.
/var/log/syslog — log file in Debian distribution which logs everything, except auth
related messages. It contains all messages which go to /var/log/messages and
/var/log/kern.log in itself.
Do this
1: date
2: sudo umount /tmp ; sudo mount /tmp
3: sudo tail -f /var/log/dmesg /var/log/messages /var/log/syslog /var/log/kern.log
What you should see
student@vm1:~$ date
Tue Jul 24 06:55:33 EDT 2012
student@vm1:~$ sudo umount /tmp ; sudo mount /tmp
student@vm1:~$ dmesg | tail
[ 7.166240] tun: Universal TUN/TAP device driver, 1.6
[ 7.166242] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
[ 7.432019] ADDRCONF(NETDEV_UP): eth0: link is not ready
[ 7.435270] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
[ 7.435927] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[ 17.472049] tap0: no IPv6 routers present
[ 17.592044] eth0: no IPv6 routers present
[ 217.497357] kjournald starting. Commit interval 5 seconds
[ 217.497561] EXT3 FS on sda8, internal journal
[ 217.497564] EXT3-fs: mounted filesystem with ordered data mode.
student@vm1:~$ sudo tail /var/log/dmesg /var/log/messages /var/log/syslog /var/log/kern.log
==> /var/log/dmesg <==
[ 6.762569] EXT3 FS on sda5, internal journal
[ 6.762572] EXT3-fs: mounted filesystem with ordered data mode.
131
[
[
[
[
[
[
[
[
6.767237] kjournald starting. Commit interval 5 seconds
6.767407] EXT3 FS on sda6, internal journal
6.767410] EXT3-fs: mounted filesystem with ordered data mode.
7.166240] tun: Universal TUN/TAP device driver, 1.6
7.166242] tun: (C) 1999-2004 Max Krasnyansky <maxk@qualcomm.com>
7.432019] ADDRCONF(NETDEV_UP): eth0: link is not ready
7.435270] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
7.435927] ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
==> /var/log/messages <==
Jul 24 06:52:07 vm1 kernel: [ 6.767407] EXT3 FS on sda6, internal journal
Jul 24 06:52:07 vm1 kernel: [ 6.767410] EXT3-fs: mounted filesystem with ordered data mode.
Jul 24 06:52:07 vm1 kernel: [ 7.166240] tun: Universal TUN/TAP device driver, 1.6
Jul 24 06:52:07 vm1 kernel: [ 7.166242] tun: (C) 1999-2004 Max Krasnyansky
<maxk@qualcomm.com>
Jul 24 06:52:07 vm1 kernel: [ 7.432019] ADDRCONF(NETDEV_UP): eth0: link is not ready
Jul 24 06:52:07 vm1 kernel: [ 7.435270] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow
Control: RX
Jul 24 06:52:07 vm1 kernel: [ 7.435927] ADDRCONF(NETDEV_CHANGE): eth0: link becomes
ready
Jul 24 06:55:36 vm1 kernel: [ 217.497357] kjournald starting. Commit interval 5 seconds
Jul 24 06:55:36 vm1 kernel: [ 217.497561] EXT3 FS on sda8, internal journal
Jul 24 06:55:36 vm1 kernel: [ 217.497564] EXT3-fs: mounted filesystem with ordered data mode.
==> /var/log/syslog <==
Jul 24 06:52:08 vm1 acpid: 1 rule loaded
Jul 24 06:52:08 vm1 acpid: waiting for events: event logging is off
Jul 24 06:52:08 vm1 /usr/sbin/cron[882]: (CRON) INFO (pidfile fd = 3)
Jul 24 06:52:08 vm1 /usr/sbin/cron[883]: (CRON) STARTUP (fork ok)
Jul 24 06:52:08 vm1 /usr/sbin/cron[883]: (CRON) INFO (Running @reboot jobs)
Jul 24 06:52:16 vm1 kernel: [ 17.472049] tap0: no IPv6 routers present
Jul 24 06:52:16 vm1 kernel: [ 17.592044] eth0: no IPv6 routers present
Jul 24 06:55:36 vm1 kernel: [ 217.497357] kjournald starting. Commit interval 5 seconds
Jul 24 06:55:36 vm1 kernel: [ 217.497561] EXT3 FS on sda8, internal journal
Jul 24 06:55:36 vm1 kernel: [ 217.497564] EXT3-fs: mounted filesystem with ordered data mode.
==> /var/log/kern.log <==
Jul 24 06:52:07 vm1 kernel: [
Jul 24 06:52:07 vm1 kernel: [
<maxk@qualcomm.com>
Jul 24 06:52:07 vm1 kernel: [
Jul 24 06:52:07 vm1 kernel: [
Control: RX
Jul 24 06:52:07 vm1 kernel: [
ready
Jul 24 06:52:16 vm1 kernel: [
Jul 24 06:52:16 vm1 kernel: [
Jul 24 06:55:36 vm1 kernel: [
Jul 24 06:55:36 vm1 kernel: [
Jul 24 06:55:36 vm1 kernel: [
7.166240] tun: Universal TUN/TAP device driver, 1.6
7.166242] tun: (C) 1999-2004 Max Krasnyansky
7.432019] ADDRCONF(NETDEV_UP): eth0: link is not ready
7.435270] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow
7.435927] ADDRCONF(NETDEV_CHANGE): eth0: link becomes
17.472049] tap0: no IPv6 routers present
17.592044] eth0: no IPv6 routers present
217.497357] kjournald starting. Commit interval 5 seconds
217.497561] EXT3 FS on sda8, internal journal
217.497564] EXT3-fs: mounted filesystem with ordered data mode.
Explanation
Prints out current date and time.
Prints last 10 messages from kernel messages buffer.
Prints last 10 messages from /var/log/dmesg, /var/log/messages, /var/log/syslog
and /var/log/kern.log.
132
Exercise 30. Lather, Rinse, Repeat: The
Grand Rote Learning
Amount of information in this guide is pretty big. You cannot retain it without long enough
practice and some hardcore grinding. So the only task left for you will be filling in this table,
and imprinting this table in your memory every day until you know it.
You may want to ask why do you need to memorize all this stuff if you can always look it up.
Well, the short answer will be because you can not. What this means is that to look up things
efficiently you already need what to look for, and to know what to look for, you need a solid
foundation. Once you have this foundation, once you understand what is important and what
is not, and how the system is organized, you will be able to efficiently look things up.
You may wonder why in my guide there are many detailed tables containing lists of many
fields which contain information which you will almost never need. What you must
understand, though, is that you should train yourself to look any console program this way.
You should approach to this information not like to a fiction book, where you may not pay
attention do details and still understand it pretty well. You should approach all those data as
mathematical formulas, where every single symbol has its meaning, and even more so, if
you do not understand what particular symbol means, you will not be able to go further.
Sometimes it is perfectly okay to left something unexplained, but make yourself a present of
going deeper, even if it will be every so often. Give yourself a present by making research
about this particular utility, understand what it tells you and why. If you will do this, if you will
look deep inside, your understanding of an Operating System (Linux in our case) will
increase dramatically.
Documentation
man, info
Command or concept
Meaning
________________________________
______________________________________
man
info
man 1
man 2
man 3
man 4
man 5
man 6
man 7
man 8
man 9
man -k
man -wK
bold text</code>
italic text</code>
[]
-a | -b
argument ...
[expression] ...
Google and useful resources
133
Search
Meaning
term/resource__________________________ __________________________________
_____
____
(a|b) c
site:foo.bar
"a long query"
http://en.wikipedia.org
http://stackexchange.com/
http://www.cyberciti.biz/
http://tldp.org/
programname.site
Package management: Debian package management utility aptitude
Command or concept
Meaning
________________________________
______________________________________
aptitude
aptitude search
aptitude install
dpkg -l
dpkg -L
Desired action
Package status
http://www.debian.org/distrib/packages
System boot: runlevels, /etc/init.d, rcconf, update-rc.d
Command or concept
Meaning
________________________________
______________________________________
rcconf
update-rc.d
sysv-rc-conf
runlevel
runlevel 1
runlevel 2
runlevel 6
Processes: Working with proccesses, ps, kill
Command or concept
Meaning
________________________________
______________________________________
ps
kill
ps ax
ps axue
ps axue --forest
signal
HUP
TERM
KILL
Why KILL -9 is bad?
134
Job chedulers: cron, at
Command or concept
________________________________
crontab -l
crontab -e
crontab -r
crontab /foo
crontab > foo
*****
at
atq
atq
atrm
batch
Logging, /var/log, rsyslog, logger
Command or concept
________________________________
logger
grep -irl
find . -mmin -5
tail -f
logrotate
logging daemon
log level daemon
log rotation
Filesystems
Command or concept
________________________________
Filesystem
File
Directory
Inode
Block
Mounting
UUID
Journal
MBR
Partition
Partition table
Mounting, mount, /etc/fstab
Command or concept
________________________________
parted
cfdisk
fdisk
Meaning
______________________________________
Meaning
______________________________________
Meaning
______________________________________
Meaning
______________________________________
135
mount
umount
mount -a
/etc/fstab
fsck
blkid
logging daemon
log rotation
Creating and modifying filesystems, mkfs, tune2fs
Command or concept
Meaning
________________________________
______________________________________
tune2fs
mkfs
Block size
Reserverd block count
Maximum mount count
Check interval
Changing root directory, chroot
Command or concept
Meaning
________________________________
______________________________________
chroot
ldd
Root directory
Chroot
Dynamic Dependency
Moving data arount: tar, dd
Command or concept
Meaning
________________________________
______________________________________
tar
dd
losetup
Security permissions, chown, chmod
Command or concept
Meaning
________________________________
______________________________________
chmod
chown
umask
Permission
Permission mode
Permission class
Umask mechanism
Networking
Network conecept
Meaning
__________________________________ ______________________________________
OSI model
DOD model
136
Communications protocol
Ethernet
MAC address
Ethernet boradcast address
TCP/IP
IP
IP packet
IP address
IP subnet
Port
Network socket
Local socket address
Remote socket address
Socket pair
Routing
Default gateway
IP boadcast address
ICMP
TCP
TCP packet
UDP
UDP packet
Hostname
Interface configuration, ifconfig, netstat, iproute2, ss
Command or concept
Meaning
________________________________
______________________________________
/etc/network/interfaces
auto
allow-hotplug
/etc/hosts
/etc/hostname
localhost
loopback interface
Pseudo-interface
Configuration files, /etc/network/interfaces
Command or concept
Meaning
________________________________
______________________________________
/etc/network/interfaces
auto
allow-hotplug
/etc/hosts
/etc/hostname
localhost
loopback interface
Pseudo-interface
137
Packet filter configuration, iptables
Command or concept
Meaning
________________________________
______________________________________
iptables-save
iptables
modprobe
nc
tcpdump
LINKTYPE_LINUX_SLL
Ethernet frame header
IPv4 header
TCP segment
netfilter
iptables
iptables tables
iptables chains
iptables target
Secure shell, ssh, sshd, scp
Command or concept
Meaning
________________________________
______________________________________
ssh
sshd
scp
ssh-keygen
Host keys
Auth keys
Data encryption ciphers
Data integrity algorithms
SSH session key
Performance: getting performance stats, uptime, free, top
Command or concept
Meaning
________________________________
______________________________________
uptime
free
vmstat
top
CPU usage (us,sy,id,wa)
Memory (swpd, free, buff, cache,
inact, active)
Slab allocation
Disk (IOPS, read, write)
Process (PR, NI, VIRT,
RES, SHR, Status)
Kernel: kernel messages, dmesg
Command or concept
Meaning
________________________________
______________________________________
138
dmseg
/var/log/dmesg
/var/log/messages
/var/log/syslog
/var/log/kern.log
Kernel message buffer
139
Download