Skip to main content

sFTP Tips

What you need to know for easy and secure file transfers.

A padlock and key are straddling a handful of credit cards

I’m pretty handy using sFTP. I’ve configured sFTP several times on IBM i and am able to securely send and receive (put and get) data from the i to a remote system. And I’m talking Secure File Transfer Protocol (or SSH File Transfer Protocol), not FTP through Secure Sockets Layer or SSL FTP. sFTP is the widely used protocol for transferring information securely—especially with financial institutions like banks and credit-card companies. Note that sFTP runs under the Portable Application Solutions Environment (PASE), the UNIX runtime within i. Licensed program 5733-SC1 (Portable Utilities for i) contains OpenSSH, the open-source implementation of Secure Shell. You also need i Option 33–PASE to be installed on your system.

I usually follow the same general steps when configuring sFTP to be used in a batch process. These steps are to configure sFTP without a password. Most financial institutions I’ve worked with have used this method. You can use sFTP with a password, but you’d need something like a TCP expect script, which makes the process more complicated.

sFTP uses public-key encryption, meaning each side (your system and the remote system) will create a public encryption key and send it to the other. Each side can then encrypt information with the partner’s public key. I’ll show a basic sFTP setup, and discuss a few potential problems and how to avoid them.

sFTP Configuration Basics

First, sign on as the user that will perform the batch sFTP; I’ll use SFTPUSER in this example. Start configuring sFTP by issuing CALL QP2TERM to start an i PASE session, which provides a PASE command line. Perform the following steps by entering commands on the command line:

1. Create a /home directory for the user that will be running sFTP (the user the batch process runs under). If the user already has a /home directory, you can skip this step. If not, use command mkdir home/SFTPUSER, where SFTPUSER is the specified user.

Ensure the permissions are set correctly on the /home directory. This is one of the gotchas with sFTP. If these permissions are incorrect, sFTP won’t work and it’s difficult to find the cause. Issue the change mode (chmod) command to set the /home directory’s permissions:

chmod 755 /home/SFTPUSER

2. Generate the public and private encryption keys using the ssh-keygen command:

ssh-keygen -t dsa -N ""

You’ll be prompted for the file name; just press “Enter” for the default file name. This command will create the .ssh subdirectory and generate the public and private encryption keys in the /home/SFTPUSER/.ssh directory. You’ll have files id_dsa (the private key) and (the public key).

3. Send the public key to your communications partner. This can be done via e-mail or FTP. Your communications partner will take your public key and place in its .ssh folder, and add your host name to its known_hosts file.

4. If your partner has its own key (which is likely), you’ll use it for the transfer. Get it with this command, where your partner’s name is

ssh-keyscan -t >> ~/.ssh/known_hosts

This adds your partner’s public key to your known_hosts file and enables secure communications between the systems.

Using sFTP

Once sFTP has been configured on both sides, use it to put and get files securely. Note that we specified SFTPUSER as the user that will perform the transfers between your system and your partner’s system. This is because the SFTPUSER home directory contains the encryption key information. You’ll probably use a different user profile (one assigned by your partner) as the sFTP login user. This is another potential issue. One of the issues I’ve faced with sFTP (though not often) is that the communications partner requires specific case in the user name. I’ve encountered this when communicating via sFTP to a mainframe. The mainframe sFTP implementation required uppercase user names. User-name case usually doesn’t matter, but when it does, it can take a while to discover the problem. Luckily, the solution is simple—use the case that your partner requires.

We’ll use user profile RMTUSER for the sFTP login user profile in this example.

Again entering the CALL QP2TERM command to invoke a PASE shell, use this command to start the sFTP session:


This command provides a command line where you can put and get files, mput and mget multiple files, get directory listings with the ls command and perform other sFTP tasks. Enter “exit” at the sFTP prompt to exit sFTP.

OpenSSH vs. SSH2

Differences between the major sFTP programs can complicate sFTP processing. IBM i uses OpenSSH. Other systems (notably UNIX and Linux systems) use SSH2. The two keys are incompatible, but that’s easy to fix. If the communications partner’s public key (when viewed with DSPF or through WRKLNK) begins like this:

<many random characters>

Then that public key is in SSH2 format and must be converted to Open SSH format. You may also need to convert your OpenSSH public key format to SSH2. You can convert key formats with the ssh-keygen command:

