Filtrado por geolocalización

Si le echamos una mirada a las estadísticas internacionales de ataques en tiempo real, como el mapa Norse o el ThreatMap de FireEye o el Digital Map Attack, entre otros, podemos percatarnos que en un alto porcentaje, los ataques informáticos (y actos de ciberdelincuencia en general) tienen un patrón similar: Se originan mayormente en los mismos países (Rusia, China, India, Corea, etc.).
Hace mas o menos 15 años comenzaron a aparecer herramientas de filtrado basadas en geolocalización, pero a pesar de que cada día cobra más vigencia (ya que algunas organizaciones prefieren evitar el tráfico con países con un alto grado de cibercriminalidad), muchos usuarios y administradores IT no tienen idea de cómo hacerlo y a medida que salen nuevas versiones de los sistemas operativos más utilizados, estas herramientas y métodos van quedando obsoletos o se vuelven incompatibles.
Existen varios tipos de filtrado por geolocalización. Los más conocidos son GeoCA y GeoIP. El primero bloquea certificados de seguridad expedidos por agencias CA (que pueden ser fraudulentos o válidos), pero que como usuarios nos generan mucha desconfianza, por ejemplo los expedidos por una CA de China, Rusia, Ucrania, etc. Si quiere profundizar sobre este tema, puedes consultar el post ¿En manos de quién está la seguridad?.
La segunda son herramientas y procedimientos destinados a bloquear ips por países, de acuerdo al estándar ISO 3166 de 1974.
En este gran océano hemos elegido solo dos, que han sobrevivido al paso del tiempo sin perder vigencia y aún hoy son muy útiles; y si bien no nos protegen en un 100% (ninguna herramienta o procedimiento actual es capaz de lograrlo, porque es virtualmente imposible determinar el origen de todas las ip y certificados existentes), ayudan mucho en este proceso. 
Hablamos de SSLCop, de Yago Jesús (Security By Default) y el módulo xtables para el firewall iptables de Netfilter.
SSLCop
La primera no necesita mucha presentación. Es portable, liviana, ideal para llevar en un dispositivo usb y se ejecuta bien en Windows (XP y 7), y con IE y Chrome. Se espera que en su próxima entrega sea compatible con Firefox y otros navegadores y también con Linux.
Consiste en una lista negra donde se añaden aquellos países que queremos bloquear. Su filtrado está orientado a la navegación y se concentra en bloquear cualquier certificado SSL por geolocalización.
Es muy sencilla de utilizar. La descargan AQUI. Clic (con privilegios), elija el país (o los países) que quiera restringir y pulse el botón BLOCK!.
Xtables
Nuestro segundo elegido está orientado al bloqueo de ips por países (GeoIP). Es un poco más complicado de configurar, ya que depende de una funcionalidad del kernel que quedó obsoleta, por lo que Netfilter (creador de iptables) decidió retirar algunos módulos integrados por defecto, entre ellos el Xtables. Esto obviamente afectó también a los módulos psd (que se usa para evitar el escaneo de puertos) y a pknock (que sirve para Port Knocking). Pueden consultar en Sourceforge, la lista completa de módulos que vienen con Xtables.
Adicionalmente para que funcione el filtrado por GeoIP, Xtables debe estar acompañado de una base de datos y librerias de geolocalización. La más usada es GeoIP de maxmind.com.
Instalación
Existen algunas diferencias en la manera en que se "instala" el módulo Xtables. Depende de las diferentes distribuciones de Linux, sus versiones y kernels (ya que requiere compilar), y otros paquetes.
Es por esta razón que automatizar el proceso con un script general para cualquier versión es muy engorroso, por tanto recomendamos su instalación manual.
Básicamente debería ser así. Primero actualizamos el sistema e instalamos algunos paquetes esenciales, sin embargo este punto depende de su sistema (en algunos casos podrá omitir algunos de los paquetes sugeridos)...
Muy Importante: No se garantiza su funcionamiento en kernel 3x (solo 2x). Para kernel 3x debe utilizar ipset
sudo apt-get update && sudo apt-get dist-upgrade -y
sudo apt-get install libtext-csv-xs-perl libncurses5-dev module-assistant geoip-database libgeoip1 iptables iptables-dev kernel-package build-essential module-assistant bzip2 gzip unzip -y
# Extra (optional)
sudo apt-get install build-essential checkinstall cdbs devscripts dh-make fakeroot libxml-parser-perl check avahi-daemon automake make dpatch patchutils autotools-dev debhelper quilt xutils lintian cmake libtool autoconf git-core subversion bzr gcc patch -y
sudo apt-get install linux-headers-$(uname -r)
Una vez tengamos el sistema actualizado, instalamos las dependencias necesarias de Xtables...
sudo apt-get install module-assistant xtables-addons-common libtext-csv-xs-perl -y
Nota: El paquete xtables-addons-common incluye xtables-addons-dkms, pero si por alguna razón no lo instala puede hacerlo manualmente.
Y lanzamos mode-assistant para Xtables...
module-assistant --verbose --text-mode auto-install xtables-addons
Luego descargamos e instalamos la base de datos de geolocalización...
cd /usr/lib/xtables-addons/  
./xt_geoip_dl
./xt_geoip_build GeoIPCountryWhois.csv
mkdir -p /usr/share/xt_geoip/  
cp -r {BE,LE} /usr/share/xt_geoip/
Sin embargo es más recomendado hacerlo de la siguiente manera:
sudo mkdir /usr/share/xt_geoip
sudo /usr/lib/xtables-addons/xt_geoip_dl
sudo /usr/lib/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip *.csv
El último paso es ejecutar una regla de iptables en el terminal, bloqueando algún país y verificar su funcionamiento. Ejemplo:
sudo iptables -A INPUT -m geoip --src-cc CN,RU -j DROP
o especificando la interface
sudo iptables -A INPUT -i eth0 -m geoip --src-cc CN,RU -j DROP
Aquí bloqueamos las ips procedentes de China y Rusia. Ahora verificamos...
sudo iptables -L
Y el resultado debe ser mas o menos así (asumiendo que su iptables no tenga reglas y la cadena INPUT esté en ACCEPT):
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     udp  --  anywhere             anywhere             udp dpt:domain
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:domain
ACCEPT     udp  --  anywhere             anywhere             udp dpt:bootps
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:bootps
DROP       all  --  anywhere             anywhere             -m geoip --source-country CN,RU
También podemos echar mano de Mangle, con un prefix para que ULOG guarde los registros:
iptables -t mangle -A PREROUTING -m geoip --src-cc CN,RU -j DROP
iptables -t mangle -A PREROUTING -m geoip --src-cc CN,RU -j ULOG --ulog-prefix 'ATAQUE: geoip'
Y aprovechar que tenemos activo Xtables, para agregar una regla anti Port Scan.
iptables -A INPUT -m psd -j DROP
iptables -A INPUT -m psd -j ULOG --ulog-prefix 'ATAQUE: portscan'
Geolocalización con Apache
Otro de los múltiples usos del GeoIP es el filtrado por Apache, utilizando mod_geoip2, de maxmind. Para mayor información consulte el post Apache+mod_geoip = win
Filtrado GeoIP personalizado
Puede darse el caso que la base de datos GeoIP que utilice con xtables no cubra en un 100% todas las ips procedentes de países que pretendemos bloquear; por ejemplo ips utilizadas por anonimizadores, proxys, red tor y muchas otras fuentes; o también ips procedentes de países "permitidos", pero que, en algunos casos, resultan ips atacantes (el hecho que validemos el tráfico procedente de Estados Unidos y Canadá no significa que allá no existan hackers).
Para solucionarlo se hace necesario crear una regla en el iptables, independiente al filtrado xtables/geoip. A modo de ejemplo, creamos una acl, que llamaremos blacklist-geoip, y dentro pondremos las ips o rangos de ips específicos que queremos restringir.
Es imprescindible que no haya ips o rangos repetidos, por tanto deberá confrontar sus bases de datos antes de bloquear una ip con esta regla, para evitar la recarga del iptables.
# blacklist-geoip
route=/home/usuario/acl
for ips in `sed $route/blacklist-geoip`; do
   if echo $ips |  | grep "-" >/dev/null; then
     $iptables -A FORWARD -m iprange --dst-range "$ips" -j DROP
   else
     $iptables -t mangle -A PREROUTING -i $ips -j DROP
     $iptables -A FORWARD -d $ips -j DROP
     $iptables -A INPUT -s $ips -j DROP
     $iptables -A OUTPUT -s $ips -j DROP
   fi
done
Automatización
A pesar de que recomendamos SIEMPRE la instalación manual de xtables y la base de datos, podemos automatizar el proceso.
Los siguientes scripts son para Ubuntu, pero su aplicación queda bajo su propio riesgo. Se recomienda no ejecutarlos en entornos diferentes a los propuestos, ni tampoco más de una vez en el mismo entorno, ya que puede generar fallo en la compilación.
Nota: Para el caso del script de Ubuntu 14.04, si se presenta fallo en la compilación, puede hacerlo manualmente, usando las líneas relacionadas con los paquetes xtables-addons-common, xtables-addons-dkms, xtables-addons-source y module-assistant
Script for Xtables only for Ubuntu 14x
kernel v3.13.0-43-generic, Iptables v1.4.21
#!/bin/bash
# SCRIPT PARA BLOQUEO IPTABLES POR GEO-LOCALIZACION
# Instalacion del modulo xtables para ubuntu 14.04 LTS
# Por Maravento.com administrador@maravento.com
# Agradecimientos a: georgian.cracium@gmail.com y novatoz.com
#
# Comprobando version de ubuntu
version=$(lsb_release -c | awk '{print $2}')
case $version in
        trusty)
                echo "Iniciando la instalacion del modulo xtables..."
                ;;
        *)
                echo "Si el script presenta error en la instalacion"
                exit 1
                ;;
# instalando dependencias
esac
sudo apt-get install libtext-csv-xs-perl libncurses5-dev module-assistant geoip-database libgeoip1 iptables iptables-dev kernel-package build-essential module-assistant bzip2 gzip unzip -y
#
# instalando modulo xtables
sudo apt-get install xtables-addons-common -y
sudo module-assistant --verbose --text-mode auto-install xtables-addons
#
# Si falla la compilacion instale manualmente los siguientes paquetes
# sudo apt-get install xtables-addons-common xtables-addons-dkms xtables-addons-source
# sudo module-assistant auto-install xtables-addons-source
#
# creando el directorio de la base de datos
sudo mkdir /usr/share/xt_geoip
# Descarga e integracion de la base de datos
sudo /usr/lib/xtables-addons/xt_geoip_dl
sudo /usr/lib/xtables-addons/xt_geoip_build -D /usr/share/xt_geoip *.csv
#
echo done
# Fin del script
Script for Xtables only for Ubuntu 10x
kernel v2.6.32-58-generic, Iptables v1.4.4
#!/bin/bash
# SCRIPT PARA BLOQUEO IPTABLES POR GEO-LOCALIZACION
# Instalacion del modulo xtables para ubuntu 10.04 LTS
# Por georgian.cracium@gmail.com
# Traduccion Maravento.com
#
# Comprobando version de ubuntu
version=$(lsb_release -c | awk '{print $2}')
case $version in
        lucid)
                echo "Iniciando la instalacion del modulo xtables..."
                ;;
        *)
                echo "Si el script presenta error en la instalacion"
                exit 1
                ;;
