Skip to content

Restricting Requester Origin in IBM i HTTP Server (V7R4M0, Apache 2.4)

Applies to: IBM i V7R4M0 (Integrated Apache 2.4 semantics)
File locations (typical):
- Config: /www/<instance>/conf/httpd.conf
- Web root: /www/<instance>/htdocs - Logs: /www/<instance>/logs/ (access_log, error_log)

This guide explains practical ways to restrict who can access your IBM i HTTP Server. Choose the method that matches what “origin” means in your case:

  • Network origin: IP/CIDR rules, mTLS (client certs)
  • Browser origin: CORS Origin header
  • Page origin (hotlinking): Referer header
  • Application-level: Authentication and header-based gates

Note: V7R4M0 uses the Apache 2.4 authorization model (Require, RequireAny, RequireAll). Examples below follow that syntax.


1) Check Your Module & Context

  • Use <Directory>, <Location>, <FilesMatch>, or <VirtualHost> depending on scope.
  • Ensure modules used in examples are loaded in your instance config:
  • LoadModule headers_module /QOpenSys/pkgs/lib/httpd/modules/mod_headers.so (path may vary)
  • LoadModule ssl_module ... for TLS
  • LoadModule remoteip_module ... if behind a proxy and you need real client IPs
  • Use Navigator for i (Web Admin GUI) or edit /www/<instance>/conf/httpd.conf directly.

2) IP / Network Restrictions (Strongest & Simple)

Allow only trusted source networks or hosts. This is the most reliable control.

# Restrict entire site
<VirtualHost *:80>
    ServerName app.example.com
    DocumentRoot /www/APP/htdocs

    <Location />
        Require ip 203.0.113.42           # single IP
        Require ip 198.51.100.0/24        # subnet
        Require not ip 10.0.0.0/8         # explicit block (optional)
    </Location>
</VirtualHost>

Scope to a specific path or directory:

<Location /admin/>
    Require ip 203.0.113.0/24
</Location>

<Directory "/www/APP/htdocs/private">
    Require ip 198.51.100.0/24
</Directory>

Tip: Combine with authentication for defense-in-depth.


3) Hostname (Reverse DNS) Restrictions

DNS-based checks are slower and can be spoofed. Prefer IPs where possible.

<Location />
    Require host partner.example.com
    Require host .trustedcorp.net    # suffix match
</Location>

4) Mutual TLS (mTLS) with Client Certificates

mTLS verifies the caller using a client certificate—excellent for partner APIs and admin apps.

<VirtualHost *:443>
    ServerName secure.example.com
    DocumentRoot /www/SECURE/htdocs

    SSLEngine on
    SSLCertificateFile      /QIBM/UserData/ICSS/Cert/Server/servercert.pem
    SSLCertificateKeyFile   /QIBM/UserData/ICSS/Cert/Server/serverkey.pem

    # CA trust bundle for validating client certs
    SSLCACertificateFile    /QIBM/UserData/ICSS/Cert/CA/trusted-ca-bundle.pem

    SSLVerifyClient require
    SSLVerifyDepth 3

    <Location />
        Require ssl
        # Optional: Gate by cert subject/issuer attributes
        # Require expr %{SSL_CLIENT_S_DN_O} == 'TrustedCorp'
    </Location>
</VirtualHost>

Manage certs with Digital Certificate Manager (DCM) on IBM i.


5) CORS: Restrict by Browser Origin

CORS controls which browsers may access resources cross-origin. It does not block non-browser tools (curl, Postman). Use with IP or auth for real enforcement.

Single allowed origin:

<IfModule mod_headers.c>
  <Location /api/>
    Header always set Access-Control-Allow-Origin "https://app.trusted.example"
    Header always set Vary "Origin"
    Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
    Header always set Access-Control-Allow-Headers "Content-Type, Authorization"
  </Location>
</IfModule>

Allowlist multiple origins (echo back when matched):

# Capture allowed Origin
SetEnvIf Origin "^https://(app1|app2)\.trusted\.example$" allowed_origin=$0

<IfModule mod_headers.c>
  <Location /api/>
    Header always set Access-Control-Allow-Origin "%{allowed_origin}e" env=allowed_origin
    Header always set Vary "Origin"
    Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
    Header always set Access-Control-Allow-Headers "Content-Type, Authorization"
  </Location>
</IfModule>

6) Referer-Based Gating (Hotlinking)

Good for blocking hotlinking or providing a light deterrent. Not strong security.

# Only allow if Referer starts with https://www.trustedsite.com/
SetEnvIf Referer "^https://(www\.)?trustedsite\.com/" ok_ref

