Reputation: 81
Any one familiar with nginx? I am trying to enable proxy_protocol in a conditional manner in a stream block ie for certain endpoints I want the proxy protocol header to be added. For others I dont want to add it. Looking at the documentation there is no way for proxy_protocol to take a variable (Tried the map directive) Any suggestions on how to achieve this? Added my nginx conf here. http://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_protocol
This is the problematic piece proxy_protocol $proxy_state;
map $ssl_preread_server_name $proxy_state{
default on;
facebook.com off;
}
server {
listen 8443 ;
resolver 8.8.8.8 ipv6=off;
proxy_pass $server;
proxy_protocol $proxy_state;
ssl_preread on;
}
The following is the complete config
error_log logs/error.log;
events {
}
stream {
map $ssl_preread_server_name $server {
# default 127.0.0.1:8080;
default unix:/var/run/nginx.sock;
include /home/user/allow_url_list;
}
map $ssl_preread_server_name $proxy_state{
default on;
facebook.com off;
}
server {
listen 8443 ;
resolver 8.8.8.8 ipv6=off;
proxy_pass $server;
proxy_protocol $proxy_state;
ssl_preread on;
}
}
http {
server {
listen 8080 ssl;
listen 80;
listen unix:/var/run/nginx.sock ssl proxy_protocol;
set_real_ip_from unix:;
real_ip_header proxy_protocol;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
include /home/conf/ssl-params.conf;
location / {
resolver 8.8.8.8;
proxy_pass https://$host$request_uri;
}
}
}
Upvotes: 6
Views: 2239
Reputation: 1
I have a similar question to yours. In my situation, I need to proxy both frps service and a website on the same port, 443. The former uses a custom first byte in the TLS handshake, which makes it difficult to proxy via the HTTP block. Additionally, I need to identify the source IP of connections to my website to implement per-IP rate limiting.
To meet these requirements, I use the following configuration in the stream block:
map $ssl_preread_server_name $name_https {
frps.example.com frps_https;
default nginx_https;
}
upstream frps_https {
server 127.0.0.1:3211;
}
# A wrapper to the FRPS connection to absorb pp packet after handshake (I guess)
server {
listen 3211 proxy_protocol;
proxy_pass 127.0.0.1:7000;
}
upstream nginx_https {
server 127.0.0.1:8443;
}
server {
listen 443 reuseport;
listen [::]:443 reuseport;
proxy_pass $name_https;
proxy_protocol on;
ssl_preread on;
}
To be honest, I'm not an expert in nginx, but this configuration works magically. What it does is enable the proxy_protocol
by default and then "disable" it for upstreams that don't require it.
In your situation, you may try the following configuration (untested):
# events ...
stream {
map $ssl_preread_server_name $proxy_server {
facebook.com 127.0.0.1:9443;
default 127.0.0.1:10443;
}
map $ssl_preread_server_name $server {
default unix:/var/run/nginx.sock;
include /home/user/allow_url_list;
}
server {
listen 9443 proxy_protocol;
proxy_pass $server;
ssl_preread on;
}
server {
listen 10443 proxy_protocol;
proxy_pass $server;
proxy_protocol on;
ssl_preread on;
}
server {
listen 8443;
proxy_pass $proxy_server;
resolver 8.8.8.8 ipv6=off;
proxy_protocol on;
ssl_preread on;
}
}
# http ...
Upvotes: 0
Reputation: 1
You can split it into 2 servers. you can try if it works. Proxy protocol might cause problems.
map $ssl_preread_server_name $internalport {
facebook.com 10443;
default 8443;
}
server {
listen 8443 ;
resolver 8.8.8.8 ipv6=off;
proxy_pass $server;
proxy_protocol on;
ssl_preread on;
}
server {
listen 10443 ;
resolver 8.8.8.8 ipv6=off;
proxy_pass $server;
proxy_protocol off;
ssl_preread on;
}
Upvotes: -1