Gmail y CSF Firewall, listas blanca para no sufrir como SysAdmin

Gmail + CSF Firewall, lista blancas How to

Gmail y CSF Firewall son una combinación que de no cuidarse, puede llevarnos de cabeza. Quien dice Gmail dice Hotmail, o lo que es lo mismo, las aplicaciones de correo web, que permiten usar el navegador como programa de correo, en lugar de usar un programa de escritorio. Eso, unido a la falta de lectura y comprensión de los usuarios menos avanzados produce que muchas veces, estos servicios sean baneados por nuestros sistemas de seguridad.

La propuesta es sencilla, poner en lista blanca todas las IP’s de Gmail de una forma dinámica y revisando de manera automática mediante una tarea cron.

Seguridad y los problemas con los grandes de Internet

No vamos a entrar en las dificultades que los administradores de empresa pequeñas o medianas tenemos, debido a los mil y un problemas derivados de los errores de seguridad de los webmasters y profesionales del sector, que llevan a que nuestros sistema entren de vez en cuando en listas negras ya sea, por formularios no protegidos, mala gestión en la salvaguarda de las contraseñas de las cuentas de correo de la empresa, uso de sistemas operativos poco fiables o abiertos e inseguros. 

Pero lo que si es cierto, que cualquiera se atreve a banear a el poderos Google, a Microsoft, pese a que deses sus redes, se envia una buena parte del spam que llega a los sistemas frontales.

El planteo de la solución que surge de los problemas derivados por muchos usuarios que al tratar de conectar su cuenta Gmail con sus cuentas en uno de nuestros servidores de correo, y que lleva a que nuestro sistema de seguridad banee (prohíba el acceso) a alguna de las IP de Gmail u otro, es sencilla.

Obtener la lista de IPs mediante el uso de dig, filtrarla y actuar con ella y nuestro firewall.

Gmail

Obteniendo los rangos de IP de Gmail

El primer paso sería obtener con dig el registro TXT  usado por Gmail  para su SPF

dig +short  _spf.google.com txt
"v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all

El resultado nos muestra 3 hostnames FDQN para Google.

  • _netblocks.google.com
  • _netblocks2.google.com
  • _netblocks3.google.com

Con cada uno de ellos podríamos obtener de su registro TXT a que IP’s pertenecen cada uno, por ejemplo

# dig +short  _netblocks.google.com txt
"v=spf1 ip4:35.190.247.0/24 ip4:64.233.160.0/19 ip4:66.102.0.0/20 ip4:66.249.80.0/20 ip4:72.14.192.0/18 ip4:74.125.0.0/16 ip4:108.177.8.0/21 ip4:173.194.0.0/16 ip4:209.85.128.0/17 ip4:216.58.192.0/19 ip4:216.239.32.0/19 ~all"

# dig +short  _netblocks2.google.com txt
"v=spf1 ip6:2001:4860:4000::/36 ip6:2404:6800:4000::/36 ip6:2607:f8b0:4000::/36 ip6:2800:3f0:4000::/36 ip6:2a00:1450:4000::/36 ip6:2c0f:fb50:4000::/36 ~all"
# dig +short _netblocks3.google.com txt
"v=spf1 ip4:172.217.0.0/19 ip4:172.217.32.0/20 ip4:172.217.128.0/19 ip4:172.217.160.0/20 ip4:172.217.192.0/19 ip4:108.177.96.0/19 ip4:35.191.0.0/16 ip4:130.211.0.0/22 ~all"

Bueno el resultado filtrado así para el artículo en el momento de su escritura sería:

  • 35.190.247.0/24
  • 64.233.160.0/19
  • 66.102.0.0/20
  • 66.249.80.0/20
  • 72.14.192.0/18
  • 74.125.0.0/16
  • 108.177.8.0/21
  • 173.194.0.0/16
  • 209.85.128.0/17
  • 216.58.192.0/19
  • 216.239.32.0/19
  • 172.217.0.0/19
  • 172.217.32.0/20
  • 172.217.128.0/19
  • 172.217.160.0/20
  • 172.217.192.0/19
  • 108.177.96.0/19
  • 35.191.0.0/16
  • 130.211.0.0/22
  • 2001:4860:4000::/36
  • 2404:6800:4000::/36
  • 2607:f8b0:4000::/36
  • 2800:3f0:4000::/36
  • 2a00:1450:4000::/36
  • 2c0f:fb50:4000::/36

Bien, con este dato podemos preparar nuestro firewall para evitar que las IP de Google entren en la lista negra, y así, el único que sufrirá será el usuario que esta haciendo mal su configuración. Por supuesto, no vamos a abrir, todo el trafico a esas IP, pues desde esas IP’s también se hacen maldades de todo tipo, así que sólo abriremos los puertos afectados, 25, 465, 587, 110, 143.

Automatización del procesos de obtención de Ip’s

El código del script esta disponible en mi Gitlab, ya que allí tendré la versión mas actualizada de este y de otros que iré publicando.

Ejecución

