En la siguiente entrada vamos a ver como montar una arquitectura de SFTP en Azure en alta disponibilidad.
Este tutorial no veremos en detalle como desplegar un servidor en azure, ni una vnet…etc por lo tanto se pasará un poco por encima en la creación de estos recursos.
Escenario
Para garantizar la alta disponibilidad del servicio disponemos de dos servidores GNU/Linux en diferentes zonas de disponibilidad.
Dicha alta disponibilidad cuenta con balanceo de carga entre los diferentes servidores mediante Azure Load Balancer, de la misma forma, para otorgar persistencia de los datos transferidos contamos con almacenamiento compartido entre los dos servidores empleando Azure File share
Para montar los recursos compartidos de Azure FIle Share se realizará mediante autofs, de esta forma garantizamos que los recursos únicamente se monten cuando sean necesarios.
Diagrama de red
En primer lugar tenemos que crear una Vnet
Configuramos un Resource Group y un nombre para la Vnet
Configuramos el rango de ip que creamos
A continuación en el apartado de Security y tag lo debemos por defecto (a no ser que nosotros queramos configurar algo extra) y presionamos a crear
Tras crear la VNet desplegamos los servidores GNU/Linux, en mi caso no voy a poner los pasos de como desplegar un nuevo servidor para más información sobre esto podemos ver el siguiente link o otros de los muchos recursos que te puedes encontrar en internet. de la misma forma, puedes obtener información sobre los availability set
Sin mas preámbulos, muestro mi configuración de availability set
Una vez desplegado los servidores tenemos que desplegar el Load Balancer, para ello nos vamos a Load Balancer y presionamos en Crear
Configurar Load Balancer
Lo primero que tenemos que configurar es el grupo de recursos, el nombre de load balancer, región y que tipo de load balancer queremos, en nuestro caso dado que va a estar publicado a internet seleccionaremos Public
Configuramos el direccionamiento publico
Creamos un pool agregando los dos servidores desplegados anteriormente
Establecemos el chequeo health al puerto 22
Configuramos en Load balancer, en mi caso voy como podemos ver en la siguiente imagen, establecemos el puerto 2222 en escucha en el load balancer y esté lo redirigirá al puerto 22 del pool creado anteriormente
Establecemos las reglas de Inbound
Por ultimo establecemos las reglas de Outbound
Nos dirigimos al NSG de los servidores y creamos la siguiente regla, no se recomienda bajo ningún concepto tener el puerto del SSH expuesto a internet, pero si por necesidad de negocio no se puede disponer de una VPN o se puede realizar un filtrado de direcciones…
Configuración Storage Account
Una vez creado el Load Balancer nos dirigimos al Storage Account y presionamos en Create
Tras complementar todos los datos que nos pide y crear el Storage Account nos vamos a File Share y creamos un recurso compartido. Una vez creado el recurso, accedemos a el y presionamos conectar.
Copiamos las credenciales para configurarlas en nuestros servidores GNU/Linux
A continuación vamos a configurar el servicio de SFTP en nuestros servidores, por lo tanto todos estos pasos se tendrán que realizar en ambos nodos.
Accedemos mediante SSH a nuestros servidores GNU/Linux y creamos las carpetas en donde se va almacenar el archivo que contiene las claves de acceso al recurso compartido.
mkdir /root/smbcredentials/
Configuramos el usuario y la contraseña que hemos obtenido anteriormente.
cat /root/smbcredentials/sftppro.cred
username=sftp
password=paSsSSsw0rd===
Asignamos los permisos correctamente
chown root:root /root/smbcredentials/sftppro.cred
chmod 600 /root/smbcredentials/sftppro.cred
Creación de usuario de SFTP
groupadd sftp
useradd -g sftp -s /bin/false -d /sftp/sftpuser sftpuser
passwd sftpuser
creamos el home del usuario y otorgamos los permisos
mkdir -p /sftp/sftpuser
chmod 755 /sftp/sftpuser
chown root:root /sftp/sftpuser
Accedemos al /etc/ssh/sshd_config y debemos modificar la siguiente linea:
Subsystem sftp /usr/lib/openssh/sftp-server
Por esta:
Subsystem sftp internal-sftp
También tenemos que añadir la siguiente configuración al final del fichero:
Match user sftpuser
ChrootDirectory %h
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
KbdInteractiveAuthentication yes
Configurar AutoFS
para montar el recurso de Azure File lo vamos a realizar mediante autofs. Instalamos los paquetes necesarios:
apt-get install autofs samba-client
A continuación tienes que añadir la siguiente linea en /etc/auto.master
Como podemos ver en este fichero de configuración la primera parte (/sftp/sftpuser) es el home del usuario y /etc/auto.master.d/sftpuser corresponde al fichero de configuración de autofs en donde vamos a establecer los datos necesarios para poder montar el recurso.
/sftp/sftpuser/ /etc/auto.master.d/sftpuser
Para poder montar el recuso mediante autofs debemos establecer la configuración con los datos obtenidos de Azure File.
Esta configuración se realizará en mi caso en: /etc/auto.master.d/sftpuser dado que así lo hemos establecido en el archivo /etc/auto.master
Es muy importante poner correctamente todos los datos, URL del recurso, archivos de las credenciales que hemos configurado anteriormente y el UUID y GUID
CARPETA_A_MONTAR -fstype=cifs,nofail,vers=3.0,credentials=/root/smbcredentials/sftppro.cred,uid=UUID_USUARIO,gid=UUID_GRUPO ://STORAGE_ACCOUNT_CREADO.file.core.windows.net/AZURE_FILE_CREADO
CARPETA_A_MONTAR: Debemos que establecer el nombre de la carpeta que se va a montar en el home del usuario que estamos creando (Por ejemplo: /sftp/sftpuser/Public)
credentials: Tenemos que añadir el archivo donde anteriormente hemos configurado el usuario y la contraseña
uid y gid: En este campo tenemos que agregar el UUID del usuario, este dato lo podemos sacar con: «id -u USUARIO» o en /etc/passwd y el del grupo con «id -g GRUPO» o en /etc/groups
//STORAGE_ACCOUNT_CREADO.file.core.windows.net: Este dato se trata de la URL para acceder al Storage Acount que hemos creado, y se puede ver accediendo al recurso compartido que hemos creado en Azure File Share y presionando el conectar.
AZURE_FILE_CREADO: De la misma forma, este recurso es la carpeta compartida creada en Azure File Share
Ejemplo
Public -fstype=cifs,nofail,vers=3.0,credentials=/root/smbcredentials/sftppro.cred,uid=1001,gid=100 ://sftpstorage.file.core.windows.net/fsprueba
Reiniciamos el servicio de autofs y ssh
systemctl restart sshd
systemctl restart autofs
Comprobar el funcionamiento del SFTP
Mediante un cliente SFTP intentamos acceder al recurso
De la misma forma, comprobamos si monta correctamente el recurso mediante autofs el recurso de azure, para ello podemos hacer un df -h
Configurar fail2ban y ipset
Ya tenemos configurado correctamente nuestro SFTP, por ultimo falta configurar fail2ban y ipset para prevenir ataques de fuerza bruta., dado que este recurso estará expuesto a internet.
apt install fail2ban
ipset
Copiamos la configuración
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
En mi caso, dado que los servidores son Ubuntu y este tiene por defecto UFW como firewall he configurado fail2ban utilizando este firewall.
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1
bantime = 1d
findtime = 10m
maxretry = 5
[ssh-with-ufw]
enabled = true
port = 22
filter = sshd
action = ufw[application="OpenSSH", blocktype=reject]
logpath = /var/log/auth.log
maxretry = 3
Reiniciamos el servicio
systemctl restart fail2ban
Para la configuración de ipset he utilizado el script: https://github.com/trick77/ipset-blacklist el cual me gusto mucho la configuración.
wget -O /usr/local/sbin/update-blacklist.sh https://raw.githubusercontent.com/trick77/ipset-blacklist/master/update-blacklist.sh
chmod +x /usr/local/sbin/update-blacklist.sh
mkdir -p /etc/ipset-blacklist ; wget -O /etc/ipset-blacklist/ipset-blacklist.conf https://raw.githubusercontent.com/trick77/ipset-blacklist/master/ipset-blacklist.conf
En mi caso, cambie esta configuración quedando de la siguiente forma:
IPSET_BLACKLIST_NAME=blacklist # change it if it collides with a pre-existing ipset list
IPSET_TMP_BLACKLIST_NAME=${IPSET_BLACKLIST_NAME}-tmp
# ensure the directory for IP_BLACKLIST/IP_BLACKLIST_RESTORE exists (it won't be created automatically)
IP_BLACKLIST_RESTORE=/etc/ipset-blacklist/ip-blacklist.restore
IP_BLACKLIST=/etc/ipset-blacklist/ip-blacklist.list
VERBOSE=yes # probably set to "no" for cron jobs, default to yes
FORCE=yes # will create the ipset-iptable binding if it does not already exist
let IPTABLES_IPSET_RULE_NUMBER=1 # if FORCE is yes, the number at which place insert the ipset-match rule (default to 1)
# Sample (!) list of URLs for IP blacklists. Currently, only IPv4 is supported in this script, everything else will be filtered.
BLACKLISTS=(
"file:///etc/ipset-blacklist/ip-blacklist-custom.list" # optional, for your personal nemeses (no typo, plural)
"file:///etc/ipset-blacklist/ip-blacklist-shodan.list" # Shodan
"https://www.projecthoneypot.org/list_of_ips.php?t=d&rss=1" # Project Honey Pot Directory of Dictionary Attacker IPs
"https://check.torproject.org/cgi-bin/TorBulkExitList.py?ip=1.1.1.1" # TOR Exit Nodes
"http://danger.rulez.sk/projects/bruteforceblocker/blist.php" # BruteForceBlocker IP List
"https://www.spamhaus.org/drop/drop.lasso" # Spamhaus Don't Route Or Peer List (DROP)
"https://cinsscore.com/list/ci-badguys.txt" # C.I. Army Malicious IP List
"https://lists.blocklist.de/lists/all.txt" # blocklist.de attackers
"https://blocklist.greensnow.co/greensnow.txt" # GreenSnow
"https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/firehol_level1.netset" # Firehol Level 1
"https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/stopforumspam_7d.ipset" # Stopforumspam via Firehol
"https://raw.githubusercontent.com/firehol/blocklist-ipsets/master/alienvault_reputation.ipset" #Alienvault reputation
"http://ipverse.net/ipblocks/data/countries/af.zone" #Afghanistan
"http://ipverse.net/ipblocks/data/countries/cn.zone" #China
"http://ipverse.net/ipblocks/data/countries/ir.zone" #Iran
"http://ipverse.net/ipblocks/data/countries/pk.zone" #Pakistan
"http://ipverse.net/ipblocks/data/countries/pk.zone" #India
"http://ipverse.net/ipblocks/data/countries/hk.zone" #Hong Kong
"http://ipverse.net/ipblocks/data/countries/kp.zone" #North Korea
"http://ipverse.net/ipblocks/data/countries/kr.zone" #South Korea
"http://ipverse.net/ipblocks/data/countries/ru.zone" #Russia
"http://ipverse.net/ipblocks/data/countries/tw.zone" #Taiwan
"http://ipverse.net/ipblocks/data/countries/il.zone" #Israel
"http://ipverse.net/ipblocks/data/countries/sa.zone" #Saudi Arabia
"http://ipverse.net/ipblocks/data/countries/tr.zone" #Turkey
"http://ipverse.net/ipblocks/data/countries/vn.zone" #Vietnam
"http://ipverse.net/ipblocks/data/countries/lt.zone" #Lithuania
"http://ipverse.net/ipblocks/data/countries/ee.zone" #Estonia
"http://ipverse.net/ipblocks/data/countries/sg.zone" #Singapore
"http://ipverse.net/ipblocks/data/countries/my.zone" #Malaysia
"http://ipverse.net/ipblocks/data/countries/ua.zone" #Ukraine
)
MAXELEM=131072
De la misma forma, cree este pequeño script que aunque es cutre funciona correctamente.
En este script agrego todos los ataques detectados por fail2ban a una backlist de ipset
#!/bin/bash
filecontent=(`zgrep 'Ban' /var/log/fail2ban.log* | awk '{print $8}'`)
blacklist=/etc/ipset-blacklist/ip-blacklist-custom.list
blacklist1=$( cat $blacklist )
touch $blacklist.1
for ip in "${filecontent[@]}"
do
if [[ " $blacklist1" =~ "$ip" ]]
then
echo "" > /dev/null 2>&1
else
echo "$ip" >> $blacklist.1
fi
done
sort -u $blacklist.1 >> $blacklist
sed -i '/^$/d' $blacklist
rm $blacklist.1
/usr/local/sbin/update-blacklist.sh /etc/ipset-blacklist/ipset-blacklist.conf
Por ultimo, configuro este script en el crontab
@hourly root /usr/local/sbin/update-blacklist-custom.sh
Por ultimo, creamos un script para la creación del usuario automáticamente, en este script no crea el File share en Azure, eso es lo único que tiene que crear a mano.
#!/bin/bash
usage()
{
cat << EOF
USO: $0 -G grupo -u usuario -f file system
Script para la creacion de usuarios enjaulados SFTP
OPCIONES:
-G Grupo
-u Usuario SFTP
-f file system
ejemplo de uso: /usr/bin/createuser.sh -G sftp -u usersftp -f /sftp/usersftp
EOF
}
inputgroup=
inputusuario=
inputfs=
remotesrv=X.X.X.X
while getopts "hH:G:u:f:" OPTION
do
case $OPTION in
h)
usage
exit 1
;;
G)
inputgroup=$OPTARG
;;
u)
inputusuario=$OPTARG
;;
f)
inputfs=$OPTARG
;;
esac
done
if [ -z $inputgroup ] || [ -z $inputusuario ] || [ -z $inputfs ]
then
usage
exit 1
fi
if [[ $EUID -ne 0 ]]; then
echo "Este script se tiene que ejecutar con el usuario root"
exit 1
fi
function SSHconfig (){
if [ -f "/etc/ssh/sshd_config-bck" ]
then
cat << EOF >> /etc/ssh/sshd_config
Match user $inputusuario
ChrootDirectory %h
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp
KbdInteractiveAuthentication yes
EOF
else
echo "No se encontro el fichero de configuracion /etc/ssh/sshd_config-bck"
exit 1
fi
}
checkuser=`getent passwd $inputusuario | wc -l`
if [ $(getent group admin) ]; then
echo "Existe el grupo $inputgroup"
else
groupadd $inputgroup
ssh root@$remotesr "groupadd $inputgroup"
fi
if [ $checkuser == "0" ]
then
useradd -g $inputgroup -s /bin/false -d $inputfs $inputusuario
ssh root@$remotesrv "useradd -g $inputgroup -s /bin/false -d $inputfs $inputusuario"
passwd $inputusuario
echo "Repite de nuevo la password para mprolsftp002"
ssh root@$remotesrv "passwd $inputusuario"
mkdir -p $inputfs/Processed
chmod 755 $inputfs
chown root:root $inputfs
chown $inputusuario:$inputgroup $inputfs/Processed
cp /etc/ssh/sshd_config /etc/ssh/sshd_config-bck
SSHconfig
scp /etc/ssh/sshd_config root@$remotesrv:/etc/ssh/sshd_config
service sshd restart
ssh root@$remotesrv "service sshd restart"
echo "Se ha creado el usuario sftp $inputusuario"
else
echo "*ERROR: El usuario $inputusuario ya existe"
exit 1
fi
Modo de eso:
Script para la creacion de usuarios enjaulados SFTP
OPCIONES:
-G Grupo
-u Usuario SFTP
-f file system
-s Name Azure File Share
ejemplo de uso: /usr/bin/createuser.sh -G sftp -u usersftp -f /sftp/usersftp -s fsprueba
:wq!
Una respuesta a “Crear SFTP en Alta disponibilidad en Azure”