To create new wiki account, please join us on #znc at Libera.Chat and ask admins to create a wiki account for you. You can say thanks to spambots for this inconvenience.
Reverse Proxy: Difference between revisions
DarthGandalf (talk | contribs) Undo revision 2291 by DarthGandalf (talk) Tag: Undo |
Entirely rewritten with the exception of lighttpd |
||
Line 1: | Line 1: | ||
== About Reverse Proxies == | |||
While ZNC is a fantastic bouncer, in many situations it can be beneficial to utilize a reverse proxy in front of it for features such as: | |||
* Subdomains | |||
* Tighter control of SSL ciphers and protocols | |||
* ECDH support | |||
* SSL session caching | |||
* SSL stapling | |||
* Compression | |||
=== Notes === | |||
* <code>TrustedProxy</code> must be set in your configuration for web access logs to reflect actual addresses instead of the reverse proxy address (<code>127.0.0.1</code> / <code>::1</code>): | |||
<nowiki> | |||
TrustedProxy = 127.0.0.1 | |||
<nowiki>TrustedProxy = 127.0.0.1 | |||
TrustedProxy = ::1</nowiki> | TrustedProxy = ::1</nowiki> | ||
== Nginx == | == Nginx == | ||
=== As | '''Note:''' If you plan on utilizing Nginx for IRC in conjunction with HTTP/HTTPS, the port number (''or'' address) of the two services '''must be different'''. | ||
=== HTTP === | |||
==== As a Subdomain ==== | |||
<nowiki>server { | <nowiki>server { | ||
listen 80; | listen 192.0.2.1:80; | ||
listen [::]:80; | listen [2001:db8::192:0:2:1]:80; | ||
server_name znc. | server_name znc.example.test; | ||
access_log /var/log/nginx/znc.example.test/znc-access.log; | |||
error_log /var/log/nginx/znc.example.test/znc-error.log; | |||
location / { | location / { | ||
proxy_pass http://[::1]:6667/; | proxy_pass http://[::1]:6667/; | ||
# For IPv4 loopback (there's almost no reason to do this) | |||
# proxy_pass http://127.0.0.1:6667/; | |||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
} | } | ||
}</nowiki> | }</nowiki> | ||
=== As | ==== As a Subdirectory ==== | ||
'''Note:''' | |||
* There is intentionally no <code>/</code> after the port number. | |||
* You must set <code>URIPrefix</code> of the Listener in ZNC to the target location | |||
<nowiki>server { | <nowiki>server { | ||
... | ... | ||
location /znc/ { | location /znc/ { | ||
proxy_pass http:// | proxy_pass http://[::1]:6667; | ||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
} | } | ||
}</nowiki> | }</nowiki> | ||
On most distributions this would be put in <code>/etc/nginx/conf.d/znc.example.test.conf</code> . | |||
=== HTTPS === | |||
This is a basic configuration utilizing Diffie Hellman key exchange: | |||
<nowiki> | |||
server { | |||
listen 192.0.2.1:7001 ssl http2; | |||
listen [2001:db8::192:0:2:1]:7001 ssl http2; | |||
server_name znc.example.test; | |||
access_log /var/log/nginx/znc.example.test/znc_ssl-access.log; | |||
error_log /var/log/nginx/znc.example.test/znc_ssl-error.log; | |||
# SSL options | |||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; | |||
ssl_certificate /etc/letsencrypt/live/znc.example.test/fullchain.pem; | |||
ssl_certificate_key /etc/letsencrypt/live/znc.example.test/privkey.pem; | |||
ssl_dhparam /etc/letsencrypt/live/znc.example.test/dhparam.pem; | |||
ssl_trusted_certificate /etc/letsencrypt/live/znc.example.test/chain.pem; | |||
location / { | |||
proxy_pass http://[::1]:7001$request_uri; | |||
# For IPv4 loopback (there's almost no reason to do this) | |||
# proxy_pass http://127.0.0.1:7001$request_uri; | |||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |||
} | |||
}</nowiki> | |||
On most distributions this would be put in <code>/etc/nginx/conf.d/znc.example.test.conf</code> . | |||
=== IRC === | |||
Nginx has a directive separate from <code>http</code> called [https://nginx.org/en/docs/stream/ngx_stream_core_module.html stream] for protocols other than HTTP. We can utilize this to allow nginx to act as a reverse proxy for ZNC: | |||
<nowiki> | |||
upstream znc { | |||
server [::1]:7000; | |||
# For IPv4 loopback (there's almost no reason to do this) | |||
# server 127.0.0.1:7000; | |||
} | |||
server { | |||
listen 192.0.2.1:7000 ssl; | |||
listen [2001:db8::192:0:2:1]:7000 ssl; | |||
# SSL options | |||
ssl_certificate /etc/letsencrypt/live/znc.example.test/fullchain.pem; | |||
ssl_certificate_key /etc/letsencrypt/live/znc.example.test/privkey.pem; | |||
ssl_dhparam /etc/letsencrypt/live/znc.example.test/dhparam.pem; | |||
ssl_trusted_certificate /etc/letsencrypt/live/znc.example.test/chain.pem; | |||
proxy_pass znc; | |||
}</nowiki> | |||
On most distributions these would be put in <code>/etc/nginx/conf.d/znc.example.test.stream</code> . | |||
=== Additional Configuration Abilities === | |||
Nginx has many configuration options that can enhance the behavior of both the ZNC web interface and IRC, so the <code>http</code> or <code>server</code> nginx directive options below only demonstrate the most common portions of them: | |||
<nowiki> | |||
sendfile on; | |||
tcp_nopush on; | |||
tcp_nodelay on; | |||
keepalive_timeout 65; | |||
types_hash_max_size 2048; | |||
server_tokens off; | |||
# Compression | |||
gzip on; | |||
gzip_comp_level 9; | |||
gzip_types application/javascript application/vnd.ms-fontobject application/x-font-otf application/x-font-ttf application/x-font-woff image/jpg image/png image/svg image/x-icon text/css; | |||
############### | |||
# SSL options # | |||
############### | |||
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:DHE-DSS-AES256-GCM-SHA384:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256; | |||
ssl_ecdh_curve secp384r1; | |||
ssl_protocols TLSv1.2 TLSv1.3; | |||
ssl_prefer_server_ciphers on; | |||
ssl_session_cache shared:https:15m; | |||
ssl_session_timeout 15m; | |||
# Stapling | |||
ssl_stapling on; | |||
ssl_stapling_verify on; | |||
resolver 1.1.1.1 8.8.8.8 [2606:4700:4700::1111] [2001:4860:4860::8888]; | |||
</nowiki> | |||
== lighttpd == | == lighttpd == | ||
=== HTTP === | |||
<nowiki>$HTTP["host"] =~ "^(sub\.domain\.com)$" { | <nowiki>$HTTP["host"] =~ "^(sub\.domain\.com)$" { | ||
proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => 6667 ) ) ) | proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => 6667 ) ) ) | ||
}</nowiki> | }</nowiki> |
Revision as of 00:35, 21 October 2019
About Reverse Proxies
While ZNC is a fantastic bouncer, in many situations it can be beneficial to utilize a reverse proxy in front of it for features such as:
- Subdomains
- Tighter control of SSL ciphers and protocols
- ECDH support
- SSL session caching
- SSL stapling
- Compression
Notes
TrustedProxy
must be set in your configuration for web access logs to reflect actual addresses instead of the reverse proxy address (127.0.0.1
/::1
):
TrustedProxy = 127.0.0.1 TrustedProxy = ::1
Nginx
Note: If you plan on utilizing Nginx for IRC in conjunction with HTTP/HTTPS, the port number (or address) of the two services must be different.
HTTP
As a Subdomain
server { listen 192.0.2.1:80; listen [2001:db8::192:0:2:1]:80; server_name znc.example.test; access_log /var/log/nginx/znc.example.test/znc-access.log; error_log /var/log/nginx/znc.example.test/znc-error.log; location / { proxy_pass http://[::1]:6667/; # For IPv4 loopback (there's almost no reason to do this) # proxy_pass http://127.0.0.1:6667/; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
As a Subdirectory
Note:
- There is intentionally no
/
after the port number. - You must set
URIPrefix
of the Listener in ZNC to the target location
server { ... location /znc/ { proxy_pass http://[::1]:6667; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
On most distributions this would be put in /etc/nginx/conf.d/znc.example.test.conf
.
HTTPS
This is a basic configuration utilizing Diffie Hellman key exchange:
server { listen 192.0.2.1:7001 ssl http2; listen [2001:db8::192:0:2:1]:7001 ssl http2; server_name znc.example.test; access_log /var/log/nginx/znc.example.test/znc_ssl-access.log; error_log /var/log/nginx/znc.example.test/znc_ssl-error.log; # SSL options add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; ssl_certificate /etc/letsencrypt/live/znc.example.test/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/znc.example.test/privkey.pem; ssl_dhparam /etc/letsencrypt/live/znc.example.test/dhparam.pem; ssl_trusted_certificate /etc/letsencrypt/live/znc.example.test/chain.pem; location / { proxy_pass http://[::1]:7001$request_uri; # For IPv4 loopback (there's almost no reason to do this) # proxy_pass http://127.0.0.1:7001$request_uri; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
On most distributions this would be put in /etc/nginx/conf.d/znc.example.test.conf
.
IRC
Nginx has a directive separate from http
called stream for protocols other than HTTP. We can utilize this to allow nginx to act as a reverse proxy for ZNC:
upstream znc { server [::1]:7000; # For IPv4 loopback (there's almost no reason to do this) # server 127.0.0.1:7000; } server { listen 192.0.2.1:7000 ssl; listen [2001:db8::192:0:2:1]:7000 ssl; # SSL options ssl_certificate /etc/letsencrypt/live/znc.example.test/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/znc.example.test/privkey.pem; ssl_dhparam /etc/letsencrypt/live/znc.example.test/dhparam.pem; ssl_trusted_certificate /etc/letsencrypt/live/znc.example.test/chain.pem; proxy_pass znc; }
On most distributions these would be put in /etc/nginx/conf.d/znc.example.test.stream
.
Additional Configuration Abilities
Nginx has many configuration options that can enhance the behavior of both the ZNC web interface and IRC, so the http
or server
nginx directive options below only demonstrate the most common portions of them:
sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; server_tokens off; # Compression gzip on; gzip_comp_level 9; gzip_types application/javascript application/vnd.ms-fontobject application/x-font-otf application/x-font-ttf application/x-font-woff image/jpg image/png image/svg image/x-icon text/css; ############### # SSL options # ############### ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:DHE-DSS-AES256-GCM-SHA384:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256; ssl_ecdh_curve secp384r1; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_session_cache shared:https:15m; ssl_session_timeout 15m; # Stapling ssl_stapling on; ssl_stapling_verify on; resolver 1.1.1.1 8.8.8.8 [2606:4700:4700::1111] [2001:4860:4860::8888];
lighttpd
HTTP
$HTTP["host"] =~ "^(sub\.domain\.com)$" { proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => 6667 ) ) ) }