$ bash google-ips.sh 
!/bin/sh
 #
 URL: https://castris.com
 Email: abdelkarim.mateos@castris.com
 License MIT: https://gitlab.castris.com/root/systips/raw/master/LICENSE
 #
 The following script read DNS record TXT for _spf of Google
 After read, clean and add IP4 and IP6 ranges of Google to temporal files
 in format CIDR
 #
 mydate=$(date +"%Y%m%d")
 input=/tmp/google-$mydate
 ip4=/tmp/google-ip4-$mydate
 ip6=/tmp/google-ip6-$mydate
 Check and delete files if exists
 [ -f "$ip4" ] && rm -f "$ip4"
 [ -f "$ip6" ] && rm -f "$ip6"
 for block in $(dig +short  _spf.google.com txt | awk  '{ print $2,$3,$4}'| sed 's/include://g');
 do
   dig +short $block txt;
 done > $input
 while IFS= read -r line
 do
   # readarray -d falla en sistemas Centos
   # readarray -d ' ' -t strarr <<< "$line"   read -r -a strarr <<< "$line"   for (( n=0; n < ${#strarr[*]}; n++))   do     if [[ "${strarr[n]}" == *"ip4"* ]]; then       remove="ip4:"       ip="${strarr[n]}"       echo ${ip//$remove/} >> $ip4
       continue
     fi
     if [[ "${strarr[n]}" == "ip6" ]]; then
       remove="ip6:"
       ip="${strarr[n]}"
       echo ${ip//$remove/} >> $ip6
       continue
     fi
   done
 done < "$input"

Este script dejará en el directorio /tmp dos ficheros con el nombre google-ip4-YYYYMMDD y google-ip6-YYYYMMDD, ya limpios, que sólo contendrán lineas con rangos de IP en formato CIDR 

Firewall

Activación de IPs en la lista blanca

El siguiente proceso es automatizar nuestro firewall CSF, de forma que la lista este actualizada. No es necesario hacerlos cada hora, con hacerlo una vez al día o a la semana, te valdría. No suele haber cambios de forma habitual, pero … los hay.

Vamos a autorizar sólo los puertos correspondientes al correo, y no todos los puertos.

Script

#!/bin/sh
usage="$(basename "$0") [-h] name

where:
    -h            show this help text
    name:         of provider without spaces
    iptype:       all|ip4|ip6"

function checkArg() {
    if (( $# < 2 ))
    then
        echo "$usage"
        exit
    fi
}

while getopts ':hs:' option; do
  case "$option" in
    h) echo "$usage"
       exit
       ;;
  esac
done

checkArg $1 $2

function addIp() {
  file="/tmp/${1}-ip${2}-$(date +"%Y%m%d")"
  ports=(25 465 587 110 143)

  while IFS= read -r line
  do
    # Remove if any bloc is already in CSF deny or deny temp
    csf -dr ${line}
    csf -tr ${line}

    # Loop for every port
    for port in "${ports[@]}"
      [[ -z "$line" ]] || continue
      csf -a "tcp|in|d=${port}|s=${line}" ${1}
      csf -a "tcp|out|d=${port}|d=${line}" ${1}
    done
  done < "$file"
}

sed -i "/${1}/d" /etc/csf/csf.allow

case "$2" in
  all)
    addIp $1 "4"
    addIp $1 "6"
    ;;
  ip4)
    addIp $1 "4"
    ;;
  ip6)
    addIp $1 "6"
    ;;
  *)
    echo "$usage"
    exit
  ;;
esac

Ejecución

$ sh firewall/add-ips-allow-google-csf.sh google ip4
csf: 35.190.247.0/24 not found in csf.deny
csf: 35.190.247.0/24 not found in temporary bans
csf: There are no temporary IP allows
Adding tcp|in|d=25|s=35.190.247.0/24 to csf.allow and iptables ACCEPT...
ACCEPT  tcp opt -- in !lo out *  35.190.247.0/24  -> 0.0.0.0/0   tcp dpt:25
Adding tcp|out|d=25|d=35.190.247.0/24 to csf.allow and iptables ACCEPT...
ACCEPT  tcp opt -- in * out !lo  0.0.0.0/0  -> 35.190.247.0/24   tcp dpt:25
Adding tcp|in|d=465|s=35.190.247.0/24 to csf.allow and iptables ACCEPT...
ACCEPT  tcp opt -- in !lo out *  35.190.247.0/24  -> 0.0.0.0/0   tcp dpt:465
Adding tcp|out|d=465|d=35.190.247.0/24 to csf.allow and iptables ACCEPT...
ACCEPT  tcp opt -- in * out !lo  0.0.0.0/0  -> 35.190.247.0/24   tcp dpt:465
Adding tcp|in|d=587|s=35.190.247.0/24 to csf.allow and iptables ACCEPT...
ACCEPT  tcp opt -- in !lo out *  35.190.247.0/24  -> 0.0.0.0/0   tcp dpt:587
Adding tcp|out|d=587|d=35.190.247.0/24 to csf.allow and iptables ACCEPT...
ACCEPT  tcp opt -- in * out !lo  0.0.0.0/0  -> 35.190.247.0/24   tcp dpt:587
Adding tcp|in|d=110|s=35.190.247.0/24 to csf.allow and iptables ACCEPT...
ACCEPT  tcp opt -- in !lo out *  35.190.247.0/24  -> 0.0.0.0/0   tcp dpt:110
Adding tcp|out|d=110|d=35.190.247.0/24 to csf.allow and iptables ACCEPT...
ACCEPT  tcp opt -- in * out !lo  0.0.0.0/0  -> 35.190.247.0/24   tcp dpt:110
Adding tcp|in|d=143|s=35.190.247.0/24 to csf.allow and iptables ACCEPT...
ACCEPT  tcp opt -- in !lo out *  35.190.247.0/24  -> 0.0.0.0/0   tcp dpt:143
Adding tcp|out|d=143|d=35.190.247.0/24 to csf.allow and iptables ACCEPT...
ACCEPT  tcp opt -- in * out !lo  0.0.0.0/0  -> 35.190.247.0/24   tcp dpt:143...

Automatización cron

Yo por ejemplo lo ejecuto los domingos a las 6:14

# crontab -e
14 6 * * mon bash /root/systips/firewall/google-ips.sh && bash /root/systips/firewall/add-ips-allow-google-csf.sh google ip4
>/dev/null 2>&1

 

Agradecimientos

Gracias a Taskin Ashiq por su imagen que me sirvió para editarla en Canva

 

Comparte este articulo en

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax