Nginx

GeoIP Module ใน Nginx — บล็อกตามประเทศบน Cloud VPS

GeoIP Module เป็นฟีเจอร์ที่มีประสิทธิภาพในการจัดการ IP Address ของผู้เข้าชม (visitors) โดยแยกแยะตามตำแหน่งภูมิศาสตร์ การใช้งาน GeoIP Module ใน Nginx ช่วยให้นักพัฒนา (developers) สามารถควบคุมการเข้าถึงเนื้อหา (content access) บล็อก (block) ผู้เข้าชมจากประเทศที่ไม่ต้องการ เปลี่ยนเส้นทาง (redirect) ไปยังเนื้อหาที่เหมาะสม หรือแสดง (deliver) เนื้อหาที่แตกต่างกันตามตำแหน่งภูมิศาสตร์ได้อย่างมีประสิทธิภาพ

บทความนี้จะอธิบายรายละเอียดเกี่ยวกับการใช้ GeoIP Module ทั้งการติดตั้ง (installation) การตั้งค่า (configuration) และการนำไปใช้งานในสถานการณ์จริง (real-world scenarios) รวมถึง GeoIP2 Module ที่มีความสามารถเพิ่มเติม

GeoIP Module คืออะไร

GeoIP Module (ngx_http_geoip_module) เป็น built-in module ใน Nginx ที่ใช้ในการระบุตำแหน่งภูมิศาสตร์ของผู้เข้าชมตามหมายเลข IP Address โดยใช้ฐานข้อมูล GeoIP (GeoIP Database) ที่จัดทำโดย MaxMind

ฟีเจอร์หลักของ GeoIP Module ได้แก่:

  • ระบุประเทศ (country code) จากไอพี
  • ระบุเมือง (city) ละติจูด ลองจิจูด
  • ใช้ในการปฏิเสธการเข้าถึง (deny/allow)
  • ตั้งค่าตัวแปร (variables) สำหรับการประมวลผลเพิ่มเติม
  • ทำงานได้เร็วและใช้ทรัพยากรน้อย (low-overhead)

การติดตั้ง GeoIP Module และฐานข้อมูล

ขั้นตอนแรกในการใช้ GeoIP Module คือการตรวจสอบว่า Nginx ของคุณมี module นี้รวมอยู่แล้วหรือไม่

ตรวจสอบ GeoIP Module:

nginx -V

ค้นหา “geoip” ในผลลัพธ์ หากไม่มี ต้องคอมไพล์ Nginx ใหม่พร้อมกับ module นี้

ติดตั้ง GeoIP Module (สำหรับ Debian/Ubuntu):

sudo apt-get update
sudo apt-get install nginx-module-geoip

ติดตั้ง MaxMind GeoLite2 Database:

sudo apt-get install geoipupdate

ดาวน์โหลดฐานข้อมูล GeoLite2 ที่ไม่มีค่าใช้จ่าย (free) จากเว็บไซต์ MaxMind หรือใช้ geoipupdate:

cd /usr/share/GeoIP/
sudo wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.tar.gz
sudo tar -xzf GeoLite2-Country.tar.gz
sudo cp GeoLite2-Country_*/GeoLite2-Country.mmdb .

สำหรับ GeoLite2-City ซึ่งให้ข้อมูลเนื้อที่ละเอียดกว่า:

sudo wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
sudo tar -xzf GeoLite2-City.tar.gz
sudo cp GeoLite2-City_*/GeoLite2-City.mmdb .

การตั้งค่า geoip_country และ geoip_city

เมื่อติดตั้ง module และฐานข้อมูลเสร็จแล้ว ต้องตั้งค่า Nginx ให้ใช้งาน GeoIP Database

เพิ่มคำสั่งใน nginx.conf (http block):

http {
    load_module "modules/ngx_http_geoip_module.so";

    geoip_country /usr/share/GeoIP/GeoLite2-Country.mmdb;
    geoip_city /usr/share/GeoIP/GeoLite2-City.mmdb;

    map $geoip_country_code $country_name {
        default "Unknown";
        TH "Thailand";
        US "United States";
        GB "United Kingdom";
        JP "Japan";
        CN "China";
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            add_header X-Country-Code $geoip_country_code;
            add_header X-Country-Name $country_name;
            add_header X-City $geoip_city;

            proxy_pass http://backend;
        }
    }
}

การบล็อก (Block) ประเทศเฉพาะ