# instalando dependencias
esac
sudo apt-get update
sudo aptitude -y install iptables iptables-dev
sudo apt-get -y install kernel-package
sudo aptitude -y install build-essential
sudo aptitude -y install module-assistant
sudo module-assistant prepare
sudo module-assistant auto-install xtables-addons-source
sudo aptitude -y install xtables-addons-common
sudo aptitude -y install libtext-csv-xs-perl gzip unzip
#
# Descarga de xtables-addons version 1.30
wget -O /usr/src/xtables-addons.tar.xz  http://sourceforge.net/projects/xtables-addons/files/Xtables-addons/1.30/xtables-addons-1.30.tar.xz/download
cd /usr/src/
tar xf /usr/src/xtables-addons.tar.xz
#
# Copiando archivos geoip_build_db.pl y geoip_download.sh
mkdir /etc/xtables
cp /usr/src/xtables-addons-1.30/geoip/geoip_build_db.pl /etc/xtables/geoip_build_db.pl
cp /usr/src/xtables-addons-1.30/geoip/geoip_download.sh /etc/xtables/geoip_download.sh
#
# Eliminando la carpeta en la que se desempaqueto xtables
rm -rf /usr/src/xtables-addons-1.30
rm /usr/src/xtables-addons.tar.xz
#
# creando el directorio en el que se buscará en la base de datos
mkdir /var/geoip
mkdir /var/geoip/LE
cd /etc/xtables
#
# Descarga de la base de datos en formato csv
/etc/xtables/geoip_download.sh
/etc/xtables/geoip_build_db.pl -D /var/geoip/LE *.csv
#
# creando el ejecutable que actualiza cada mes la base de datos con los países
echo -e "#!/bin/bash
cd /etc/xtables
#
# Realizando operaciones adicionales
rm /etc/xtables/GeoIPCountryWhois.csv
rm /etc/xtables/GeoIPv6.csv
rm /etc/xtables/GeoIPCountryCSV.zip
/etc/xtables/geoip_download.sh
/etc/xtables/geoip_build_db.pl -D /var/geoip/LE *.csv" > /etc/cron.monthly/geoip_xptables
sudo chown -R root:root /etc/cron.monthly/geoip_xptables
chmod +x "/etc/cron.monthly/geoip_xptables"
chmod 755 /etc/cron.monthly/geoip_xptables
#
echo done
# Fin del script
Tutoriales, Descargas y DB
A continuación un resumen de enlaces más importantes (HowTO, descarga y DB de geolocalización), algunos de ellos mencionados en el post:
Módulo: Xtables-addons
Descarga: sourceforge
HowTo para CentOS: HowToForge
HowTo para Debian y derivados: Jeshurun's BlogLin's TechDidoTechDevsysadmin, etc
GeoIP Database: Maxmind
GeoIP Apache: SecuritybyDefault
Update GeoIP Database: DevSysAdmin.
Norma ISO 3166: listado de códigos de países
IPset Tutorial
IPset Man
ISO 3166 Country Codes.
Country                                         A 2     A 3     Number
----------------------------------------------------------------------
AALAND ISLANDS                                  AX      ALA     248
AFGHANISTAN                                     AF      AFG     004
ALBANIA                                         AL      ALB     008
ALGERIA                                         DZ      DZA     012
AMERICAN SAMOA                                  AS      ASM     016
ANDORRA                                         AD      AND     020
ANGOLA                                          AO      AGO     024
ANGUILLA                                        AI      AIA     660
ANTARCTICA                                      AQ      ATA     010
ANTIGUA AND BARBUDA                             AG      ATG     028
ARGENTINA                                       AR      ARG     032
ARMENIA                                         AM      ARM     051
ARUBA                                           AW      ABW     533
AUSTRALIA                                       AU      AUS     036
AUSTRIA                                         AT      AUT     040
AZERBAIJAN                                      AZ      AZE     031
BAHAMAS                                         BS      BHS     044
BAHRAIN                                         BH      BHR     048
BANGLADESH                                      BD      BGD     050
BARBADOS                                        BB      BRB     052
BELARUS                                         BY      BLR     112
BELGIUM                                         BE      BEL     056
BELIZE                                          BZ      BLZ     084
BENIN                                           BJ      BEN     204
BERMUDA                                         BM      BMU     060
BHUTAN                                          BT      BTN     064
BOLIVIA                                         BO      BOL     068
BOSNIA AND HERZEGOWINA                          BA      BIH     070
BOTSWANA                                        BW      BWA     072
BOUVET ISLAND                                   BV      BVT     074
BRAZIL                                          BR      BRA     076
BRITISH INDIAN OCEAN TERRITORY                  IO      IOT     086
BRUNEI DARUSSALAM                               BN      BRN     096
BULGARIA                                        BG      BGR     100
BURKINA FASO                                    BF      BFA     854
BURUNDI                                         BI      BDI     108
CAMBODIA                                        KH      KHM     116
CAMEROON                                        CM      CMR     120
CANADA                                          CA      CAN     124
CAPE VERDE                                      CV      CPV     132
CAYMAN ISLANDS                                  KY      CYM     136
CENTRAL AFRICAN REPUBLIC                        CF      CAF     140
CHAD                                            TD      TCD     148
CHILE                                           CL      CHL     152
CHINA                                           CN      CHN     156
CHRISTMAS ISLAND                                CX      CXR     162
COCOS (KEELING) ISLANDS                         CC      CCK     166
COLOMBIA                                        CO      COL     170
COMOROS                                         KM      COM     174
CONGO, Democratic Republic of (was Zaire)       CD      COD     180
CONGO, Republic of                              CG      COG     178
COOK ISLANDS                                    CK      COK     184
COSTA RICA                                      CR      CRI     188
COTE D'IVOIRE                                   CI      CIV     384
CROATIA (local name: Hrvatska)                  HR      HRV     191
CUBA                                            CU      CUB     192
CYPRUS                                          CY      CYP     196
CZECH REPUBLIC                                  CZ      CZE     203
DENMARK                                         DK      DNK     208
DJIBOUTI                                        DJ      DJI     262
DOMINICA                                        DM      DMA     212
DOMINICAN REPUBLIC                              DO      DOM     214
ECUADOR                                         EC      ECU     218
EGYPT                                           EG      EGY     818
EL SALVADOR                                     SV      SLV     222
EQUATORIAL GUINEA                               GQ      GNQ     226
ERITREA                                         ER      ERI     232
ESTONIA                                         EE      EST     233
ETHIOPIA                                        ET      ETH     231
FALKLAND ISLANDS (MALVINAS)                     FK      FLK     238
FAROE ISLANDS                                   FO      FRO     234
FIJI                                            FJ      FJI     242
FINLAND                                         FI      FIN     246
FRANCE                                          FR      FRA     250
FRENCH GUIANA                                   GF      GUF     254
FRENCH POLYNESIA                                PF      PYF     258
FRENCH SOUTHERN TERRITORIES                     TF      ATF     260
GABON                                           GA      GAB     266
GAMBIA                                          GM      GMB     270
GEORGIA                                         GE      GEO     268
GERMANY                                         DE      DEU     276
GHANA                                           GH      GHA     288
GIBRALTAR                                       GI      GIB     292
GREECE                                          GR      GRC     300
GREENLAND                                       GL      GRL     304
GRENADA                                         GD      GRD     308
GUADELOUPE                                      GP      GLP     312
GUAM                                            GU      GUM     316
GUATEMALA                                       GT      GTM     320
GUINEA                                          GN      GIN     324
GUINEA-BISSAU                                   GW      GNB     624
GUYANA                                          GY      GUY     328
HAITI                                           HT      HTI     332
HEARD AND MC DONALD ISLANDS                     HM      HMD     334
HONDURAS                                        HN      HND     340
HONG KONG                                       HK      HKG     344
HUNGARY                                         HU      HUN     348
ICELAND                                         IS      ISL     352
INDIA                                           IN      IND     356
INDONESIA                                       ID      IDN     360
IRAN (ISLAMIC REPUBLIC OF)                      IR      IRN     364
IRAQ                                            IQ      IRQ     368
IRELAND                                         IE      IRL     372
ISRAEL                                          IL      ISR     376
ITALY                                           IT      ITA     380
JAMAICA                                         JM      JAM     388
JAPAN                                           JP      JPN     392
JORDAN                                          JO      JOR     400
KAZAKHSTAN                                      KZ      KAZ     398
KENYA                                           KE      KEN     404
KIRIBATI                                        KI      KIR     296
KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF          KP      PRK     408
KOREA, REPUBLIC OF                              KR      KOR     410
KUWAIT                                          KW      KWT     414
KYRGYZSTAN                                      KG      KGZ     417
LAO PEOPLE'S DEMOCRATIC REPUBLIC                LA      LAO     418
LATVIA                                          LV      LVA     428
LEBANON                                         LB      LBN     422
LESOTHO                                         LS      LSO     426
LIBERIA                                         LR      LBR     430
LIBYAN ARAB JAMAHIRIYA                          LY      LBY     434
LIECHTENSTEIN                                   LI      LIE     438
LITHUANIA                                       LT      LTU     440
LUXEMBOURG                                      LU      LUX     442
MACAU                                           MO      MAC     446
MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF      MK      MKD     807
MADAGASCAR                                      MG      MDG     450
MALAWI                                          MW      MWI     454
MALAYSIA                                        MY      MYS     458
MALDIVES                                        MV      MDV     462
MALI                                            ML      MLI     466
MALTA                                           MT      MLT     470
MARSHALL ISLANDS                                MH      MHL     584
MARTINIQUE                                      MQ      MTQ     474
MAURITANIA                                      MR      MRT     478
MAURITIUS                                       MU      MUS     480
MAYOTTE                                         YT      MYT     175
MEXICO                                          MX      MEX     484
MICRONESIA, FEDERATED STATES OF                 FM      FSM     583
MOLDOVA, REPUBLIC OF                            MD      MDA     498
MONACO                                          MC      MCO     492
MONGOLIA                                        MN      MNG     496
MONTSERRAT                                      MS      MSR     500
MOROCCO                                         MA      MAR     504
MOZAMBIQUE                                      MZ      MOZ     508
MYANMAR                                         MM      MMR     104
NAMIBIA                                         NA      NAM     516
NAURU                                           NR      NRU     520
NEPAL                                           NP      NPL     524
NETHERLANDS                                     NL      NLD     528
NETHERLANDS ANTILLES                            AN      ANT     530
NEW CALEDONIA                                   NC      NCL     540
NEW ZEALAND                                     NZ      NZL     554
NICARAGUA                                       NI      NIC     558
NIGER                                           NE      NER     562
NIGERIA                                         NG      NGA     566
NIUE                                            NU      NIU     570
NORFOLK ISLAND                                  NF      NFK     574
NORTHERN MARIANA ISLANDS                        MP      MNP     580
NORWAY                                          NO      NOR     578
OMAN                                            OM      OMN     512
PAKISTAN                                        PK      PAK     586
PALAU                                           PW      PLW     585
PALESTINIAN TERRITORY, Occupied                 PS      PSE     275
PANAMA                                          PA      PAN     591
PAPUA NEW GUINEA                                PG      PNG     598
PARAGUAY                                        PY      PRY     600
PERU                                            PE      PER     604
PHILIPPINES                                     PH      PHL     608
PITCAIRN                                        PN      PCN     612
POLAND                                          PL      POL     616
PORTUGAL                                        PT      PRT     620
PUERTO RICO                                     PR      PRI     630
QATAR                                           QA      QAT     634
REUNION                                         RE      REU     638
ROMANIA                                         RO      ROU     642
RUSSIAN FEDERATION                              RU      RUS     643
RWANDA                                          RW      RWA     646
SAINT HELENA                                    SH      SHN     654
SAINT KITTS AND NEVIS                           KN      KNA     659
SAINT LUCIA                                     LC      LCA     662
SAINT PIERRE AND MIQUELON                       PM      SPM     666
SAINT VINCENT AND THE GRENADINES                VC      VCT     670
SAMOA                                           WS      WSM     882
SAN MARINO                                      SM      SMR     674
SAO TOME AND PRINCIPE                           ST      STP     678
SAUDI ARABIA                                    SA      SAU     682
SENEGAL                                         SN      SEN     686
SERBIA AND MONTENEGRO                           CS      SCG     891
SEYCHELLES                                      SC      SYC     690
SIERRA LEONE                                    SL      SLE     694
SINGAPORE                                       SG      SGP     702
SLOVAKIA                                        SK      SVK     703
SLOVENIA                                        SI      SVN     705
SOLOMON ISLANDS                                 SB      SLB     090
SOMALIA                                         SO      SOM     706
SOUTH AFRICA                                    ZA      ZAF     710
SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS    GS      SGS     239
SPAIN                                           ES      ESP     724
SRI LANKA                                       LK      LKA     144
SUDAN                                           SD      SDN     736
SURINAME                                        SR      SUR     740
SVALBARD AND JAN MAYEN ISLANDS                  SJ      SJM     744
SWAZILAND                                       SZ      SWZ     748
SWEDEN                                          SE      SWE     752
SWITZERLAND                                     CH      CHE     756
SYRIAN ARAB REPUBLIC                            SY      SYR     760
TAIWAN                                          TW      TWN     158
TAJIKISTAN                                      TJ      TJK     762
TANZANIA, UNITED REPUBLIC OF                    TZ      TZA     834
THAILAND                                        TH      THA     764
TIMOR-LESTE                                     TL      TLS     626
TOGO                                            TG      TGO     768
TOKELAU                                         TK      TKL     772
TONGA                                           TO      TON     776
TRINIDAD AND TOBAGO                             TT      TTO     780
TUNISIA                                         TN      TUN     788
TURKEY                                          TR      TUR     792
TURKMENISTAN                                    TM      TKM     795
TURKS AND CAICOS ISLANDS                        TC      TCA     796
TUVALU                                          TV      TUV     798
UGANDA                                          UG      UGA     800
UKRAINE                                         UA      UKR     804
UNITED ARAB EMIRATES                            AE      ARE     784
UNITED KINGDOM                                  GB      GBR     826
UNITED STATES                                   US      USA     840
UNITED STATES MINOR OUTLYING ISLANDS            UM      UMI     581
URUGUAY                                         UY      URY     858
UZBEKISTAN                                      UZ      UZB     860
VANUATU                                         VU      VUT     548
VATICAN CITY STATE (HOLY SEE)                   VA      VAT     336
VENEZUELA                                       VE      VEN     862
VIET NAM                                        VN      VNM     704
VIRGIN ISLANDS (BRITISH)                        VG      VGB     092
VIRGIN ISLANDS (U.S.)                           VI      VIR     850
WALLIS AND FUTUNA ISLANDS                       WF      WLF     876
WESTERN SAHARA                                  EH      ESH     732
YEMEN                                           YE      YEM     887
ZAMBIA                                          ZM      ZMB     894
ZIMBABWE                                        ZW      ZWE     716
Iptables
Si queremos bloquear una dirección ip o un rango en nuestro firewall, con crear una regla iptables podría ser suficiente:
iptables -I INPUT -s 1.2.3.4 -j DROP
iptables -I INPUT -s 1.2.0.0/16 -j DROP
Pero qué sucedería si queremos neutralizar un país entero con varios cientos de miles (y a veces hasta millones) de ips. Hacerlo con estas reglas de iptables no es algo muy recomendable, ya que pueden saturar el firewall.
En este punto muchos optarán por hacerlo a la inversa, o sea dejar pasar las ips que nos interesan y denegar el resto, sin embargo en redes flexibles (abiertas o semi-abiertas) sería un trabajo de tiempo completo para el operador IT, ya que tendría que validar cada ip que solicite un usuario de su red local, convirtiéndose en una auténtica locura, no viable para estos escenarios.
Pero esto no significa que nos quedemos de brazos cruzados. Hay ips relacionadas con spam, o de países de "dudosa reputación", que podemos bloquear, sin que esto implique una carga excesiva tanto a nuestro firewall como a nuestro trabajo.
sslcop
Anteriormente expusimos varias herramientas que hacen esto posible; entre ellas el módulo Xtables-addons de Netfilter Iptables (vea el tutorial), SSL Cop de Securybydefault (para certificados CAs), GeoLocalización por Apache, entre otras, pero algunas han quedado obsoletas, como es el caso de Xtables, que funcionó bien en kernel 2.x, pero presenta problemas de compatibilidad con los nuevos kernels 3.x, y hay que compilar el kernel para instalarla, lo cual no siempre es conveniente, y SSL Cop no ha recibido actualizaciones en más de 2 años.
Existen otros proyectos con el mismo propósito, como ipfilterXIPlistI-blocklistcountryipblocksip2location, entre otros, en su mayoría relacionados con Netfilter, al igual que nuestro candidato de hoy, ipset, el cual utiliza reglas tipo ipdeny <country>, para el bloqueo de ips, que es tan bueno, que usted olvidará cualquier otro método de bloqueos de ips, por su velocidad y flexibilidad (Vea el benchmarks AQUI).
Antes de comenzar
Las reglas que explicaremos a continuación están basadas en Debian/Ubuntu, IPv4 y formato CIDR. Se recomienda utilizar kernel 3.1x, iptables v1.4.x o superior y ipset v6.20x. También se sugiere realizar la instalación directamente de los repositorios:
sudo apt-get install ipset
Muy Importante
Los programas y reglas que se describen en este post consumen gran cantidad de recursos de su sistema. Su uso excesivo puede llevar a su servidor al colapso. Úselos con moderación.
Ipset + ipdeny
Las reglas ipset son sencillas. Basta con echarle una mirada al tutorial y tendremos todas las opciones, entonces solo nos resta poner algunos ejemplos para automatizarlo.
Asumiendo que tenemos un script de iptables (que es lo más aconsejable) con nuestras reglas personales, entonces vamos a agregar ipset.
Primero crearemos un script que descargará la base de datos de ips geolocalizadas por países, para que la labor de bloqueo se haga directamente en nuestro terminal y/o servidor y no tener que descargar cada bloque de manera independiente, según el país que queramos restringir.
Abrimos el editor de texto y pegamos el siguiente código
#!/bin/bash
### BEGIN INIT INFO
# Provides:          geozones
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable service provided by daemon.
### END INIT INFO
if [ ! -d /etc/zones ]; then mkdir -p /etc/zones; fi
wget -c --retry-connrefused -t 0 http://www.ipdeny.com/ipblocks/data/countries/all-zones.tar.gz && tar -C /etc/zones -xvzf all-zones.tar.gz && rm -R all-zones.tar.gz
Y lo guardamos con un nombre, en este caso elegimos geozone.sh en la carpeta /etc/init.d/. Le damos permisos de ejecución.
sudo chmod +x /etc/init.d/geozones.sh
Y lo programamos en el cron para que actualice periódicamente. Por ejemplo semanalmente.
sudo crontab -e
@weekly /etc/init.d/geozones.sh >/dev/null 2>&1
Este script crea una carpeta en /etc llamada zones (si ya existe no la crea) y descarga y descomprime la base de datos ipdeny a /etc/zones (puede ser cualquier otra carpeta).
El paso siguiente es abrir nuestro script de iptables, y antes de cualquier regla propia, agregamos el bloqueo por geolocalización. En el siguiente ejemplo, vamos bloquear a china y rusia. Si quiere saber exactamente cuál es la nomenclatura usada para cada país (para poder agregar los países a su regla de iptables), puede consultarla AQUI.
#!/bin/bash
# BLACKZONE (seleccione el pais o la ip/rango a bloquear)
# http://www.ipdeny.com/ipblocks/
ipset=/sbin/ipset
iptables=/sbin/iptables
$ipset -F
$ipset -N -! blackzone hash:net maxelem 1000000
for ip in $(cat /etc/zones/{cn,ru}.zone /etc/acl/blackips); do
$ipset -A blackzone $ip
done
$iptables -A FORWARD -p tcp -m set --match-set blackzone src -j DROP
En el ejemplo anterior utilizamos dos variables. iptables (representando a /sbin/iptables) y ipset (representando a /sbin/ipset) con el propósito de no escribir esta información y en su reemplazo poner $iptables y $ipset.
Luego hacemos un flush de las reglas almacenadas en ipset (ipset -F) y creamos nuestra lista negra para ipset, la cual llamamos blackzone (puede ser cualquier nombre). Le agregamos el parámetro -! que significa -exist, que me permite ignorar el error que se genera cuando se corre más de una vez el script y se vuelven a agregar los mismos bloques CIDR del país a bloquear.
También utilizamos hash:net que por lo general se utiliza para almacenar múltiples bloques de ips diferentes (lo contrario a hash:ip que sirve para host o ips individuales. También existen otros como hash:mac, etc). Por defecto tiene 65.536 elementos, sin embargo se recomienda elevar este valor con el parámetro maxelem. En este caso lo hemos subido a 1000000 (ya que son muchos bloques)
Luego hacemos un cat a los archivos que contienen las ips de los países a bloquear, en este caso cn.zone y ru.zone y los agregamos a la regla de ipset que creamos (blackzone). Finalmente iptables bloquea a blackzone utilizando la regla -m set --match-set blackzone src. Esta "engancha" el conjunto IP con el interruptor -m y se establece la asociación con blackzone y aplica a la ip destino src y cerramos con DROP.
Nota: Tenga en cuenta la cabecera de los script (/bin/bash vs /bin/sh). El comando cat no es capaz de leer los corchetes con cabecera /bin/sh ({cn,ru}.zone) por tanto para evitar este y otros errores de compatibilidad se recomienda /bin/bash. Para mayor información consulte el portal askubuntu.
Finalmente verificamos que la regla funcione.
sudo iptables -L
Y si queremos agregar algunos rangos de ips adicionales a nuestra lista negra de ipset blackzone, podemos hacerlo directamente por terminal. Ejemplo:
sudo ipset add blackzone 1.1.1.1/32
sudo ipset add blackzone 1.1.2.0/24
Y verificamos que se hayan agregado con el comando:
sudo ipset list
Y debería salir algo similar a lo siguiente:
Y para vaciar las ips
sudo ipset flush
Ipset + listas negras personalizadas
Podemos crear nuestras propias listas negras de ips, rangos de ips, CIDR, bien sea a partir de las existentes o desde 0. Como habíamos mencionado, en internet existen muchas de estas listas, tales como la ya mencionada ipdeny, y también countryipblocksip2location, etc. También puede incluir las utilizadas por los nodos proxys (Tor, ultrasurf, etc). Incluso en el post Firewall IV publicamos algunas de estas superlistas.
Y creamos una acl que contenga estas ips, y la ponemos en algún lugar de nuestro servidor y/o terminal y modificamos la regla de iptables descrita para que la lea.
En el siguiente ejemplo creamos la acl blackips que contiene las ips a denegar y la guardamos en algún lugar (ejemplo: /home/usuario/blackips) y la creamos también en ipset con el nombre de blackips y luego la denegamos. En este caso reemplazamos hash:net por hash:ip, que es el que se utiliza para bloquear IPs independientes.
#!/bin/bash
iptables=/sbin/iptables
ipset=/sbin/ipset
$ipset -F
$ipset -N -! blackips hash:ip maxelem 1000000
for ip in $(cat /home/usuario/blackips); do $ipset -A blackips $ip; done
$iptables -A INPUT -p tcp -m set --match-set blackips src -j DROP
hash:mac
Para poder bloquear direcciones macs con ipset, debe verificar la versión. Los repositorios de Ubuntu 14.04 traen la v6.20.1 y hash:mac solo está disponible a partir de la v6.22. Por tanto debe actualizarla, ya sea en el sitio oficial de descarga (tar -jxvf ipset-6.26.tar.bz2) o por git en el siguiente orden:
git clone git://git.netfilter.org/iptables.git
cd iptables
sudo git pull
git clone git://git.netfilter.org/libmnl.git
cd libmnl
sudo git pull
git clone git://git.netfilter.org/ipset.git
cd ipset
sudo git pull
Sin embargo es probable que le salga el mensaje "Already up-to-date". En ese caso, verifique con ipset version y si no sale el mensaje ipset v6.26, protocol version: 6, pruebe compilando (Lea el archivo README dentro de la carpeta ipset -./autogen.sh, ./configure, make, make modules, make install, make modules_install, make tests, make clean, make modules_clean-) y si tampoco funciona esto se debe a que "the ipset source supports kernels released by kernel.org. It may or may not work on distribution-specific kernel sources". Entonces no queda otro remedio que bloquear macs con una regla de iptables:
for mac in `cat /home/usuario/blackmacs`; do
 $iptables -A INPUT -m mac --mac-source $mac -j DROP
done
Donde /home/usuario/blackmacs es la ruta hacia la acl blackmacs (que puede ponerle cualquier nombre y en cualquier ruta) que contiene las direcciones macs negras.
Puede ser más específico con la regla, por ejemplo, agregando el protocolo y puerto (Ej: -p tcp --destination-port 22) o la interfaz de red (ej: -o eth1, -i eth0, etc)
Ipset + iptables (Protección externa)
También puede hacer bloqueos personalizados con iptables + ipset. Por ejemplo, supongamos que quiere monitorear algunos puertos sensibles en la entrada de su servidor (específicamente la eth que recibe el internet desde el exterior) o el acceso a algunas carpetas y archivos, con el objeto de que si alguien de afuera de su red local intenta acceder a su servidor, este lo bloquee automáticamente. Para esto podemos utilizar una regla iptables. En el siguiente ejemplo asumimos que eth0 es la que recibe internet desde el exterior y vamos a bloquear cualquier intento de acceso a los puertos 80,8080,21,22,3000,10000,5900,139,443,445,3306,20005 y de paso a las zonas esenciales del servidor como /etc/passwd, /etc/shadow y /etc/group
# Proteccion del servidor
iptables=/sbin/iptables
internet=eth0
$iptables -A INPUT -p tcp -i $internet -m multiport --dports 80,8080,21,22,3000,10000,5900,139,443,445,3306,20005 -j NFLOG --nflog-prefix 'Illegal: server access ports'
$iptables -A INPUT -p tcp -i $internet -m multiport --dports 80,8080,21,22,3000,10000,5900,139,443,445,3306,20005 -j DROP
$iptables -A INPUT -m string --string "/etc/passwd" --algo kmp  -j NFLOG --nflog-prefix 'Illegal: passwd access'
$iptables -A INPUT -m string --string "/etc/passwd" --algo kmp -j DROP
$iptables -A INPUT -m string --string "/etc/shadow" --algo kmp  -j NFLOG --nflog-prefix 'Illegal: shadow access'
$iptables -A INPUT -m string --string "/etc/shadow" --algo kmp -j DROP
$iptables -A INPUT -m string --string "/etc/group" --algo kmp  -j NFLOG --nflog-prefix 'Illegal: group access'
$iptables -A INPUT -m string --string "/etc/group" --algo kmp -j DROP
Como podemos ver, no solo hemos bloqueado estos accesos sino que los registros son manejados por NFLOG, por tanto irán a parar al log ubicado en /var/log/ulog/syslogemu.log. Un intento de acceso podría quedar reflejado de la siguiente manera:
Oct 28 14:07:38 adminred Illegal: server access ports IN=eth0 OUT= MAC=00:99:88:77:66:55:AA:BB:CC:DD:EE:FF:08:00 SRC=86.108.3.167 DST=190.99.99.99 LEN=40 TOS=00 PREC=0x00 TTL=63 ID=43260 PROTO=TCP SPT=50208 DPT=443 SEQ=1 ACK=0 WINDOW=0 RST URGP=0 MARK=0
Nomenclatura del log:
Oct 28 14:07:38 (fecha y hora del registro del log) 
adminred (nombre del servidor) 
Illegal: server access ports (mensaje de registro que proporciona la regla iptables) 
IN=eth0 (interface de red conectada directamente al modem o proveedor de internet) 
MAC=00:99:88:77:66:55 (dirección mac de la DST, o sea interface eth0 IP 190.99.99.99) 
AA:BB:CC:DD:EE:FF (dirección mac del modem o proveedor de internet) 
08:00 (significa que es TCP) 
SRC=86.108.3.167 (IP de origen - de donde intentan acceder ilegalmente a nuestro servidor)
DST=190.99.99.99 (ip destino IN=eth0) 
SPT=50208 (puerto de origen) 
DPT=443 (puerto de destino)
Nota: las peticiones ff:ff:ff:ff:ff:ff son de broadcast
En este caso específico sabemos que la ip 86.108.3.167 (esta ip es real y fue utilizada en un ataque contra un servidor en latinoamérica) es el origen del ataque, por tanto simplemente la bloqueamos con el siguiente script bash:
#!/bin/bash
cat /var/log/ulog/syslogemu.log | grep -Eo 'SRC=[0-9.]+' | sed 's:SRC=::' >> /home/usuario/blackips
sort -o /home/usuario/blackips -u /home/usuario/blackips -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n /home/usuario/blackips
cat /dev/null > /var/log/ulog/syslogemu.log
O puede utilizar sed en reemplazo de grep
cat /var/log/ulog/syslogemu.log | sed 's/.*SRC=\([0-9.]\+\).*/\1/' infile | sort -u > /home/usuario/blackips
Este script lee el log, extrae las ips de origen (SRC) y la envía a la ACL de ipset explicada anteriormente (/home/usuario/blackips pero puede ser cualquier ruta) y finalmente limpia el log.
Podemos automatizar esta labor, guardando el script en init.d, le damos permisos chmod +x y lo programamos en el cron para que lea regularmente el log y bloquee estas ips.
Otros comandos de ipset
# Listar ipset
sudo ipset list
# Eliminar nuestra regla de ipset (blackzone)
sudo ipset destroy blackzone
# Eliminar todas
sudo ipset destroy
# Antes de eliminar hay que borrar las reglas de iptables que las estáun usando
iptables -F
iptables -X
Ipset + iblocklist y otras listas negras de ips
Otro método de bloqueo con ipset es el descrito por el portal xmodulo.com, el cual utiliza otra base de datos llamada iblocklist. También puede consultar el post Protegiendo nuestro servidor (algo mas que iptables), donde encontrará muchos enlaces a listas de ips de países.
Errores frecuentes
ipset v6.20.1: Syntax error: cannot resolve 'xxx.com' to an IPv4 address: Name or service not known
Syntax error: cannot parse xxx.com: resolving to IPv4 address failed
Si se utilizan en lugar de direcciones IP o números de servicio, nombres de host o nombres de servicios con guión en el nombre, el nombre de host o nombre de servicio deben ir entre corchetes. Ejemplo: ipset add foo [test-hostname],[ftp-data]
ipset v6.20.1: Syntax error: Second element is missing from 1.160.0.0/12
Este error es frecuente en compilaciones y se refiere al rango CIDR no válido, versiones incompatibles y otras situaciones. Puede consultar el siguiente enlace
Aclaratoria
Es necesario esclarecer que con ipset o cualquier otro método, no se garantiza el bloqueo completo a un país, y tampoco lo consideramos prudente, ya que las ips cambian de mano constantemente y puede que una ip sea hoy de China y mañana de Francia. Es por eso que recomendamos la lectura de los logs y bloquear con ipset solamente aquellas ips que nos afecten directamente (y no necesariamente un país entero). Esto agilizaría mucho nuestro firewall.
NtopNG
Para acompañar a ipset, que mejor que un aplicativo web de geolocalización. En el post Network Monitor, vimos algunas herramientas que monitorean nuestra red local, y entre ellas NtopNG, que incluye esta posibilidad. Lo instalamos...
sudo add-apt-repository ppa:cavedon/ntop --yes
sudo apt-get update && sudo apt-get -y --force-yes -f install libpcap-dev libglib2.0-dev libgeoip-dev redis-server libxml2-dev libnl1 && sudo apt-get -y --force-yes -f install ntopng ntopng-data
sudo service redis-server restart && sudo service ntopng restart
Y creamos un script, al cual llamaremos updategeoip.sh para descargar y mantener las bases de datos geoip de Ntopng actualizadas.
#!/bin/bash
### BEGIN INIT INFO
# Provides:          Geoip update
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable service provided by daemon.
### END INIT INFO
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# # Functions
# ==========================================================================

