Essential System Administration, Third Edition
Because passwords play a central role in overall system security, all user accounts should have passwords.[14] However, simply having a password is only the first step in making a user account secure. If the password is easy to figure out or guess, it will provide little real protection. In this section, we'll look at characteristics of good and bad passwords. The considerations discussed here apply both to choosing the root password (which the system administrator chooses) and to user passwords. In the latter case, your input usually takes the form of educating users about good and bad choices. [14] The only possible exception I see is an isolated, non-networked system with no dial-in modems at a personal residence, but even then you might want to think about the potential risks from repair people, houseguests, neighborhood kids, and so on, before deciding not to use passwords. Every system in a commercial environment, even single-user systems in locked offices, should use passwords. 6.4.1 Selecting Effective Passwords
The purpose of passwords is to prevent unauthorized people from accessing user accounts and the system in general. The basic selection principle is this: Passwords should be easy to remember but hard to figure out, guess, or crack. The first part of this principle argues against imposing automatically-generated random passwords (except when government or other mandated security policies require it). Many users have a very hard time remembering them, and in my experience, most users will keep a written record of their password for some period of time after they first receive it, even when this is explicitly prohibited. If users are educated about easier ways to create good passwords, and you take advantage of features that Unix systems provide requiring passwords to be a reasonable length, users can select passwords that are just as good as system-generated ones. Allowing users to select their own passwords will make it much more likely that they will choose one that they can remember easily. In practical terms, the second part of the principle means that passwords should be hard to guess even if someone is willing to go to a fair amount of effort and there are plenty of people who are. This means that the following items should be avoided as passwords or even as components of passwords:
We could obviously list more such items, but this should illustrate the basic idea. Passwords should also be as immune as possible to attack by password-cracking programs, which means that the following items should not be selected as passwords:
Avoiding passwords like the items in the first list makes it harder for someone to figure out your password. Avoiding the items in the second list makes it harder for someone to successfully break into an account using a brute-force, trial-and-error method, like a computer program.
Simple modifications of any of these bad passwords, created by adding a single additional character, spelling it backwards, or permuting the letters, are still bad passwords and ought to be avoided. For example, avoid not only "john" but also "nhoj" and "ohnj" and "john2." It doesn't take a password-guessing program very long to try all combinations of adding one character, reversing, and permuting. Although they are risky themselves, items from the second list can serve as the base for creating a better password (I don't recommend using any personal items in passwords at all). Passwords that use two or more of the following modifications to ordinary words are much more likely to be good choices:
Table 6-8 illustrates some of these recommendations, using "StarTrek" as a base (although I'd recommend avoiding altogether anything having to do with Star Trek in passwords).
Of course, these would all be poor choices now. When selecting passwords and advising users about how to do so, keep in mind that the overall goal is that passwords be hard to guess, for humans and programs, but easy to remember and fast to type. There are other ways of selecting passwords other than using real words as the base. Here are two popular examples:
Here are some additional general recommendations about passwords and system security:
Unix offers options for enforcing password-selection policies; they are discussed later in this section. If you'd like to use a carrot as well as a stick in this regard, see the section on educating users about passwords later in this chapter. 6.4.1.1 Forcing a password change
Most Unix systems provide commands that allow you to force a user to change her password at the next login. You can use such commands in a script on those (hopefully rare) occasions when everyone must change their password right away. These are the commands provided by the versions we are considering (they all take a username as their final argument):
The Linux command works by setting the date of the last password change to January 1, 1970, and the maximum password lifetime to 999 days. This is a bit of akludge, but it gets the job done when password aging is not in effect (you can go back and later remove the maximum password lifetime if desired). However, if you are using password aging, you can omit the -M option and allow the normal setting to perform the same function. On FreeBSD systems, the user account modification utility is interactive and places you into an editor session by default. However, you can use the following script to automate the process of forcing a password change (accomplished by placing a date in the past into the Change field of the form): #!/bin/tcsh setenv EDITOR ed /usr/bin/chpass $1 <<END /Change/ s/:.*$/: 12 31 1999/ w q END You can choose any past date that you like. 6.4.1.2 Managing dozens of passwords
When choosing successivepasswords and especially root passwords try to avoid falling into a simple recognizable pattern. For example, if you always capitalize all the vowels, and someone knows this, you effectively lose the value of the unusual capitalization. Similarly, successive passwords are often chosen in the same way; don't always choose names of planets for your passwords. It is especially important to break such patterns when someone with longtime access to the root account and hence well aware of past patterns in passwords leaves the system or loses root access. That said, it is impossible for most people even system administrators to remember all of the root passwords that they may need to know across a large enterprise without some scheme for generating/predicting the password for each system. One approach is to use the same root password on all the systems administered by the same person or group of people. This may be effective for some sites, but it has the disadvantage that if the root password is compromised on any system, the entire group of systems is then wide open to unauthorized root-level access. Sites that have experienced such a break-in tend to give up the convenience of a single root password in favor of enhanced security and the ability to contain an intruder should the worst happen. The solution in this case is to have some scheme (algorithm) for generating rootpasswords based on some characteristics of the computer system in question. Here is a simple example that indicates how to generate each character of the password in turn:
For a Sun system running Solaris 7 named dalton, this would yield a password of "s6Ns8r%"; similarly, for an IBM RS/6000 running AIX 4.3 named venus, the password would be "i5Sa4&". Although they are too short at only six characters, these are decent passwords in terms of character variety and capitalization, and they are easy to generate mentally as needed with just a little practice. Another problem that occurs with rootpasswords that are changed on a regular schedule is coordination of changes and getting the new value to everyone involved. Again, this is a case where an algorithm can be of great use. Let's suppose the root password must be changed monthly. Successive passwords can be generated from a base component that everyone knows and a varying portion generated from the current month and year. We'll use "xxxx" a lousy choice, of course for our base component in a simple example. Each month, we append the month and year to it, adding an additional "x" for months less than 10. In 2000, this would yield the passwords: xxxxx100, xxxxx200, ..., xxxx1200. A real scheme would need to be more complex, of course. This could be done by choosing a more obscure base component and generating the varying portion according to a more complex algorithm: something involving a simple mathematical computation using the month and year as variables, for example. The advantage of such a system is that any administrator can change the monthly root password without inconveniencing other administrators. If someone attempts to use the old root password and is unsuccessful, she will realize that the monthly change has occurred and will already know the new password. In fact, these two separate approaches could be combined. The remaining two (or more) characters of the system information-based password could be used for the varying portion based on the time period. 6.4.2 Educating Users About Selecting Effective Passwords
Helping users use the system more effectively is part of a system administrator's job. Sometimes, this means providing them with the information they need to do something, in this case, choose a good password. There are a variety of ways you might convey information and suggestions about password selection to the users on your systems or at your site:
One or more of these suggestions may make sense at your site. 6.4.2.1 Password advice in the age of the Internet
The Internet and its myriad web sites, many of which now request or require user names and passwords for access, has made advising users on good password usage practices significantly more complicated. As we noted above, users should be prohibited from using their password(s) for the local site in any other context, and especially not on the Internet. But beyond that, users often need to have the risks associated with Internet access and transactions explicitly pointed out from time to time, accompanied by a reminder that the passwords they choose to protect such activities are their only defense against the bad guys. It is not uncommon for a user to visit several to dozens of such web sites on a regular basis. In theory, the best practice is to use a different password for every one of them. Realistically, however, very few users are capable of remembering that many passwords, especially when some of the sites involved are visited rather infrequently (say, less than once a month). Clearly, we need to modify our usual password selection and usage advice to deal with the realities of the Internet and to be of more genuine help to users. Treating equally every web site requesting an account name andpassword merely exacerbates the problem and its inherent combinatorics. Instead, we can divide such Web sites into classes based on the potential losses that might occur if the username and password associated with them was discovered by an unscrupulous person: in other words, by what we have to lose (if anything). There are several general types of such sites:
Note that even the most innocuous sites can change their character over time. For example, a site that now merely provides access to information might at some point in the future add other services; at such time, the password in use there would need to be rethought. Obviously, the different security needs of the different kinds of sites make different demands on the rigor of password selection. Given that it is seldom practical to have a unique password for every Internet site, we can make the following recommendations:
6.4.3 Setting Password Restrictions
Users don't like to change theirpasswords. However, Unix provides mechanisms by which you can force them to do so anyway. You can specify how long a user can keep the same password before being forced to change it (the maximum password lifetime), how long he must keep a new password before being allowed to change it again (the minimum password lifetime), the minimum password length, and some other related parameters. Setting the minimum and maximum password lifetimes is referred to as specifying password aging information. Before you decide to turn on password aging on your system, you should consider carefully how much password fascism you really need. Forcing users to change their password when they don't want to is one of the least effective system security tactics. Certainly, there are times when passwords must be changed whether users like it or not, such as when an employee with high-level system access is terminated. However, random forced password changes don't ensure that good passwords will be chosen (in fact, the opposite effect is at least as likely). And using a minimum password lifetime to prevent a user from changing her new password right back to what it was before (a password she liked and could remember without writing it down) can also have some unexpected side effects. One potential problem with aminimum password lifetime comes when a password really needs to be changed when someone who shouldn't know it does, for example. At such times, a user might be unable to change his password even though he needs to. Of course, the superuser can always change passwords, but then the user will have to hunt down the system administrator, admit what happened, and get it changed. Depending on the security policies and general atmosphere at your site, the user may decide just to wait until the minimum lifetime expires and change it himself, and live with the risk until then. You'll need to decide which is more likely on your system: users attempting to circumvent necessary password aging or users needing to be able to change their passwords at will; either one could be more important for system security in your particular situation. Many Unix versions also offer other controls related to password selection and related items:
6.4.3.1 Password aging
On most systems, password aging settings for user accounts are stored with the entries in theshadow password file. As we noted earlier, entries in the shadow password file have the following syntax: username:coded password:last_change:minlife:maxlife:warn:inactive:expires:unused where username is the name of the user account, and coded password is the encoded user password. The remaining fields within each entry control the conditions under which a user is allowed to and is forced to change his password, as well as an optional account expiration date:
The settings provide a system administrator with considerable control over user password updating practices. You can edit these fields directly in the shadow password file, or you may use the command provided by the system, usually passwd (Linux systems use the chage command). The options corresponding to each setting are listed in Table 6-9. HP-UX and Tru64 systems running enhanced security and AIX provide the same functionality via different mechanisms: theprotected password database and the settings in the /etc/security/user configuration file, respectively. FreeBSD provides an account expiration date via a field in the master.passwd file. Table 6-10 also lists the commands for modifying this data.
For example, the following commands set the minimum password age to seven days and the maximum password age to one year for user chavez: # passwd -n 7 -x 365 chavez HP-UX and Solaris # chage -m 7 -M 365 chavez Linux # chuser maxage=52 minage=1 chavez AIX # usermod -x password_min_change_time=7 \ Tru64 password_expire_time=365 chavez Here is the display produced by passwd -s for listing a user's password aging settings: # passwd -s chavez chavez PS 05/12/2000 0 183 7 -1 The second item in the display is the password status, one of PS or P (password defined), NP (no password), or LK or L (account is locked via a password modification). The third item is the date chavez last changed her password. The fourth and fifth items indicate the minimum and maximum password lifetimes (in days), and the sixth item shows the number of days prior to password expiration that chavez will begin to receive messages to that effect. The final column indicates the inactivity period. In our example, chavez must change her password about twice a year, and she will be warned seven days before her password expires; the minimum password age and inactivity periods are not used. Here is the corresponding display produced by chage under Linux, which is much more informative and self-explanatory: # chage -l harvey Minimum: 0 Maximum: 99999 Warning: 0 Inactive: -1 Last Change: Sep 05, 2002 Password Expires: Never Password Inactive: Never Account Expires: Never These settings provide user harvey with complete freedom about when (or if) to change his password. You can also set user account password aging settings with most of the graphical administrative tools we considered earlier. Figure 6-12 illustrates these features. Figure 6-12. Specifying password aging settings Starting from the upper left and moving clockwise, the figure shows the forms provided by HP-UX's SAM, Solaris' SMC, AIX's SMIT, the Red Hat User Manager, and YaST2. The latter provides a convenient way of setting the system default password aging and length settings (it is reached via the Security
6.4.3.2 Password triviality checks
Security weaknesses arising from user passwords are of two main sorts: poorly chosen passwords are easy to guess or crack, and passwords of any quality may be discovered or inadvertently revealed in a variety of ways. Imposing password aging restrictions represents an attempt to deal with the second sort of risk by admitting up front that sometimes passwords are discovered and by reasoning that changing them periodically will deal with these exigencies. Helping users to choose better, more secure passwords in the first place is the goal of password triviality checking systems (the process is also known as obscurity checking and checking for obviousness). This approach involves checking a new password proposed by a user for various characteristics that will make it easy to crack and rejecting the password if these characteristics are found. Obscurity-checking capabilities are usually integrated into the passwd command and may reject passwords of a variety of types, including the following:
Many Unix systems check for the second and third items on the list automatically. Unfortunately, these tests still accept many poor passwords. Some versions allow you to optionally impose additional checks. 6.4.3.2.1 Tru64
Tru64 automatically checks that new passwords are not the same as any local username or group name, are not palindromes, and are not recognized by the spell utility (the final test means that the password may not appear in the online dictionary /usr/share/dict/words, nor be a simple transformation, such as a plural form, of a word within it). Triviality checks are imposed if the user's protected password database file contains the u_restrict field, which corresponds to the Triviality checks check box on the Modify Account form. 6.4.3.2.2 AIX
AIX provides a different subset of triviality-checking capabilities via these account attributes (stored in /etc/security/user), which may also be specified using the chuser command:
By default, password triviality checking is not imposed. The dictionlist attribute allows site-specific word lists to be added to the standard online dictionary, and the pwdchecks attribute provides a hook for whatever checking a site deems appropriate, although developing such a module will take time. Here are some sample settings that impose a reasonable set of password content restrictions: minalpha=6 minother=2 maxrepeats=2 mindiff=2 6.4.3.2.3 Linux
Linux systems provide a very simple password obscurity checking facility. It is enabled via the OBSCURE_CHECK_ENAB entry in the /etc/login.defs configuration file. The facility performs some simple checks on its own and then calls the library provided with the Crack password-cracking package (described later in this chapter). The path to the associated dictionary files can be specified with the CRACKLIB_DICTPATH entry in the same file. Note that the obscurity checks do not apply when the superuser changes any password, but you can specify whether root is warned when a specified password would not pass via the PASS_ALWAYS_WARN setting. 6.4.3.2.4 FreeBSD
FreeBSD provides password content controls via user classes; the settings are accordingly specified in /etc/login.conf . These are the most useful:
6.4.3.3 The freely available npasswd command
If you'd like to precheck user passwords but your version of Unix doesn't provide this feature, or if you want to impose more rigorous restrictions on password selection than your system supports, there are freely available programs that you can use for this purpose. For example, the npasswd package (written by Clyde Hoover) is widely available (including all of our systems). It provides a replacement for the normal passwd command that can be configured to check proposed passwords according to a variety of criteria. Looking at npasswd's configuration file, which is /usr/lib/passwd/passwd.conf by default, provides a good sense of the kind of checking it does: # npasswd configuration file # Dictionaries passwd.dictionaries /usr/dict/words passwd.dictionaries /usr/dict/new_words passwd.dictionaries /etc/local_words # Content controls passwd.singlecase no Disallow single-case passwords. passwd.alphaonly no Disallow all alphabetic passwords. passwd.charclasses 2 Minimum number of character types in password. passwd.whitespace yes Allow whitespace characters in passwords. passwd.printableonly no Allow nonprinting characters in passwords. passwd.maxrepeat 2 Only two adjacent characters can be the same. # Minimum password length passwd.minpassword 8 npasswd performs some simple length and character-type tests on a proposed password and then checks it against the words in the dictionaries specified in the configuration file. Checking a proposed password against every login name, group name, and so on, on the system rather than merely against the user's own seems an unambiguous improvement. It is fairly easy to generate a list of such words. The following script performs a basic version of this task: #!/bin/sh # mk_local_words - generate local word list file PATH=/bin:/usr/bin:/usr/ucb; export PATH umask 077# protect against prying eyes rm -f /etc/local_words set `hostname | awk -F. '{print $1,$2,$3,$4,$5,$6,$7}'` while [ $# -gt 0 ]; do echo $1 >> /etc/local_tmp; shift done set `domainname | awk -F. '{print $1,$2,$3,$4,$5,$6,$7}'` while [ $# -gt 0 ]; do echo $1 >> /etc/local_tmp; shift done # usernames, then GECOS names cat /etc/passwd | awk -F: '{print $1}' >> /etc/local_tmp cat /etc/passwd | awk -F: '{print $5}' | \ awk -F, '{print $1}' | \ awk '{print tolower($1)};{print tolower($2)}' | \ grep -v '^$' >> /etc/local_tmp cat /etc/group | awk -F: '{print $1}' >> /etc/local_tmp cat /etc/hosts.equiv >> /etc/local_tmp # add other local stuff to this file (e.g. org name) if [ -f /etc/local_names ]; then chmod 400 /etc/local_names cat /etc/local_names >> /etc/local_tmp fi sort /etc/local_tmp | uniq > /etc/local_words rm -f /etc/local_tmp This version can be easily modified or extended to capture the important words on your system. Note that standard awk does not contain the tolower function, although both nawk and gawk (GNU awk) do. 6.4.3.4 Password history lists
Users tend to dislike creating new passwords almost as much as they dislike having to change them in the first place, so it is a common practice for users to oscillate between the same two passwords. Password history records are designed to prevent this. Some number of previous passwords for each user are remembered by the system and cannot be reselected. The HP-UX, Tru64, and AIX password facilities offer this feature. Note that the password history feature is only effective when it is combined with a minimum password lifetime (otherwise, a user can just keep changing his password until the one he wants falls off the list). Under AIX, the following attributes in /etc/security/user control how and when previous passwords can be reused:
On Tru64 systems, this feature is enabled when the u_pwdepth in a user's protected password database file is nonzero. Its maximum value is 9. It corresponds to the Password History Limit slider on the user account modification screen. The list of old passwords is stored in the u_pwdict field, and items cannot be reselected as long as they remain in the history list. On HP-UX systems, password history settings can be specified on a system-wide basis in the /etc/default/security file, as in this example: PASSWORD_HISTORY_DEPTH=5 Remember 5 passwords. The maximum setting is 10. 6.4.3.5 Password settings default values
Default values forpassword aging settings can be specified on systems using them. These are the default value locations on the systems we are considering:
We've seen examples of most of these already. Here is an example of the Linux defaults file, /etc/login.defs : PASS_MAX_DAYS 90 Must change every 3 months. PASS_MIN_DAYS 3 Keep new password 3 days. PASS_WARN_AGE 7 Warn 7 days before expiration. PASS_MIN_LEN 8 Passwords must be at least 8 chars long. OBSCURE_CHECKS_ENABLE yes Reject very poor passwords. PASS_CHANGE_TRIES 3 Users get 3 tries to pick a valid password. PASS_ALWAYS_WARN yes Warn root of bad passwords (but allow). PASS_MAX_LEN 8 Encode this many password characters. CRACKLIB_DICTPATH /usr/lib/cracklib_dict Path to dictionary files. Note that some of these settings can interact with the PAM facility used on most Linux systems, so they may not operate exactly as described in this section. PAM is discussed later in this chapter. The Solaris /etc/default/passwd file is very similar (although the attribute names are spelled differently): MAXWEEKS=1 Keep new passwords for one week. MINWEEKS=26 Password expires after 6 months. PASSLENGTH=6 Minimum password length. WARNWEEKS=1 Warn user 7 days before expiration. 6.4.4 Testing User Passwords for Weaknesses
As we've noted, having users select effective passwords is one of the best ways to protect system security, and educating them about good selection principles can go a long way in this direction. Sometimes, however, you want to be able to assess how well users are doing at this task. Attempting to discern user passwords using a password-cracking program is one way to go about finding out. In this section, we will consider two such programs, crack and john, beginning with the latter, somewhat simpler facility.
6.4.4.1 John the Ripper
The John package its full name is John the Ripper is an easy-to-use and effective password cracking facility. It is available for all of the Unix systems we are considering. Once installed, the john command is used to test the passwords contained in the password file given as its argument. The package includes the unshadow command, which can be used to create a traditional Unix password file from passwd and shadow files. Here is a simple example of running john: # unshadow /etc/passwd /etc/shadow > /secure/pwdtest # chmod go= /secure/pwdtest # john -rules -wordfile:/usr/dict/many_words /secure/pwdtest The first command creates a password file for testing, and the second command protects it from unauthorized access. The final command initiates a john session (which it starts in the background), in this case checking the passwords against the words in the specified dictionary file and many transformations of these words. As john runs, it periodically writes status information to files in its installation directory (usually /usr/lib/john); the file john.pot holds information about the passwords cracked so far, and the file restore contains information necessary for restarting the current session if it is interrupted (the command to do so is simply john -restore). You can specify an alternate restart filename by including the -session:name option on the john command line, which takes the desired session name as its argument and names the file accordingly. The john facility can operate in several distinct password-cracking modes (requested via distinct options to the john command):
As we noted, John records its progress periodically to its restart file. You can force this information to be written and displayed using commands like these: # kill -HUP pid # john -status guesses: 3 time: 0:00:21:52 68% c/s: 46329 Similarly, the following command reports the last recorded status information for the session named urgent: # john -status:urgent Some aspects of john's functioning are controlled by the facility's configuration file, typically /var/lib/john/john.ini. Here are some sample entries from that file: # John settings [Options] # Wordlist file name, to be used in batch mode Wordfile = /var/lib/john/password.lst # If Y, use idle cycles only Idle = N # Crash recovery file saving delay in seconds Save = 600 # Beep when a password is found (who needs this anyway?) Beep = N Later sections of this file contain rules/specifications of the procedures for each of the cracking modes. 6.4.4.2 Using Crack to find poorly chosen passwords
Crack is a freely available package that attempts to determine Unix passwords using the words in an online dictionary as starting points for generating guesses. The package includes a lot of files and may seem somewhat daunting at first, but it generally builds without problems and is actually quite easy to use. These are the most important parts of its directory structure (all relative to its top-level directory, created when the package is unpacked):
The entire Crack directory tree should be owned by root and should allow no access by anyone but root. Crack also provides a utility to convert the password and shadow password files into a single conventional-style file suitable for use by the program; it is named shadowmrg.sv and is stored in the scripts subdirectory. It takes the two filenames as its arguments and writes the merged file to standard output. Here is an example invocation of Crack: # Crack -nice 5 /secure/pwdtest The script builds the compressed dictionary files, if necessary, and then starts the password cracker program in the background. While Crack is running, you can use the Reporter script to check on its progress (located in the same directory as the Crack script). In this case, Crack runs at lower priority than normal jobs due to the inclusion of -nice. If you want to stop a Crack run in progress, run the plaster script in the scripts subdirectory. Eventually or quickly, depending on the speed of your CPU and the length of the dictionary files Crack produces output like the following (in the file Dhost.pid where host is the hostname and pid is the process ID of the main Crack process): I:968296152:OpenDictStream: status: /ok/ stat=1 look=679 find=679 genset='conf/rules.basic' rule='!?Xc' dgrp='1' prog='smartcat run/dict/1.*' O:968296152:679 I:968296155:LoadDictionary: loaded 130614 words into memory G:968296209:KHcqrOsvoY80o:Arcana The general procedure Crack uses is illustrated by this output. It opens each dictionary file in turn and then applies each rule from the various collection of rules files in the run subdirectory to the words in it, using each transformed word as a guess for every remaining uncracked user password. When it finds a match, it displays the cracked and encoded versions of the password in the output; in this example, the password "Arcana" has just been cracked. Once a rule has been applied to every dictionary word and every password, Crack continues on to the next rule, and eventually on to the next dictionary, until all possibilities have been exhausted or all passwords have been cracked. Rules specify transformations to apply to a dictionary word and are written using a metalanguage unique to Crack. Here are some example entries illustrating some of its features:
The installed rules files contain several important types of transformations, and they can be extended and customized as desired. Once a Crack run has completed, it is important to remove any remaining scratch files, because they may contain clear-text passwords. Running the command make tidy is one way to do so. You will also want to copy the D* results files and run/F-merged file to offline storage and then delete the online copies (restoring the latter the next time you want to run Crack). NOTE There are several large dictionary files available on the Internet (for example, see ftp://ftp.ox.ac.uk/pub/wordlists). Using them to augment the standard Unix dictionary (and any package-provided ones) will make any password cracking program more successful (but it will also take longer to complete). 6.4.4.3 How well do they do?
We ran Crack and John on a password file containing several poorly chosen passwords. Table 6-11 shows the results we obtained with the standard program options and configurations, using only the standard Unix dictionary with the words "arcana" and "vermillion" added.
Both of them cracked passwords with simple transformations, but not with special characters or the addition of two numerals. However, adding rules to either facility to handle these cases is very easy. |