Proxy block

The proxy block allows you to configure host spoofing via web (reverse) proxies or WEBIRC.

NOTE: If you are running UnrealIRCd 6.1.0 or older, then instead see the WebIRC block for webirc support, or set listener::options::websocket::proxy for limited web support

Syntax
proxy name-of-proxy { type web; match { ip 1.2.3.4; } password "somepass"; };

The name-of-proxy is a short name for the proxy. It is not used yet as of UnrealIRCd 6.1.1, but may be used or displayed somewhere at a later point.

Within the block:
 * type is the type of proxy:
 * web: a web proxy sending  headers. This is (only) used to reverse proxy websocket connections.
 * webirc: a WEBIRC / CGI:IRC gateway, see also WebIRC Support.
 * match is checked against the proxy that is trying to connect. It is a Mask item.
 * password is only used for type webirc

Examples
We have several examples:
 * Reverse proxy for websocket connections
 * WEBIRC example with KiwiIRC

Reverse proxy for websocket connections
In this example we use a reverse proxy in NGINX to proxy websocket connections via NGINX to your UnrealIRCd. Of course you can use other reverse proxies as well, if you do, make sure they send the  header, as described in technical docs at Mozilla.

UnrealIRCd configuration
First, set up websockets on port 8000 with SSL/TLS: loadmodule "websocket"; loadmodule "webserver";

listen { ip *; port 8000; options { websocket { type text; } tls; } }

Then add the proxy block: proxy { type web; match { ip 6.6.6.6; } // IP of your reverse proxy }

NGINX configuration
This is based on NGINX docs plus the addition of $proxy_protocol from ourselves

Add this to your config so the  variable becomes available: map $https $proxy_protocol { "^on$" "proto=https"; default "proto=http"; }

map $remote_addr $proxy_forwarded_elem { # IPv4 addresses can be sent as-is ~^[0-9.]+$         "for=$remote_addr;$proxy_protocol";

# IPv6 addresses need to be bracketed and quoted ~^[0-9A-Fa-f:.]+$  "for=\"[$remote_addr]\";$proxy_protocol";

# Unix domain socket names cannot be represented in RFC 7239 syntax default            "for=unknown;$proxy_protocol"; }

map $http_forwarded $proxy_add_forwarded { # If the incoming Forwarded header is syntactically valid, append to it   "~^(,[ \\t]*)*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*([ \\t]*,([ \\t]*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*)?)*$" "$http_forwarded, $proxy_forwarded_elem";

# Otherwise, replace it   default "$proxy_forwarded_elem"; }

And then add something like this in your site block: location /websocket { proxy_set_header Forwarded $proxy_add_forwarded; proxy_pass https://5.5.5.5:8000/; } This assumes your UnrealIRCd is running at 5.5.5.5 with websockets enabled at port 8000 and it is a SSL/TLS port, as we configured earlier above.

Test
Be sure to REHASH the IRCd and your NGINX or whatever proxy you use, and then connect with a websocket to

Your websocket client should pop up on IRC with the end-user IP address (and not the IP address of the proxy). If it doesn't work, then also connect as IRCOp via normal (non-websocket) IRC and see if there is anything logged by the IRCd, UnrealIRCd log messages such as "proxy did not send a valid forwarded header".


 * If you see the "proxy did not send a valid forwarded header" warning then it means your proxy is not sending the  header. For example it could be using old headers such as   or  . Reconfigure the proxy to send the modern   header instead, check with your proxy/provider documentation. Technical docs about this header are at Mozilla.

WEBIRC example with KiwiIRC
The example below configures KiwiIRC and UnrealIRCd. Note that this is just an example, if you use something other than KiwiIRC you edit that instead of the KiwiIRC-side.

The most important thing is that you set the same password on both the Kiwi side and on the UnrealIRCd side, we use  as an example here.

KiwiIRC-side (old and outdated)
Edit kiwiirc's config.js as follows (note: this is NOT a complete configuration file, it just shows 3 important sections): // WebIRC passwords enabled for this server conf.webirc_pass = { "irc1.yournetwork.org":       "ThisIsMySecretWebIRCPassword" };

// Default settings for the client. These may be changed in the browser conf.client = { server: 'irc1.yournetwork.org', port:   6697, ssl:    true, channel: '#test', nick:   'kiwi_?' }; // or use conf.restrict_server etc... to achieve the same effect (see example config.js file).

// What matters is that the server name in conf.client or conf.restrict_server // match the server name in conf.webirc_pass (and use the right password). // So be sure to replace BOTH the irc1.yournetwork.org instances with the same server name.

// Now something else... "send ip as username".... // Be sure *NOT* to list your server here !!!! // If you add it here, then the IP will show up in the ident. This is NOT what you want // as the IP is already sent via WEBIRC. Doing so would reveal the users' IP to everyone which is bad. conf.ip_as_username = [ "do_not_set_your_server_here" ];

KiwiIRC-side (new aka nextclient)
Edit kiwiirc's webircgateway config.conf as follows (note: this is NOT a complete configuration file): // WebIRC passwords enabled for this server [upstream.1] webirc = "ThisIsMySecretWebIRCPassword"

UnrealIRCd-side
Then, in your unrealircd.conf you add a webirc block:

proxy { type webirc; mask 127.0.0.1; password "ThisIsMySecretWebIRCPassword"; };

except ban { mask 127.0.0.1; type { connect-flood; handshake-data-flood; blacklist; }; };

The Except ban block block is highly recommended. This will ensure your webirc gateway is not seen as connection flooding and the blacklist exception will make it connect faster. If you don't have an except ban block for your webirc gateway then users will not be able to connect during peak hours or after a server restart.