ssh-keygen -i -f SSH2_format_file > OpenSSH_format_file>

Convert from OpenSSH format to SSH2 format with this command:

ssh-keygen -e -f OpenSSH_format_file > SSH2_format_file

The public key file after a conversion will have a comment line inserted to show the conversion. For example:

Comment: "1024-bit RSA, converted from OpenSSH by sftpuser@MYLOCALSYSTEM.COM"

The OpenSSH/SSH2 issue doesn’t seem to be as much of a problem as it used to be. However, different partners have different versions of SSH2, so be aware.

sFTP in Batch

You can also invoke sFTP in batch with the -b (for batch) parameter. I’ll use a script file that contains commands such as get or put. For example:

put /settle/workfile.txt /incoming/workfile.txt

This script file will send the /settle/workfile.txt file in the IFS to the remote system as file /incoming/workfile.txt, and then exit sFTP. You can invoke the script file in several ways—I use QSH (the QShell environment) and specify the sftp command directly:

QSH CMD('/QOpenSys/usr/bin/sftp -b /Script/put_script.txt')

Verbose Debugging

Sometimes the best of plans don’t do what we planned. A helpful technique to see what exactly is being generated is the -v (or -vv or -vvv) parameter. The number of v’s determine the amount of logging information that will be provided. Using the sFTP command above, we could change it to:

sftp -vvv -b /Script/put_script.txt

Or, in batch as:

QSH CMD('/QOpenSys/usr/bin/sftp -vvv -b /Script/put_script.txt > /logs/put_logoutput.txt 2>&1')

In the interactive example, the verbose debugging output will be displayed on the screen. In the batch example, the output will be placed in file /logs/put_logoutput.txt. In either case, the output will look something like this:

Connecting to
OpenSSH_3.5p1, SSH protocols 1.5/2.0, OpenSSL 0.9.7d 17 Mar 2004
debug1: Reading configuration data /QOpenSys/QIBM/ProdData/SC1/OpenSSH/openssh-3
debug3: Seeding PRNG from /QOpenSys/QIBM/ProdData/SC1/OpenSSH/openssh-3.5p1/libe
debug1: Rhosts Authentication disabled, originating port will not be trusted.
debug1: ssh_connect: needpriv 0
debug1: Connecting to [] port 22.
debug1: Connection established.
debug1: identity file /home/ SFTPUSER/.ssh/id_dsa type -1
debug3: Not a RSA1 key file /home/SFTPUSER/.ssh/id_dsa.
debug2: key_type_from_name: unknown key type '-----BEGIN'
debug3: key_read: no key found
debug3: key_read: no space
debug3: key_read: no space

sFTP output information isn’t necessarily easy to read, but it contains all of the information (including the sFTP commands) shown during an sFTP session. I usually specify the -vvv debugging level to gather all the information I can. I may not need it, but it’s there if I do. It’s especially helpful when first establishing an sFTP connection.

sFTP Return Code

Using sFTP in QShell is handy. You can run the sFTP commands in batch easily, and use script files and logging output. However, you may want to include the QSH command in a CL program as part of a job stream. If you do, you probably need to know if sFTP completed successfully. You could examine the verbose debugging log, but that would be time consuming and difficult to automate.

However, sFTP can return a return code when the sFTP command is completed. I believe this capability is part of i 6.1, and PTFs in version V5R3 (SI25208) and V5R4 (SI25209) for 5733-SC1 provide this capability. It’s easy to use the return code capability. Here’s a short CL program to demonstrate:


QSH CMD('/QOpenSys/usr/bin/sftp  -vvv -b /Script/put_script.txt > /logs/put_logoutput.txt 2>&1')


  /* Error processing */

This program checks the return code after the sFTP command executed. If the return code is anything except zero, an error occurred.

sFTP Basics and Tips

There’s much more to sFTP, but I hope you can use this as a start for sFTP processing. Remember these items:

  • Permissions on the home directory
  • Case of the user name
  • OpenSSH vs. SSH2
  • Verbose debugging
  • Running sFTP in batch
  • Executing sFTP from QShell
  • Return codes

sFTP is a valuable tool being used by financial institutions and other communications partners. While some potential problems exist, sFTP is easy to configure and use.

IBM Systems Webinar Icon

View upcoming and on-demand (IBM Z, IBM i, AIX, Power Systems) webinars.
Register now →