วิธีทั่วไปในการใช้ GeoIP Module คือการบล็อกผู้เข้าชมจากประเทศที่ไม่ต้องการ

ตัวอย่าง: บล็อกการเข้าถึงจากประเทศที่ไม่ใช่ไทย

http {
    geoip_country /usr/share/GeoIP/GeoLite2-Country.mmdb;

    map $geoip_country_code $blocked_country {
        default 0;
        TH 0;
        SG 0;
        MY 0;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            if ($blocked_country = 1) {
                return 403;
            }
            proxy_pass http://backend;
        }
    }
}

ตัวอย่าง: บล็อกประเทศที่ระบุได้

map $geoip_country_code $allowed_country {
    default 0;
    US 1;
    UK 1;
    DE 1;
    FR 1;
}

server {
    location /premium {
        if ($allowed_country = 0) {
            return 451;
        }
        proxy_pass http://backend;
    }
}

การอนุญาต (Allow) เฉพาะประเทศที่ต้องการ

ในบางกรณี คุณอาจต้องการให้การเข้าถึงหรือบริการเฉพาะประเทศบางประเทศเท่านั้น

ตัวอย่าง: อนุญาตเฉพาะประเทศเอเชียตะวันออกเฉียงใต้

map $geoip_country_code $allowed {
    default 0;
    TH 1;
    SG 1;
    MY 1;
    ID 1;
    PH 1;
    VN 1;
}

server {
    location /asia-only {
        if ($allowed = 0) {
            return 403 "Access Denied - Service available in selected regions only";
        }
        proxy_pass http://backend;
    }
}

การเปลี่ยนเส้นทาง (Redirect) ตามประเทศ

ในการจัดการประสบการณ์ของผู้เข้าชม (user experience) คุณอาจต้องการให้ผู้เข้าชมถูกเปลี่ยนเส้นทางไปยังเวอร์ชันต่างๆ ของเว็บไซต์ตามประเทศ

ตัวอย่าง: Redirect ไปยังเวอร์ชันภาษาที่เหมาะสม

map $geoip_country_code $lang_version {
    default "en";
    TH "th";
    JP "ja";
    ZH "zh";
    DE "de";
}

server {
    listen 80;
    server_name example.com;

    location / {
        rewrite ^/$ /$lang_version/ redirect;
        proxy_pass http://backend;
    }
}

ตัวอย่าง: Redirect แบบ Domain-based

map $geoip_country_code $domain {
    default "example.com";
    TH "example.co.th";
    JP "example.co.jp";
    US "us.example.com";
}

server {
    listen 80;
    server_name example.com;

    location / {
        if ($host != $domain) {
            return 301 https://$domain$request_uri;
        }
        proxy_pass http://backend;
    }
}

การจัดหาเนื้อหาตามตำแหน่งภูมิศาสตร์ (Geo-based Content Delivery)

GeoIP Module ช่วยให้คุณสามารถจัดเตรียมเนื้อหาที่แตกต่างกันตามประเทศของผู้เข้าชม เพื่อให้ได้ประสบการณ์ที่ดีขึ้น

ตัวอย่าง: แสดง Ad ที่เกี่ยวข้อง (localized ads)

map $geoip_country_code $ad_server {
    default "global-ads.example.com";
    TH "asia-ads.example.com";
    US "us-ads.example.com";
    EU "eu-ads.example.com";
}

server {
    location /ads {
        proxy_pass http://$ad_server;
        add_header X-Ads-Server $ad_server;
    }
}

ตัวอย่าง: บันทึก log ตามประเทศ

map $geoip_country_code $geo_log {
    default /var/log/nginx/geo/other.log;
    TH /var/log/nginx/geo/thailand.log;
    US /var/log/nginx/geo/usa.log;
}

server {
    access_log $geo_log combined;
}

การใช้ Map Directive พร้อม GeoIP

Map directive เป็นเครื่องมือที่มีประสิทธิภาพในการจับคู่ (mapping) ค่าตัวแปร GeoIP กับการตัดสินใจต่างๆ

ตัวอย่าง: Map ที่ซับซ้อนพร้อม Fallback

map $geoip_country_code $content_server {
    default "global.example.com";
    ~^(TH|SG|MY|ID|PH|VN)$ "apac.example.com";
    ~^(US|CA|MX)$ "americas.example.com";
    ~^(GB|DE|FR|IT)$ "europe.example.com";
}

map $geoip_country_code $rate_limit_zone {
    default "global_limit";
    TH "vip_limit";
    US "vip_limit";
}

