ONLamp.com    
 Published on ONLamp.com (http://www.onlamp.com/)
 See this if you're having trouble printing code examples


FreeBSD Basics Improving User Passwords with apg

by Dru Lavigne
10/30/2003

A few years back, I wrote about password policies and using a dictionary cracker to monitor compliance to a network's password policy. In today's article, I'll demonstrate an application from the ports collection that can assist users in choosing complex yet memorable passwords.

The apg, or automatic password generator, intrigued me, since it supports the pwdgen protocol, defined by RFC 972. Yes, I know I need to get out more often, but I find it interesting that this protocol has been available since 1986, yet most people have never heard of it or had the opportunity to use it in a network.

Let's install this application and see how useful it is:

% cd /usr/ports/security/apg
% make install clean

The port will actually install three utilities: the apg client, the apgd server, and the Bloom filter manager, apgbfm. Each utility has an associated manpage, all chock-full of examples and useful URLs for additional reading.

One of those URLs leads to NIST, the National Institute of Standards and Technology. NIST is known for its security best practices or FIPS (Federal Information Processing Standards). The other URL that is worth checking out explains that Bloom filter.

In its simplest use, apg will generate six random passwords, in the hopes that one of them will appeal to you as a password choice. The passwords will be complex, meaning they won't be found by a dictionary cracker. To help make the passwords memorable, include the t switch, which will show you how to pronounce the generated passwords. Here's an example:

$ apg -t

UlmIrrors1 (Ulm-Irr-ors-ONE)
ziadrotAw (zia-drot-Aw)
FoacodCurt (Foac-od-Curt)
wroztAm1 (wrozt-Am-ONE)
HeudIfpyd9 (Heud-If-pyd-NINE)
BeshDaftem (Besh-Daft-em)

By default, apg creates passwords of eight to 10 alphanumeric characters, using both upper and lower case. However, you can use additional switches to conform to any password policy. For example, to force the inclusion of symbols:

$ apg -MS -t

loce>fruo (loc-e-GREATER_THAN-fruo)
afmisbol: (af-mis-bol-COLON)
pamob(ocon (pam-ob-LEFT_PARENTHESIS-oc-on)
swotbuad# (swot-bu-ad-CROSSHATCH)
naynalwak) (nayn-al-wak-RIGHT_PARENTHESIS)
cravser- (crav-ser-HYPHEN)

To ensure that each password is 14 characters long, specify 14 as both the minimum (-m) and maximum (-x) length:

$ apg -MS -m14 -x14 -t

If your password policy insists on truly random passwords that aren't pronounceable, use -a1 instead of -MS:

$ apg -a1 -m14 -x14

V/u|X@/qO%y;`r
ux:S};"JRCf]I8
LLV5lb!WY5qH!9
-vUY&x6Lj+:IO^
m(X2R.I`C2["Mi
jO%H3w1ZMRnZTj

Hmmm. I think I'd better stick with the pronouncable passwords.

apg also supports the ability to check the randomly generated passwords against either a dictionary file or a Bloom filter file. If it happens to create a random password that is found in either file, it will scrap it and generate another password.

Your FreeBSD system comes with the dictionary file /usr/share/dicts/words. If this file isn't on your particular system, you can install it by going into /stand/sysinstall, choosing configure and then distributions, and selecting dict. This file is alphabetical and in ASCII text, meaning you can add your own words. It's common to add words like:

R00t
r00t
r00T

and so on, since the words are case-sensitive. It is recommended that you spend some time adding the words you don't want showing up as passwords in your network. Once you're finished, configure apg to double-check against your dictionary file by using the -r switch and specifying the name of the file:

$ apg -MS -m14 -x14 -t -r /usr/share/dict/words

Also in FreeBSD Basics:

Fun with Xorg

Sharing Internet Connections

Building a Desktop Firewall

Using DesktopBSD

Using PC-BSD

Even better, take the time to create a Bloom file. This will require you to specify both the name of the dictionary and the desired name of the generated Bloom file:

$ apgbfm -d /usr/share/dict/words -f ~/bloomfile
Counting words in dictionary. Please wait...

This command can be run as a regular user. In this instance, I chose to create the Bloom file in my home directory. Once the file is generated, use the -b switch to tell apg where the Bloom file is located:

$ apg -MS -m14 -x14 -t -b ~/bloom

If you try both the -r switch and the -b switch with apg, you'll find that the Bloom file is much quicker, as it uses an algorithm to determine whether or not the password would be found in the dictionary file.

The last switch I'll mention is the -s, or seed, switch. This switch is recommended, as it gives the random number generator a seed to work with:

$ apg -MS -m14 -x14 -t -b ~/bloom -s
Please enter some random data (only first eight are significant)
(eg. your old password):>

jasvafwabvoud, (jas-vaf-wab-voud-COMMA)
rhylpoj:oruch~ (rhylp-oj-COLON-or-uch-TILDE)
dibogcewbowug{ (dib-og-cewb-ow-ug-LEFT_BRACE)
abun`frelfoksi (ab-un-GRAVE-frelf-oks-i)
dircunittanas" (dirc-un-itt-an-as-QUOTATION_MARK)
rhaph"drockeet (rhaph-QUOTATION_MARK-droc-keet)

Notice that these passwords are quite complicated, but still fairly pronouncable.

For those of you who prefer GUI-based utilities, the apg author has also released the tkAPG front end. There isn't a port for this utility, but it is easy enough to install on your FreeBSD system. Grab the source. Once you've downloaded the file, untar it and cd to the newly created directory:

$ tar xzvf tkapg-0.0.2a.tar.gz
$ cd tkapg-0.0.2a

This directory contains a README and a script file called tkapg. Open the script in your favorite editor, and change this line:

exec wish "$0" "$@"

to:

exec /usr/local/bin/wish8.3 "$0" "$@"

Once you've saved the changes, go to an X Window session, open an xterm, cd into the tkapg-0.0.2a directory, and type:

$ ./tkapg

A little GUI will pop up, allowing you to generate random passwords. I found the GUI to be a bit slower than the command line. It also didn't offer each switch possibility. However, take the time to check it out, as it may meet your password generation needs.

If you decide to stick with the command line, you may want to create a shell script so you don't have to remember to type in all of your options. Here, I've modified the suggestion from man apg to include my desired options:

$ vi ~dlavigne6/bin/pwgen.sh
#!/bin/sh
apg -MS -m14 -x14 -t -b /usr/home/dlavigne6/bloom -s

Once I save this file, I need to make it executable:

$ chmod +x ~dlavigne6/bin/pwgen.sh

When I want to generate random passwords, I simply type:

$ pwgen.sh

If you want to test your script right away and you use the C shell, type rehash so it will find your new executable.

Another alternative is to create an alias. Since I only plan on using apg from one machine and I'm always in the C shell, I added this line to ~/.cshrc:

$ alias apg /usr/local/bin/apg -MS -m14 -x14 -t \
	-b /usr/home/dlavigne6/bloom -s

Now, whenever I type apg, it automagically uses all of my desired switches. Again, if you want to test your alias right away, tell the C shell to reread its configuration file:

$ source ~dlavigne6/.cshrc

Up to this point, we've concentrated on the apg client, meaning we haven't actually used the pwdgen protocol yet. Like any TCP/IP protocol, pwdgen requires both a client component and a server component. The job of the server component is to listen for client requests on its well-known port. To determine what port that is:

$ grep pwdgen /etc/services 
pwdgen		129/tcp	   #Password Generator Protocol
pwdgen		129/udp	   #Password Generator Protocol

This service is started by the inetd daemon, meaning you'll need to edit /etc/inetd.conf as the superuser so that it includes this line:

pwdgen	stream	tcp	nowait	root	/usr/local/sbin/apgd	apgd

Once you've saved your change, simply type inetd to start the service. Alternatively, if you already have inetd listening for other services, inform it of your changes by typing:

% killall -1 inetd

This command should show inetd listening on TCP port 129:

% sockstat -4
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      
root     inetd      92412 4  tcp4   *:129                 *:*

The advantage of using apgd is that you don't have to install the apg port on each user's computer. As users need to generate random passwords, they simply connect to port 129 on the apgd server. In this example, apgd is running on a server with an IP address of 10.0.0.1:

$ telnet 10.0.0.1 129
Trying 10.0.0.1...
Connected to 10.0.0.1.
Escape character is '^]'.
AilEjmacGa
yotgakki
DrehojOird
yejBabif
albEifia
jolnapt6
Connection closed by foreign host.

Notice a few things here. One, don't panic over the telnet word. The insecure telnet service isn't running on 10.0.0.1. Instead, I've used the telnet client to make a direct connection to the pwdgen port of 129. In essence, telnet is acting as the apg client.

Second, using this method, the user has no control over the options used by apg, as they are pre-configured on the server. Depending upon your security policy, this may be seen as a bonus, as users won't be able to generate non-compliant passwords.

Let's take a closer look at that generated output. Remember, when I added my line to /etc/inetd.conf, I didn't include any switches to apgd. This means that I received the default of eight to 10 alphanumeric characters with no symbols. Also note the lack of the pronunciation guide, since I didn't include -t in my inetd entry.

I should probably change that entry to include the switches applicable to my network's password policy:

pwdgen	stream	tcp	nowait	root	/usr/local/sbin/apgd	\ 
	apgd -MS -m14 -x14 -t -b /usr/local/etc/bloom

Notice that that is now one very long line (wrapped for the sake of this article). Make sure you don't use an editor that tries to turn it into two lines. I've also created a Bloom file in a directory that is accessible to all users, rather than in one particular user's home directory. Notice also the lack of the -s switch; unfortunately, this option is not available with apgd.

Finally, I also have to remember to inform inetd of the changes:

% killall -1 inetd

Now, when a user connects to the apgd server:

$ telnet 10.0.0.1 129
Trying 10.0.0.1...
Connected to 10.0.0.1.
Escape character is '^]'.
yeog-flaysdok: (ye-og-HYPHEN-flays-dok-COLON)
caijpyfratcef| (caij-py-frat-cef-VERTICAL_BAR)
ajyafdiwubaig] (aj-yaf-di-wub-aig-RIGHT_BRACKET)
nohoktegrogib( (no-hok-te-grog-ib-LEFT_PARENTHESIS)
nobkarcyonnip= (nob-karc-yonn-ip-EQUAL_SIGN)
hirkadlarjiaf[ (hirk-ad-larj-iaf-LEFT_BRACKET)
Connection closed by foreign host.

If you decide to use the apgd server, you can also modify /etc/syslog.conf so it will keep track of when users use this service. Let's see what happens if I add these lines to the bottom of /etc/syslog.conf:

!apgd
*.info				/var/log/apgd.log

To inform syslog of these changes:

% killall -1 syslogd
Oct 19 12:40:36  syslogd: /var/log/apgd.log: No such file or directory

Oops. I forgot to make that log file:

% touch /var/log/apgd.log
% killall -1 syslogd

Next, I'll test the results by connecting to the apgd:

$ telnet localhost 129
<output snipped>

and then checking out the entry in the log:

% more /var/log/apgd.log
Oct 19 12:43:01 genisis apgd[92692]:
	password generation request from 127.0.0.1.49334

While not the most descriptive log entry, I do have a record of which IP address, in this case the localhost, used the pwdgen protocol and at what time.

This should get you started on generating random passwords. If you plan on trying this on your own system or in a very small network, you may prefer to install the apg port on each computer. For a larger network, install and configure apgd on one of your servers and instruct your users how to connect to port 129.

In the next article, I'll take a look at the science of steganography and some proof-of-concept utilities in the ports collection.

Dru Lavigne is a network and systems administrator, IT instructor, author and international speaker. She has over a decade of experience administering and teaching Netware, Microsoft, Cisco, Checkpoint, SCO, Solaris, Linux, and BSD systems. A prolific author, she pens the popular FreeBSD Basics column for O'Reilly and is author of BSD Hacks and The Best of FreeBSD Basics.

Copyright © 2009 O'Reilly Media, Inc.