#uso() {
echo -n "`basename $0`, v"
echo -n $version | awk '{printf $3}'
echo ". By Luis Palacios"
echo "Actualizado por Maravento.com"
echo "Uso: updategeoip.sh [-h]"
echo " -h help"
echo " "
echo " "
exit -1 # Salimos
}

# Analisis de las opciones
while getopts "h" Option
do
case $Option in

# EOM, no comments
h ) uso;;

# Resto de argumentos, error.
* ) uso;;

esac
done
# ================================================================
#
echo
#
cd /usr/share/ntopng/httpdocs/geoip
wget -nc http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz
gunzip -f GeoLiteCity.dat.gz
#
cd /usr/share/ntopng/httpdocs/geoip
wget -nc http://geolite.maxmind.com/download/geoip/database/GeoLiteCityv6-beta/GeoLiteCityv6.dat.gz
gunzip -f GeoLiteCityv6.dat.gz
#
cd /usr/share/ntopng/httpdocs/geoip
wget -nc http://download.maxmind.com/download/geoip/database/asnum/GeoIPASNum.dat.gz
gunzip -f GeoIPASNum.dat.gz
#
cd /usr/share/ntopng/httpdocs/geoip
wget -nc http://download.maxmind.com/download/geoip/database/asnum/GeoIPASNumv6.dat.gz
gunzip -f GeoIPASNumv6.dat.gz
Finalmente accedemos a http://localhost:3000 con el usuario admin y contraseña admin (la podemos cambiar en las preferencias)...
Y vamos a la geolocalización y ahí podemos detectar los países que tienen tráfico con nuestra red local y eventualmente bloquearlos con iptables.
Imagen cortesía de Blog.elhacker.net
Con la tecnología de Blogger.