server {
    limit_req_zone $binary_remote_addr zone=$rate_limit_zone:10m rate=10r/s;

    location / {
        limit_req zone=$rate_limit_zone burst=20;
        proxy_pass http://$content_server;
    }
}

GeoIP2 Module (ngx_http_geoip2_module)

GeoIP2 Module เป็นเวอร์ชันใหม่กว่า (newer version) ที่ใช้ฟังก์ชันการทำงานของ MaxMind GeoIP2 API โดยตรง แม้ว่าจะมีประสิทธิภาพมากกว่า GeoIP Module เดิม

ข้อดีของ GeoIP2 Module:

  • รองรับฟอร์แมต mmdb ของ MaxMind เวอร์ชันใหม่
  • ให้ข้อมูลละเอียดขึ้น (timezone, ISP, domain)
  • อัปเดตได้โดยอัตโนมัติ (automatic updates)
  • ทำงานได้เร็วกว่าเวอร์ชันเก่า

ติดตั้ง GeoIP2 Module:

cd /tmp
git clone https://github.com/leev/ngx_http_geoip2_module.git
cd /tmp/nginx-source
./configure --add-dynamic-module=../ngx_http_geoip2_module --with-compat
make modules
cp objs/ngx_http_geoip2_module.so /etc/nginx/modules/

ตัวอย่าง: การตั้งค่า GeoIP2

load_module "modules/ngx_http_geoip2_module.so";

http {
    geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
        auto_reload 60m;
        $geoip2_metadata_country_build metadata build_epoch;
        $geoip2_data_country_code country iso_code;
        $geoip2_data_country_name country names en;
    }

    geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb {
        auto_reload 60m;
        $geoip2_data_city_name city names en;
        $geoip2_data_postal_code postal code;
        $geoip2_data_latitude location latitude;
        $geoip2_data_longitude location longitude;
        $geoip2_data_accuracy_radius location accuracy_radius;
    }

    server {
        location / {
            add_header X-Country-Code $geoip2_data_country_code;
            add_header X-Country-Name $geoip2_data_country_name;
            add_header X-City $geoip2_data_city_name;
            proxy_pass http://backend;
        }
    }
}

การอัปเดตฐานข้อมูล GeoIP โดยอัตโนมัติ

ฐานข้อมูล GeoIP ควรได้รับการอัปเดตเป็นประจำเพื่อให้มีข้อมูล IP ที่ถูกต้อง MaxMind แนะนำให้อัปเดตอย่างน้อยเดือนละครั้ง

ตั้งค่า geoipupdate.conf:

sudo nano /etc/GeoIP.conf

แก้ไขไฟล์ให้มีเนื้อหาดังนี้:

# MaxMind account ID
AccountID 000000

# MaxMind license key
LicenseKey xxxxxxxxxxxxxxxx

# ประเภทฐานข้อมูลที่ต้องการ
EditionIDs GeoLite2-Country GeoLite2-City

# ไดเรกทอรี่เก็บฐานข้อมูล
DatabaseDirectory /usr/share/GeoIP

ตั้งค่า Cron เพื่ออัปเดตโดยอัตโนมัติ:

0 3 * * 5 /usr/bin/geoipupdate -f /etc/GeoIP.conf && systemctl reload nginx

เพิ่ม cron job โดยใช้:

sudo crontab -e

การทดสอบด้วย Curl Headers

ในการทดสอบว่า GeoIP Module ทำงานถูกต้อง คุณสามารถใช้ curl เพื่อจำลอง IP Address จากประเทศต่างๆ

ตัวอย่าง: ทดสอบด้วย X-Forwarded-For Header

curl -H "X-Forwarded-For: 203.154.0.0" http://example.com/
curl -H "X-Forwarded-For: 8.8.8.8" http://example.com/
curl -I -H "X-Forwarded-For: 203.154.0.0" http://example.com/

หมายเหตุ: ให้ตรวจสอบว่า Nginx ถูกตั้งค่าให้ยอมรับ X-Forwarded-For header

server {
    set_real_ip_from 127.0.0.1;
    real_ip_header X-Forwarded-For;

    location / {
        add_header X-Real-IP $remote_addr;
        proxy_pass http://backend;
    }
}

ตัวอย่าง: ทดสอบบล็อกประเทศ

curl -H "X-Forwarded-For: 203.154.0.0" http://example.com/ -v
curl -H "X-Forwarded-For: 195.10.0.0" http://example.com/ -v

