Country blocking using Nginx with GeoIP2 in Ubuntu 16.04

After try out the country block with multiple module, including the previous Nginx http_geoip_module, until I manage to figure it out and make it work, than only I found out that GeoIP version 1 will be stop update soon by Maxmind company, where they encourage developer to move to the next generation of IP database, which is GeoIP2. After sometime of figure out, finally I manage to make the module functioning as per what I expected.

The following are the step that I make it work from the fresh installation of ubuntu 16.04 server. Basically the following script did the following thing

  1. 1. Add the maxmind repository into the Ubuntu default repository list
  2. 2. Update the repo
  3. 3. Install all necessary module that needed in order to do the installation
  4. 4. Create the working directory in the home folder
  5. 5. Download the pcre source code, compile and install it
  6. 6. Download the zlib source code, compile and install it
  7. 7.  Download the openssl source code, compile and install it
  8. 8. Download the geoip2 module and decompress it
  9. 9. Download the Nginx 1.15.0 source code and decompress it
  10. 10. Configure the Nginx with all the necessary module
  11. 11. Compile and install the Nginx 1.15
  12. 12. Crate the service file and move to the  /etc/systemd/system/
  13. 13. Create the auto start for the Nginx when the server boot up
  14. 14. Download the free GeoIP2 database from Maxmind website and decompress it
  15. 15. Configure the Nginx.conf to include the GeoIP2 database
  16. 16. Create the block country list and include it into the virtual server configuration

 

sudo add-apt-repository ppa:maxmind/ppa && \

sudo apt update && sudo apt upgrade -y && \

sudo apt install build-essential dh-autoreconf unzip wget curl libmaxminddb0 libmaxminddb-dev mmdb-bin checkinstall -y && \

sudo mkdir ~/nginx-dev && cd ~/nginx-dev && \

sudo wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.42.tar.gz && \
sudo tar -zxf pcre-8.42.tar.gz && \
cd pcre-8.42 && \
sudo ./configure && \
sudo make && \
sudo make install && \
cd .. && \

sudo wget http://zlib.net/zlib-1.2.11.tar.gz && \
sudo tar -zxf zlib-1.2.11.tar.gz && \
cd zlib-1.2.11 && \
sudo ./configure && \
sudo make && \
sudo make install && \
cd .. && \

sudo wget https://www.openssl.org/source/openssl-1.0.2o.tar.gz && sudo tar xzvf openssl-1.0.2o.tar.gz && \
cd openssl-1.0.2o && \
sudo ./config --prefix=/usr && \
sudo make && \
sudo make install && \
cd .. && \

sudo rm *.gz && \

sudo wget https://github.com/leev/ngx_http_geoip2_module/archive/master.zip && \
sudo unzip master.zip && \
sudo mv ngx_http_geoip2_module-master ngx_http_geoip2_module && \
sudo rm master.zip && \

cd ~/nginx-dev && \
sudo wget https://nginx.org/download/nginx-1.15.0.tar.gz && \
sudo tar zxf nginx-1.15.0.tar.gz && \
cd nginx-1.15.0 && \

sudo ./configure \
--prefix=/usr/share/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--user=www-data \
--group=www-data \
--build=Ubuntu \
--http-client-body-temp-path=/var/lib/nginx/body \
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
--http-proxy-temp-path=/var/lib/nginx/proxy \
--http-scgi-temp-path=/var/lib/nginx/scgi \
--http-uwsgi-temp-path=/var/lib/nginx/uwsgi \
--with-openssl=../openssl-1.0.2o \
--with-openssl-opt=enable-ec_nistp_64_gcc_128 \
--with-openssl-opt=no-nextprotoneg \
--with-openssl-opt=no-weak-ssl-ciphers \
--with-openssl-opt=no-ssl3 \
--with-pcre=../pcre-8.42 \
--with-pcre-jit \
--with-zlib=../zlib-1.2.11 \
--with-compat \
--with-file-aio \
--with-threads \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_mp4_module \
--with-http_random_index_module \
--with-http_realip_module \
--with-http_slice_module \
--with-http_ssl_module \
--with-http_sub_module \
--with-http_stub_status_module \
--with-http_v2_module \
--with-http_secure_link_module \
--with-mail \
--with-mail_ssl_module \
--with-stream \
--with-stream_realip_module \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-debug \
--add-module=../ngx_http_geoip2_module \
--with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2' \
--with-ld-opt='-Wl,-z,relro -Wl,--as-needed' && \

sudo make && \
sudo make install && \
sudo mkdir -p /var/lib/nginx && \
sudo ldconfig && \

sudo echo "
[Unit]
Description=A high performance web server and a reverse proxy server
After=network.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
TimeoutStopSec=5
KillMode=mixed

[Install]
WantedBy=multi-user.target " > ~/nginx.service && \

sudo mv ~/nginx.service /etc/systemd/system/nginx.service && \

sudo systemctl start nginx.service && sudo systemctl enable nginx.service && \

sudo mkdir /etc/nginx/geoip && cd /etc/nginx/geoip && \

sudo wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz && \

sudo gunzip GeoLite2-Country.mmdb.gz

 

After the above script finish run, you should have your Nginx 1.15.0 + ngx_http_geoip2_module + GeoLite2 database ready in your server. If you wish to double check is the ngx_http_geoip2_module install and ready in your Nginx, you may always run the following command, you should see the module highlighted in red color, if not, you may need to go back to the above script and try to run it line by line to debug what’s going wrong.

nginx -V 2>&1|grep --color=always ngx_http_geoip2_module

 

Once confirm the Nginx module is success install, we may proceed to do the configuration on the Nginx.conf, add the following script into your nginx.conf (Normally will be at the /etc/nginx/ directory)

sudo vim /etc/nginx/nginx.conf

Add the following script into the file


http{

...

geoip2 /etc/nginx/geoip/GeoLite2-Country.mmdb{
$geoip2_data_country_code default=US country iso_code;
$geoip2_data_country_name country names en;
}

include /etc/nginx/geoip/whitelistip;

...

server{

...

include /etc/nginx/GeoIP/geoblocker;

...

}

}

 

Once done to include the GeoIP2 database into the Nginx, than we may create the whitelist file

sudo vim /etc/nginx/geoip/whitelistip

 

Add in the following script into the file

geo $whitelistip {
default 0;
61.6.79.253/32 1;
10.0.0.0/8 1;
192.168.0.0/16 1;
}

 

Create another file to store the logic of the country block, so that you may include it for more than one server directive

sudo vim /etc/nginx/geoip/geoblocker

 

Add in the following script into the file


set $geoblock 0;
if ($geoip2_data_country_code!~ (DK|NO|SE)) {
set $geoblock 1;
}

if ($whitelistip = 1){
set $geoblock 0;
}

if ($geoblock = 1){
rewrite ^ http://www.google.com/;
}

 

You may try using any browser to access your Nginx web server, if the IP is not block, you should get the default nginx page such as following.

 

If you add your country code to block list, than you should be redirect to Google home page.

 

Hopefully this sharing help and please do leave your comment if you have any better suggestion to share with me or other.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: