h2o / h2o

H2O - the optimized HTTP/1, HTTP/2, HTTP/3 server

Home Page:https://h2o.examp1e.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cloudflare Real IP

libDarkstreet opened this issue · comments

commented

How do I get back the real ip address of my visitors from cloudflare proxy?

In nginx there is a setting called "set_real_ip_from" and "real_ip_header ", this settings allows nginx to use the ip address that was returned by the cloudflare proxy via "X-Forwarded-For" header. I need the same solution but with H2O.

The nginx config looks like this:

set_real_ip_from  192.168.1.0/24;
set_real_ip_from  192.168.2.1;
set_real_ip_from  2001:0db8::/32;
real_ip_header    X-Forwarded-For;

Reference:
https://developers.cloudflare.com/support/troubleshooting/restoring-visitor-ips/restoring-original-visitor-ips/

Hi! @libDarkstreet
I consider that the alternative which uses for the mruby acl and access log directives like that is suitable.

h2o.conf

    paths:
      "/":
        mruby.handler: |
          acl {
            deny { !addr.start_with?("50.50.") }
          }
        file.dir: doc
    access-log:
      path: /dev/stdout
      format: "%h %l %u %t \"%r\" %s %b %{X-Forwarded-For}i"

result

% curl -v -H"X-Forwarded-For:111.111.111.111" -k https://localhost/index.html
*   Trying 127.0.0.1:443...
...
> GET /index.html HTTP/2
> Host: localhost
> user-agent: curl/7.81.0
> accept: */*
> x-forwarded-for:111.111.111.111
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 403
< server: h2o/2.3.0-DEV@e621be4f2
< date: Sun, 17 Sep 2023 00:57:30 GMT
< alt-svc: h3=":443";ma=60,quic=":443";ma=60
< cache-control: no-cache
< content-length: 9
<
* Connection #0 to host localhost left intact
Forbidden%

access-log

127.0.0.1 - - [17/Sep/2023:09:57:30 +0900] "GET /index.html HTTP/2" 403 9 111.111.111.111

access controll phase
addr is defined here which can be retrieved the most left side of x-forwarded-for value.
https://github.com/h2o/h2o/blob/master/share/h2o/mruby/acl.rb#L98-L105
If you used for another header (just like specified real_ip_header in ngx_real_ip_module), it should be better to use header. And then you have to be defined the filter yourself into mruby handler like just doing in addr method.
https://github.com/h2o/h2o/blob/master/share/h2o/mruby/acl.rb#L115-L118

access log phase
The document says it can be retrieved the value of the given request header like below.
%{X-Forwarded-For}i