การพิจารณาเรื่องประสิทธิภาพ (Performance Considerations)

การใช้ GeoIP Module สามารถส่งผลกระทบต่อประสิทธิภาพของเซิร์ฟเวอร์ได้หากไม่ได้ตั้งค่าอย่างถูกต้อง

คำแนะนำเพื่อเพิ่มประสิทธิภาพ:

  • ใช้ Map Directive: Map directive ใน Nginx จะ cache ผลลัพธ์ของ GeoIP lookup ในหน่วยความจำ ซึ่งเร็วกว่าการเรียกใช้ฟังก์ชันหลายครั้ง
  • ตั้งค่า Cache: ตั้งค่า proxy_cache เพื่อลดจำนวนการ lookup ซ้ำ
  • ใช้ GeoIP2 Module: GeoIP2 Module มีประสิทธิภาพดีกว่า GeoIP Module เดิม
  • ตรวจสอบเนื้อหาฐานข้อมูล: ใช้ฐานข้อมูล mmdb format เท่านั้น (เก่า binary format ช้าลง)
  • ใช้ if statement อย่างระมัดระวัง: if statement ใน location block สามารถสร้าง overhead ได้ ลองใช้ map directive แทน

ตัวอย่าง: การปรับปรุงประสิทธิภาพ

http {
    geoip_country /usr/share/GeoIP/GeoLite2-Country.mmdb;

    map $geoip_country_code $skip_cache {
        default 0;
        CN 1;
        RU 1;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            proxy_cache_bypass $skip_cache;
            proxy_cache my_cache;
            proxy_cache_valid 200 1h;

            proxy_pass http://backend;
        }
    }
}

ตัวอย่าง: โมนิเตอร์ประสิทธิภาพ

log_format geo_timing '$remote_addr - $remote_user [$time_local] '
                      '"$request" $status $body_bytes_sent '
                      '"$http_referer" "$http_user_agent" '
                      'country=$geoip_country_code city=$geoip_city '
                      'time=$request_time';

server {
    access_log /var/log/nginx/access.log geo_timing;
}

สรุป

GeoIP Module ใน Nginx เป็นเครื่องมือที่ทรงพลังสำหรับการจัดการการเข้าถึงเนื้อหาตามตำแหน่งภูมิศาสตร์ ช่วยให้คุณสามารถ:

  • บล็อก (block) หรืออนุญาต (allow) การเข้าถึงจากประเทศที่ระบุ
  • เปลี่ยนเส้นทาง (redirect) ไปยังเวอร์ชันเว็บไซต์ที่เหมาะสม
  • จัดหาเนื้อหา (deliver content) ที่เกี่ยวข้องกับตำแหน่งภูมิศาสตร์
  • ปรับปรุงประสบการณ์ของผู้เข้าชม (improve user experience)
  • ป้องกันการเข้าถึงที่ไม่ได้รับอนุญาต (prevent unauthorized access)

การตั้งค่า GeoIP Module ถูกต้องสำคัญสำหรับการบริหารเซิร์ฟเวอร์อย่างมีประสิทธิภาพ และการเลือกใช้ GeoIP2 Module จะให้ความสามารถเพิ่มเติมและประสิทธิภาพที่ดีกว่า

แนะนำบริการ DE

เพื่อให้ได้ประสิทธิภาพสูงสุดในการใช้ GeoIP Module และการจัดการเซิร์ฟเวอร์ Nginx แนะนำให้ใช้บริการ Cloud Infrastructure ของเรา

Cloud VPS ของ DE มีข้อดีดังนี้:

  • ควบคุม Root Access ได้เต็มที่ (full control)
  • ติดตั้ง Nginx และ GeoIP Module ได้ตามต้องการ
  • ปรับปรุงประสิทธิภาพได้อย่างอิสระ (unlimited customization)
  • รองรับ Multiple IP Addresses สำหรับ Geo-targeting ที่ซับซ้อน
  • บริการให้ปรึกษา (support) 24/7 จากทีมผู้เชี่ยวชาญ

นอกจากนี้ Cloud Hosting ของ DE ก็เป็นตัวเลือกที่ดีสำหรับผู้ที่ต้องการบริการที่มีระดับการจัดการสูง (managed hosting) โดยไม่ต้องกังวลกับการตั้งค่าระดับเซิร์ฟเวอร์

ติดต่อ DE วันนี้เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับวิธีที่บริการของเราสามารถช่วยให้ธุรกิจของคุณเติบโตและประสิทธิภาพสูงสุด