This page describes how to setup SafeTP and Kerberos so they can share the same port (e.g. port 21, the usual FTP server port).
Kerberos (http://web.mit.edu/kerberos/www/) is a security system with some goals in common with SafeTP, and others not in common. The drawback to Kerberos is that Kerberos requires acquisition of "tickets", which is typically not convenient under operating systems other than unix. The advantage of Kerberos is its much wider scope -- SafeTP only secures FTP connections, whereas Kerberos has secure telnet, among other things. But once in use, SafeTP and Kerberos offer comparable security, and so it is reasonable to run them together.
The basic approach is for the SafeTP server (sftpd) to recognize that an incoming connection is intended for Kerberos' ftpd (hereafter: kftpd), and hand the connection to kftpd for processing.
Ideally, sftpd could simply relay data between the client and kftpd, similarly to how it operates with the default ftpd. However, Kerberos' FTP protocol includes port checks that preclude this. Therefore, the solution adopted is to exec(2) kftpd in place of sftpd, thereby inheriting sftpd's sockets (and ports).
This requires a patch to kftpd, to synchronize the client and server protocol streams. sftpd then needs to be told where to find this patched binary.
Note: The patch described was created as a diff from Kerberos version 5, sub-version 1.0.6, and is not (yet) known to work with other releases. If you find you need to use another version, let me (scott) know.
In your Kerberos v5 distribution, kftpd is in src/appl/gssftp/ftpd. Locate this directory, and verify ftpd.c is in it. You should already have built the distribution once (i.e., an ftpd binary should be in the directory). If not, do so now -- this will ensure the Makefiles etc. are in working order before we start mucking with things.
Apply this patch. Save it to a file (right-click, save link as...). Then feed it to patch(1) like this:
shell-prompt$ patch < kerb-patch.txt(do this in the ftpd directory).
If the patch worked, you ought to be able to rebuild (k)ftpd:
shell-prompt$ makeWith luck you now have a kftpd binary (called
ftpd
) that understands the -S switch.
Follow the usual instructions (install.txt) for installing SafeTP. Install it onto port 21 (or wherever you want it), supplanting whatever was listening to 21 (including kftpd).
Copy the newly-created kftpd binary to someplace where sftpd will be able to execute it. Since you'll be making kftpd setuid-root, the most prudent option is to create a special directory inside safetp's directory. E.g.:
shell-prompt# cd /home/safetp shell-prompt# mkdir kerb shell-prompt# chown safetp.daemon kerb shell-prompt# chmod 700 kerb shell-prompt# cd kerb shell-prompt# cp /WHEREVER/krb5/src/appl/gssftp/ftpd/ftpd ./kftpd shell-prompt# chown root.root kftpd shell-prompt# chmod 4755 kftpd shell-prompt# ls -ld . kftpd drwx------ 2 safetp daemon 1024 Nov 11 04:25 ./ -rwsr-xr-x 1 root root 607910 Nov 11 04:25 kftpd*
This makes the modified (and setuid-root) kftpd available only to the safetp user. I'm not aware of any problems with a generally-available setuid-root kftpd, but why take chances?
Now we need to tell sftpd where to find kftpd. Find the line of /etc/inetd.conf which looks like this:
safetp stream tcp nowait safetp /home/safetp/sftpd sftpd -f351 -s -y/home/safetpand add the -K switch, specifying the location of the modified kftpd as its argument (this is all one line, if your browser wraps it):
safetp stream tcp nowait safetp /home/safetp/sftpd sftpd -f351 -s -y/home/safetp -K/home/safetp/kerb/kftpd
Save the file, and send the HUP signal to inetd:
shell-prompt# killall -HUP inetd
killall
works under Linux; it might not on your system.
See kill(1).
shell-prompt$ ftp myhost Connected to myhost.mydomain.org. 220-myhost.mydomain.org FTP server (Version wu-2.4.2-VR16(1) Sun May 9 20:10:03 CDT 1999) ready. 220-*** This server can accept secure (encrypted) connections. *** 220 *** See http://www.cs.berkeley.edu/~smcpeak/SafeTP for info. *** 334 Ah, you want Kerberos. I'll go get him (it?)... (send security data) GSSAPI accepted as authentication type GSSAPI authentication succeeded Name (myhost:scott): 232 GSSAPI user scott@MYHOST.MYREALM.ORG is authorized as scott 230 User scott logged in. Remote system type is UNIX. Using binary mode to transfer files. ftp>
Also test with sftpc to verify the SafeTP side is still working.
If all goes well, you're done! Users should be able to connect to your server and see both SafeTP or Kerberos, depending on which client software they're using.
First off, try specifying the -d switch to all the relevant
software: Kerberos' ftp, SafeTP daemon (sftpd), Kerberos' ftpd. (The
last one is tricky because kftpd's arguments are hard-coded in sftpd's
source... so leave it for last. It's in sftpd.cpp; grep for 'execl'.)
Inetd can be unfriendly to work with when debugging; the SafeTP
distribution includes an inetd stand-in called myinetd (make
myinetd
) which can be used instead. Run it without args
for a quick usage summary.
Be sure to pay attention to the logs.. (/var/log/*, typically --
/etc/syslog.conf says exactly where).
As always, isolation is the key. Does the problem persist when
sftpd is removed from the equation?
Kftpd can be tricky to get working, even before you add sftpd to
the mix. Remember to use kadmin to addprinc
ftp/your.host
and ktadd ftp/your.host
(forgot what
that does, but it's necessary). Also, I couldn't get it to work going
to 'localhost' -- use the machine's real name.
If you already had Kerberos installed, and are installing SafeTP afterwards, be sure kerberos' ftpd is not started from inetd (or at least not on the same port that sftpd listens to).
kftpd has a bug: it looks for GSSAPI with case-sensitivity, whereas RFC 2228 specifically specifies case-insensitivity. This is a minor point, but I don't have another good place to make note of this..