IP Restriction Python Flask: Cara Validasi Alamat IP

Implementasi pembatasan akses berdasarkan alamat IP (IP restriction) pada aplikasi Python Flask dapat dilakukan dengan menggunakan fungsi decorator kustom untuk mengecek header HTTP X-Forwarded-For atau request.remote_addr. Pendekatan ini memastikan hanya daftar alamat IP yang diizinkan (whitelist) atau yang tidak diblokir (blacklist) dapat mengakses endpoint tertentu.

Metode paling aman di balik reverse proxy seperti Nginx adalah memastikan aplikasi membaca header yang tepat dengan benar, mengingat request.remote_addr sering kali hanya mengembalikan alamat IP lokal dari proxy tersebut jika konfigurasi proxy_pass tidak meneruskan header yang sesuai.

Implementasi Whitelist IP dengan Decorator Kustom

Cara paling langsung untuk membatasi akses ke route tertentu di Flask adalah dengan membuat fungsi decorator Python yang memeriksa alamat IP klien sebelum mengeksekusi fungsi tampilan (view function).

from functools import wraps
from flask import Flask, abort, request

app = Flask(__name__)

# Daftar IP yang diizinkan mengakses rute khusus
ALLOWED_IPS = ['127.0.0.1', '192.168.1.50']


def ip_restricted(f):
  @wraps(f)
  def decorated_function(*args, **kwargs):
    # Ambil IP dari header proxy jika ada, atau gunakan remote_addr
    if request.headers.get('X-Forwarded-For'):
      client_ip = request.headers.get('X-Forwarded-For').split(',')[0].strip()
    else:
      client_ip = request.remote_addr

    if client_ip not in ALLOWED_IPS:
      abort(403)  # Forbidden

    return f(*args, **kwargs)

  return decorated_function


@app.route('/admin')
@ip_restricted
def admin_dashboard():
  return 'Selamat datang di panel admin yang aman.'


if __name__ == '__main__':
  app.run(debug=True)

Metode Pembatasan IP dan Pengamanannya

Metode Kelebihan Kekurangan
Decorator Kustom Ringan, fleksibel, tanpa dependensi eksternal. Harus dikelola secara manual per route atau blueprint.
Flask-Limiter Mendukung rate limiting dan blokir IP otomatis berdasarkan kuota. Membutuhkan penyimpanan backend seperti Redis untuk produksi.
Nginx / Reverse Proxy Blokir terjadi di level server web sebelum mencapai aplikasi Python. Memerlukan akses administratif ke server Nginx.

Menggunakan Flask-Limiter untuk Pembatasan Lanjutan

Jika kebutuhan Anda bukan hanya whitelist statis, melainkan pembatasan akses untuk mencegah serangan brute-force atau DDoS berbasis IP, library Flask-Limiter adalah standar industri yang umum dipakai.

from flask import Flask
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

app = Flask(__name__)

limiter = Limiter(
    get_remote_address,
    app=app,
    default_limits=['200 per day', '50 per hour'],
    storage_uri='memory://',
)


@app.route('/api/data')
@limiter.limit('5 per minute')
def get_data():
  return {'data': 'Contoh data terbatas'}

Langkah Troubleshooting Masalah IP di Flask

Seringkali alamat IP yang terbaca di Flask selalu bernilai 127.0.0.1 atau IP internal Docker meskipun diakses dari internet publik. Berikut langkah penyelesaiannya:

  1. Pastikan Nginx atau Apache dikonfigurasi untuk meneruskan header yang benar menggunakan proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;.
  2. Gunakan ekstensi ProxyFix dariwerkzeug jika aplikasi Flask berada di belakang proxy terpercaya untuk menghindari manipulasi header palsu dari klien.
  3. Uji validasi IP menggunakan permintaan lokal via curl -H "X-Forwarded-For: 203.0.113.195" http://localhost:5000/admin untuk memastikan fungsi decorator membaca IP palsu/uji coba dengan benar selama tahap development.