geolocation

Nginx Proxy Manager GeoBlocking

GeoBlocking Nginx Proxy Managerilla

Geoblokki tarkoittaa tiettyjen maiden tai alueiden IP-osoitteiden estämistä pääsemästä palveluun. Sen tarkoituksena on parantaa tietoturvaa ja vähentää turhaa liikennettä esimerkiksi silloin, kun palvelua käytetään vain tietyssä maassa. Näin voidaan estää haitallisia kirjautumisyrityksiä ja pienentää palvelimen kuormitusta.

Dockerin asennus

Asennetaan Docker ensin kätevästi heidän valmiilla bash scriptillä.

curl -fsSL https://get.docker.com | sudo sh

Tehdään kansio Nginxille.

mkdir -p /docker/npm

cd /docker/npm

Luodaan Docker compose tiedosto johon kaikki konfiguraatiot tulevat.

nano compose.yaml

🐳
compose.yaml
services:
  app:
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      # These ports are in format <host-port>:<container-port>
      - '80:80' # Public HTTP Port
      - '443:443' # Public HTTPS Port
      - '81:81' # Admin Web Port
      # Add any other Stream port you want to expose
      # - '21:21' # FTP
    environment:
      # Mysql/Maria connection parameters:
      DB_MYSQL_HOST: "db"
      DB_MYSQL_PORT: 3306
      DB_MYSQL_USER: "npm"
      DB_MYSQL_PASSWORD: "npm"
      DB_MYSQL_NAME: "npm"
      # Uncomment this if IPv6 is not enabled on your host
      # DISABLE_IPV6: 'true'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
      - ./data/nginx/custom:/etc/nginx/conf.d/custom
    depends_on:
      - db

  db:
    image: 'jc21/mariadb-aria:latest'
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: 'npm'
      MYSQL_DATABASE: 'npm'
      MYSQL_USER: 'npm'
      MYSQL_PASSWORD: 'npm'
    volumes:
      - ./mysql:/var/lib/mysql

  geoip-upd:
    container_name: geoip-upd
    image: maxmindinc/geoipupdate:latest
    restart: unless-stopped
    volumes:
      - ./data/geoip2:/usr/share/GeoIP
    environment:
      TZ: "Europe/Helsinki"
      GEOIPUPDATE_ACCOUNT_ID: 1234567
      GEOIPUPDATE_LICENSE_KEY: "keykeykeykeykeykeykeykey"
      GEOIPUPDATE_EDITION_IDS: "GeoLite2-City GeoLite2-Country GeoLite2-ASN"    #Databaset joita tarvimme
      GEOIPUPDATE_FREQUENCY: 12                #Kuinka usein database päivittyy
      GEOIPUPDATE_PRESERVE_FILE_TIMES: 1       #Todellinen aika tiedostolle

Seuraavaksi ladataan tarvittavat moduulit.

nano /docker/npm/data/nginx/custom/root_top.conf

root_top.conf
load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so;
load_module /usr/lib/nginx/modules/ngx_stream_geoip2_module.so;

Uudelleen käynnistetään containeri jotta muutokset tulevat voimaan.

docker exec -it docker-npm nginx -s reload

Tarkista kuitenkin oman containerin nimi seuraavalla komennolla.

docker ps

Tietokannan lataaminen

Mene osoitteeseen https://www.maxmind.com/en/geolite2/signup

Käytämme maxmindin tarjoavaa geoip datasettejä, ne päivittyvät yllättävän nopeasti. Luo uusi license key ja ota talteen account ID, License Key sekä nämä:

GeoLite2-ASN, GeoLite2-Country ja GeoLite2-City

Lisättyäsi tarvittavat tunnukset Docker Compose tiedostoon ja käynnistämällä Containerin näemme tiedostot.

docker compose up -d

ls -l /docker/npm/data/geoip2

Tietokannan konfigurointi Nginx Proxy Managerille

Luodaan uusi tiedosto joka käsittelee tietokannan sisällön ja parsii sieltä mm.country coden, nimen, cityn sekä regionin. Tässä ohjeessa päästämme vain Saksasta liikenteen.

nano /docker/npm/data/nginx/custom/http_top.conf

http_top.conf
charset utf-8;
geoip2 /data/geoip2/GeoLite2-City.mmdb {
        auto_reload 3h;
        $geoip2_metadata_country_build metadata build_epoch;
        $geoip2_data_country_code default=XX source=$remote_addr country iso_code;
        $geoip2_data_country_name default=- country names de;
        $geoip2_data_city_name default=- city names de;
        $geoip2_data_region_name default=- subdivisions 0 names de;
}
geo $allowed_ip {
        default no;             # Blockaa oletuksena
        10.10.1.0/24 yes;     # Whitelistaa locaali verkko
}

map $geoip2_data_country_code $allowed_country {
        default $allowed_ip;
        DE yes;                 # Vain Saksa voit lisätä lisää maita
}

#Formaatti logille, myöhemmin myös Grafanaa varten
log_format json_analytics escape=json '{'
       '"time_local": "$time_local", '
       '"remote_addr": "$remote_addr", '
       '"request_uri": "$request_uri", '
       '"status": "$status", '
       '"server_name": "$server_name", '
       '"request_time": "$request_time", '
       '"request_method": "$request_method", '
       '"bytes_sent": "$bytes_sent", '
       '"http_host": "$http_host", '
       '"http_x_forwarded_for": "$http_x_forwarded_for", '
       '"http_cookie": "$http_cookie", '
       '"server_protocol": "$server_protocol", '
       '"upstream_addr": "$upstream_addr", '
       '"upstream_response_time": "$upstream_response_time", '
       '"ssl_protocol": "$ssl_protocol", '
       '"ssl_cipher": "$ssl_cipher", '
       '"http_user_agent": "$http_user_agent", '
       '"remote_user": "$remote_user" '
   '}';

Login näet tällä komennolla.

tail -f /dockers/nginx-proxym/data/logs/proxy-host-%HOSTID%_access-geo.log

Lisätään vielä Proxy Manageriin.

Avaa Nginx Proxy manager WebUI ja paina Proxy Hosts, sen jälkeen Add proxy Host.

Kirjoita haluamasi domain, paikallinen osoite sekä portti. Lisää vielä asetukset Block Common Exploits sekä Websocket Support.

Seuraavaksi paina oikealta ylhäältä asetus kuvaketta ja lisää seuraava koodi.

if ($allowed_country = no) {
	return 444;
}

Nyt on kaikki valmista, että geoblokki on yksinkertainen mutta tehokas keino parantaa palvelun turvallisuutta ja hallittavuutta. Toteuttamalla sen Nginx Proxy Managerin avulla saamme helposti ylläpidettävän ratkaisun, jota voidaan tarvittaessa muokata nopeasti. Näin varmistamme, että palvelu pysyy suojattuna ja toimii optimaalisesti vain halutuille käyttäjille.