Hi guys,
In this post, we will explore how to securely publish an internal SFTP server on the internet using Haproxy. In the example, we will restrict access to only a specific external IP, thereby enhancing security.


Let’s configure the internal backend system.

An example of my SSH configuration  (edit the file  /etc/ssh/sshd_config )

ChrootDirectory none
 # override default of no subsystems
 #Subsystem      sftp    /usr/libexec/openssh/sftp-server
 Subsystem       sftp    internal-sftp
# All users of our internal LAN can try to access, only the user "puppet" can try to access from (our HAPROXY server)
AllowUsers *@192.168.0*
AllowUsers puppet@

# Example of overriding settings on a per-user basis
# Match User anoncvs
#       X11Forwarding no
#       AllowTcpForwarding no
#       ForceCommand cvs server
Match User puppet
ChrootDirectory /home/puppet
ForceCommand internal-sftp

As you can see we have put the user puppet in a chroot jail. In this way the user cannot navigate freely into the file-system.

Remember to:
1. configure correctly the permission for /home/puppet.  Since is a chroot jail must have these permissions:
drwxr—– 5 root root 4096 Aug 28 2013 puppet
the owner must be root
Inside /home/puppet we will create folders owned by puppet.

2. Disable a login shell for the user puppet. In this way he will be able only to upload and download files but not to use a terminal

[root@myfileserver home]# cat /etc/passwd | grep puppet

Ok, now the Haproxy configuration. We need only a LISTEN and a BACKEND sections:

listen sftp-server
  bind :2121
  mode tcp
  acl white_list src
  tcp-request content accept if white_list
  tcp-request content reject
  default_backend sftp-server01
backend sftp-server01
  mode tcp
  server ftp01 myfileserver.foo.org:22 check port 22

Breakdown of some parameters.

bind :2121 # HAPROXY will listen on port 2121
mode tcp #set TCP protocol
acl white_list src #define an ACL.Is like an array of IP addresses
tcp-request content accept if white_list #the function “tcp-request content accept” will run only if whit_list is TRUE. So, only and can ask to access to the backend
tcp-request content reject #the others IPs are not allowed
default_backend sftp-server01 #redirect the call to the sftp backend

Let’s assume that you external haproxy is known as noodles.foo.org by the DNS.
In order to connect to the SFTP, open a client ( like FileZilla ) and point to:

SFTP://noodles.foo.org:2121 username:puppet password:puppet.123