The problem
A certain web application requires sftp access to a storage server to use it as external storage. This means that the login credentials (password or private key) will have to be stored on application server, which poses a secrutiy risk for the storage server. If the application server is breached, these credentials will allow unwanted access to the storage server, if the sftp account is not properly restricted.
The solution
In short, the remote sftp access need to be securely setup with the following restrictions:
-
sftp access only, no ssh access (= no login shell)
-
access limited to IP(s) of application server only
-
sftp access to chroot jail only, where read and write are allowed; no read or write accees to any other files or folders
-
all sftp accesses and operations are fully logged
This way, it will be guaranteed that should the application server be compromised, no extra access or attack surface will be gained on the storage server.
The following steps applies to Debian/Ubuntu, but should not differ much in other distributions.
1. Set up user account
Add a dedicated group and user for the remote access:
sudo adduser --group --system --shell /bin/false --no-create-home remote-sftp
The --group
switch creates a group with the same name ('remote-sftp'), --system
switch avoids asking for user info, --shell
switch denies shell access, and --no-create-home
avoids creating unused home directory for this user.
Use passwd remote-sftp
to set up password for this user, which will also be used for sftp access. If key-based authentication will be used for sftp access, password can be omitted.
Create the folder where remote-sftp will be reading and writing files:
sudo mkdir -p /path/to/remote-sftp-storage/storage
sudo chown remote-sftp:remote-sftp /path/to/remote-sftp-storage/storage
/path/to/remote-sftp-storage/
will be the chroot jail and /path/to/remote-sftp-storage/storage
will be the actual place where remote reads and writes are made. Make absolutely sure that "all components of the pathname are root-owned directories which are not writable by any other user or group" [1], meaning that /path
, /path/to
, and /path/to/remote-sftp-storage
must be root-owned and non-writable by others, or in other words with permission 0755
.
2. Set up openssh-server
Open /etc/ssh/sshd_config
and add the following lines to the end:
Match User remote-sftp, Address !1.2.3.4
PasswordAuthentication no
PubkeyAuthentication no
Match User remote-sftp, Address 1.2.3.4
ChrootDirectory /path/to/remote-sftp-storage
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp -l VERBOSE -f LOCAL0
Replace 1.2.3.4
with the application server's outgoing IP address. The Match directive dictates that following configurations only apply if the matching conditions are all met. The first one blocks ssh/sftp access from anywhere that is not the application server. The second one restricts access from application server to a chroot jail in /path/to/remote-sftp-storage, no X11 or TCP forwarding, and sftp only. The -l and -f parameters to internal-sftp command dictate logging level and logging facility, respectively [2]. This, however, does only half the job. The next step is required for the log messages to be recorded.
(Note: Other common hardening measures for ssh are still required, but not covered here.)
Restart ssh server for the modified sshd_config to take effect:
systemctl restart ssh
3. Set up rsyslog
Save the following as /etc/rsyslog.d/99-remote-sftp.conf
:
local0.* /var/log/remote-sftp-storage.log
$AddUnixListenSocket /path/to/remote-sftp-storage/dev/log
The first line matches the -f LOCAL0
parameter in sshd_config and directs rsyslog where to save the log messages. The second line tells rsyslog where to listen for logging requests, and to make this work, /path/to/remote-sftp-storage/dev
folder must exist [1]:
sudo mkdir /path/to/remote-sftp-storage/dev
Finally, restart rsyslog:
sudo systemctl restart rsyslog
References
[1] man sshd_config
[2] man sftp-server
Comments
comments powered by Disqus