Obtain originating IP addresses behind Anti-DDoS Proxy

Updated at:
Copy as MD

When Anti-DDoS Proxy forwards traffic to your origin server, the original client IP is masked. Retrieve it by parsing the X-Forwarded-For header or installing a TOA module.

For non-website services (Layer 4)

Install the TOA module on your origin server to obtain the originating IP address. Obtain the originating IP address of a request by installing the TOA module. If you cannot install the TOA module, contact technical support.

Anti-DDoS Proxy IPv4 instance

The client's source IP is passed using the TCP Option field. For a non-website service (Layer 4), after the three-way handshake between Anti-DDoS Proxy and the origin server, the proxy modifies the final ACK packet by inserting an 8-byte TCP Option (type 254), which contains the client's source port and source IP. The following Wireshark capture shows an example. The TCP Option – Experimental section contains the port number and source IP information:

    Destination Port: 443
     [Stream index: 0]
     [TCP Segment Len: 0]
    Sequence number: 1    (relative sequence number)
    Acknowledgment number: 1    (relative ack number)
    1001 .... = Header Length: 36 bytes (9)
  ▶ Flags: 0x010 (ACK)
    Window size value: 65535
     [Calculated window size: 65535]
     [Window size scaling factor: -2 (no window scaling used)]
    Checksum: 0x90fb [unverified]
     [Checksum Status: Unverified]
    Urgent pointer: 0
  ▼ Options: (16 bytes), Experimental
    ▼ TCP Option – Experimental
        Kind: RFC3692-style Experiment 2 (254)
        Length: 8
        Magic Number: 0xc406
      Unknown (0xfa) (8 bytes)
0000   b4 0c 25 e2 80 46 4c e1   75 f7 e5 c1 08 00 45 00   ..%..FL. u.....E.
0010   00 38 00 00 40 00 26 06   cf e9 2f 70 49 ce 67 96   .8..@.&. ../pI.g.
0020   a4 02 1b 2e 01 bb c8 c1   cf 98 ab 2f 54 e1 90 10   ........ .../T...
0030   ff ff 90 fb 00 00 fe 08   c4 06 65 xx xx 85 fa 08   ........ ..exx...
0040   01 bb cb 6b 34 80                                     ...k4.
  • Port number: The Magic Number field contains the port number in hexadecimal. For example, c4 06 converts to decimal 50182.

  • source IP: The four bytes that follow the port number represent the source IP in hexadecimal. In this example, 65 ** ** 85 corresponds to the source IP 101.*.*.133.

Anti-DDoS Proxy IPv6 instance

v6tov4 mode

In v6tov4 mode, where an IPv6 client connects to an IPv4 origin server, the final ACK packet contains a 40-byte TCP Option (type 249). This option includes the source port, source IP, and the Anti-DDoS Proxy IP address. The following shows an example:

Destination Port: 8080
[Stream index: 1]
[Stream Packet Number: 3]
[Conversation completeness: Incomplete, ESTABLISHED (7)]
[TCP Segment Len: 0]
Sequence Number: 1    (relative sequence number)
Sequence Number (raw): 2505761997
[Next Sequence Number: 1    (relative sequence number)]
Acknowledgment Number: 1    (relative ack number)
Acknowledgment number (raw): 483970095
1111 .... = Header Length: 60 bytes (15)
Flags: 0x010 (ACK)
Window: 4096
[Calculated window size: 262144]
[Window size scaling factor: 64]
Checksum: 0xbc88 [unverified]
[Checksum Status: Unverified]
Urgent Pointer: 0
Options: (40 bytes), Unknown (0xf9)
  TCP Option – Unknown
    Kind: Unknown (249)
    Length: 40
    Payload: 9d7d2401b180xxxd960f875d960f87000000012405e000100300000000000a7304b55
[Timestamps]
  • Port number: The first two bytes of the Payload contain the port number in hexadecimal. For example, 9d7d converts to decimal 40317.

  • Source IP address: The 16 bytes after the port number contain the source IPv6 address in hexadecimal. For example, 2401*****0f87 corresponds to 2401:b180:100*:*:*:f87:5d96:f87.

    Note

    The remaining 20 bytes in the Payload contain the Anti-DDoS IP information.