<Location /media/>
  Require env ok_ref
</Location>

7) Header / Token-Based Gating

Gate access on custom headers (spoofable—use real auth or mTLS for strong control).

# Example: a simple shared token (prefer OAuth, JWT, or mTLS for production)
SetEnvIfNoCase X-Trusted-Token "^v1\.[A-Za-z0-9_-]{20,}$" has_token

<Location /partner-endpoint/>
  Require env has_token
</Location>

8) RequireAll / RequireAny: Combine Checks

Create multi-factor gates (e.g., corporate network and TLS and login).

<Location /api/secure>
  <RequireAll>
    Require ip 203.0.113.0/24
    Require ssl
    Require valid-user
  </RequireAll>
</Location>

# Either corporate IP OR client certificate org matches
<Location /api/partners>
  <RequireAny>
    Require ip 203.0.113.0/24
    Require expr %{SSL_CLIENT_S_DN_O} == 'TrustedCorp'
  </RequireAny>
</Location>

9) Per-Path / File / Virtual Host Scoping

# File type restriction
<FilesMatch "\.(zip|tar\.gz)$">
  Require ip 198.51.100.0/24
</FilesMatch>

# Route subtree
<Location /internal/>
  Require ip 203.0.113.0/24
</Location>

# Whole virtual host restricted to private network
<VirtualHost *:443>
  ServerName intranet.example.com
  DocumentRoot /www/INTRA/htdocs
  <Location />
    Require ip 10.0.0.0/8
  </Location>
</VirtualHost>

10) Behind Proxies / Load Balancers

If you’re behind an ADC/ALB (e.g., F5, NGINX, Cloudflare), ensure Apache sees the real client IP:

# Trust the proxy and read client IP from X-Forwarded-For
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 192.0.2.10      # your proxy IP or subnet
# Optional: if proxies are in a CIDR
# RemoteIPInternalProxy 192.0.2.0/24

Then your Require ip ... checks apply to the actual client, not the proxy.


11) Operational Tips & Testing

  • Validate config: apachectl -t (or restart instance from Navigator for i and watch for syntax errors in error_log).
  • Test incrementally: apply rules to a narrow <Location> first.
  • Log checks: add temporary logging to confirm matches (e.g., custom log formats with %{VARNAME}e).
  • Fallbacks: keep console or a second admin session open to revert misconfigures.
  • Documentation: IBM Navigator for i → HTTP Server → your instance for module status & directives.

12) Copy-Paste Starter Templates

A) Corporate IP + Auth for /admin

<Location /admin/>
  Require ip 203.0.113.0/24
  AuthType Basic
  AuthName "Admin Area"
  AuthUserFile /www/APP/conf/.htpasswd
  Require valid-user
</Location>

B) Partner mTLS for /partner-api

<VirtualHost *:443>
  ServerName partner.example.com
  DocumentRoot /www/PARTNER/htdocs

  SSLEngine on
  SSLCertificateFile    /QIBM/UserData/ICSS/Cert/Server/servercert.pem
  SSLCertificateKeyFile /QIBM/UserData/ICSS/Cert/Server/serverkey.pem
  SSLCACertificateFile  /QIBM/UserData/ICSS/Cert/CA/partners.pem
  SSLVerifyClient require

  <Location /partner-api/>
    Require ssl
    Require expr %{SSL_CLIENT_S_DN_O} == 'TrustedCorp'
  </Location>
</VirtualHost>

C) CORS Allowlist for /api

SetEnvIf Origin "^https://(app1|app2)\.trusted\.example$" allowed_origin=$0
<IfModule mod_headers.c>
  <Location /api/>
    Header always set Access-Control-Allow-Origin "%{allowed_origin}e" env=allowed_origin
    Header always set Vary "Origin"
    Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
    Header always set Access-Control-Allow-Headers "Content-Type, Authorization"
  </Location>
</IfModule>

D) Hotlinking Block for /media

SetEnvIf Referer "^https://(www\.)?trustedsite\.com/" ok_ref
<Location /media/>
  Require env ok_ref
</Location>

Choosing the Right Control

  • Strongest enforcement: IP/CIDR allowlists and/or mTLS.
  • Defense-in-depth: Add Basic/LDAP auth behind TLS.
  • Browser-only: CORS for cross-origin browser calls (not real security).
  • Light deterrent: Referer / custom-header checks.

If you share your proxy details and exact paths, you can drop these directly into /www/<instance>/conf/httpd.conf with minimal changes.