v6tov6 mode

In a v6tov6 scenario, where both the client and the origin server use IPv6, the final ACK packet contains a 20-byte TCP Option (type 253). This option includes the source port and source IP. The following shows an example:

Destination Port: 8080
 [Stream index: 0]
 [Stream Packet Number: 1]
 [Conversation completeness: Incomplete (12)]
 [TCP Segment Len: 0]
 Sequence Number: 1    (relative sequence number)
 Sequence Number (raw): 721958393
 [Next Sequence Number: 1    (relative sequence number)]
 Acknowledgment Number: 1    (relative ack number)
 Acknowledgment number (raw): 2789445640
 1010 .... = Header Length: 40 bytes (10)
 Flags: 0x010 (ACK)
 Window: 65535
 [Calculated window size: 65535]
 [Window size scaling factor: -1 (unknown)]
 Checksum: 0x90cc [unverified]
 [Checksum Status: Unverified]
 Urgent Pointer: 0
 Options: (20 bytes), Experimental
   TCP Option - Experimental: Unknown
       Kind: RFC3692-style Experiment 1 (253)
       Length: 20
       Experiment Identifier: Unknown (0xeb98)
       Data: 2401b180100xxx0f875d960f87
  • Port number: The Experiment Identifier field contains the port number in hexadecimal. For example, eb98 converts to decimal 60312.

  • Source IP address: The Data field contains the source IPv6 address in hexadecimal. For example, 2401*****0f87 corresponds to 2401:b180:100*:*:*:f87:5d96:f87.

Important

Add the back-to-origin CIDR blocks of Anti-DDoS Proxy to your origin server's whitelist to prevent forwarded traffic from being blocked. Allow back-to-origin CIDR blocks to access the origin server.

  • Anti-DDoS Proxy -> ECS: Add the back-to-origin CIDR blocks to the ECS security group. Add a security group rule.

  • Anti-DDoS Proxy -> SLB -> ECS: Add the back-to-origin CIDR blocks to the SLB access control whitelist. Enable access control.

For website services (Layer 7)

Method 1: Use the X-Forwarded-For header

How it works

  • When a Layer 7 proxy such as Anti-DDoS Proxy forwards a request, the origin server sees the proxy's IP as the source. The X-Forwarded-For header records the client's actual IP. Format: X-Forwarded-For: <originating_IP_address>.

  • If a request passes through multiple proxies (such as WAF or CDN), the X-Forwarded-For header records the real client IP followed by each proxy IP. Format: X-Forwarded-For: real-client-IP, proxy-server-1-IP, proxy-server-2-IP, proxy-server-3-IP, .... Each proxy appends the previous node's address to X-Forwarded-For but does not append its own.

Retrieval methods

Retrieve the X-Forwarded-For header value in your application code:

Important
  • The first IP address in the comma-separated X-Forwarded-For value is the client's originating IP.

  • You can also configure your web server (Nginx, IIS 6, IIS 7, Apache, or Tomcat) to parse the X-Forwarded-For header. Retrieve the originating IP addresses of clients.

  • ASP

    Request.ServerVariables("HTTP_X_FORWARDED_FOR")
  • ASP.NET (C#)

    Request.ServerVariables["HTTP_X_FORWARDED_FOR"]
  • PHP

    $_SERVER["HTTP_X_FORWARDED_FOR"]
  • JSP

    request.getHeader("HTTP_X_FORWARDED_FOR")

Method 2: Use a custom HTTP header

Overview

In complex architectures, the standard X-Forwarded-For (XFF) header is vulnerable to forgery and IP confusion from multiple proxy layers. A custom HTTP header provides more reliable client IP transmission.

Procedure

Configure Anti-DDoS Proxy to write the client IP to a custom HTTP header. Configure back-to-origin settings.

  1. Log on to the Website Config page in the Anti-DDoS Proxy console.

  2. On the Website Config page, click Add Website.

  3. On the Website Config page, in the Forwarding Settings section, set Traffic Marking to Custom Header (for example, Custom-True-IP).

  4. In your application code, retrieve the value of the custom header, for example: request.getHeader("Custom-True-IP").