How to configure PROXY protocol in varnish upstream - proxy

I found that to accept PROXY protocol connections in varnish all I need to do is to run varnish with extra -a :1234,PROXY parameter.
But what about sending those connections to upstream?
If I have following infrastructure:
- TLS -|- VARNISH -|- NGINX - PHP
| |- ...
- TLS -|- VARNISH -|- NGINX - PHP
How should I configure Varnish to use PROXY protocol in Varnish -> Nginx connection.

As described in https://varnish-cache.org/docs/6.0/reference/vcl.html#backend-definition, you can add a .proxy_header property to your backend definition to forward the PROXY protocol to your origin webserver.
Here's an example definition:
vcl 4.1;
backend default {
.host = "localhost";
.port = "8080";
.proxy_header = 2;
}
This assumes Nginx is running locally on port 8080 and supports PROXY protocol v2.
While Nginx supports listen 8080 proxy_protocol;, I'm not sure this is part of their open source offering.
The documentation on https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/ refers to Nginx Plus though.

Related

Squid4 forward proxy to upgrade from ws to wss

Squid4.6 is used as a forward proxy to convert all traffic to secure traffic.
The configuration of squid is very simple, it allows all traffic and uses urlrewrite.pl to replace "http" to "https".(SSL-BUMP is NOT used) Squid proxy has tls_outgoing_options set, so the following works:
client(http) -----> Squid ------> Server(https)
Now, I am trying to replicate the same with websockets.
There are 3 test cases,
1.
client(ws)------> Squid -----> Server(ws)
client(wss) ------> Squid -----> Server(wss)
3
client(ws) ------> Squid -----> Server(wss)
The first two cases work with squid, but the third one does not work. And I only need the third option.
I have given debug logs for urlrewrite.pl to show the exact request received for a websocket connection, and the following is the log:
Here port 8080: is server and port 3128: is squid
DEBUG:root:localhost:8080 127.0.0.1/localhost - CONNECT myip=127.0.0.1 myport=3128
Even wireshark shows the same,
1. CONNECT HTTP 1.1
2. GET
3. upgrade protocol.
Question:
1.Is there any way to upgrade a websocket connection to secure websocket using squid4.6?
2.Or say I use wss-client (without certificate) and a wss-server(with certificates), is there a way to inform squid to use its own certificates even mentioned in "tls_outgoing_options" to establish the connection?
REQUIRED:
Client will always send a unsecure traffic HTTP/WS
and Squid should upgrade it to HTTPS/WSS.
In our application setup, we use our own openssl libraries to create certificates - which cannot be included in the (client.go) go-tls package, so we use squid proxy to use the certificates generated by our own openssl libraries.
Client and Forward-Proxy (Squid) are both in our specific environment, so squid.conf is very simple and allows all traffic.
And we need mutual cert authentication.
SQUID CONF CODE
#
# Recommended minimum configuration:
#
# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localhost src 127.0.0.1
acl SSL_ports port 443
acl Safe_ports port 443 # https
acl Safe_ports port 80 # http
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost
http_access deny all
# Squid normally listens to port 3128
http_port 3128
url_rewrite_program /etc/squid/urlrewrite.pl
url_rewrite_access allow all
tls_outgoing_options cert=/etc/squid/proxy.crt
tls_outgoing_options key=/etc/squid/proxy.key
tls_outgoing_options cafile=/etc/squid/serverauth.crt
urlrewrite CODE
#!/usr/bin/perl
select(STDOUT);
$| = 1;
while (<>) {
#print STDOUT "OK rewrite-url=\"https://google.com\"\n";
if (/^(|\d+\s+)((\w+):\/+)([^\/:]+)(|:(\d+))(|\/\S*)(|\s.*)$/) {
my $channel = $1;
my $protocolClean = $3;
my $domain = $4;
my $port = $5;
my $portClean = $6;
my $urlPath = $7;
if ($protocolClean eq 'http' ){#&& ($port eq '' || $portClean eq '80')) {
print STDOUT "${channel}OK rewrite-url=\"https://${domain}${port}${urlPath}\"\n";
#print STDOUT "${channel}OK rewrite-url=\"https://google.com\"\n";
} else {
print STDOUT "${channel}ERR\n";
}
}
}

Getting subdomains to work locally with Laravel

I am having a hard time getting subdomains to work locally. I have Docker serving the application to port 8080, and I am able to see the Laravel welcome screen. I then have a simple route setup like this:
Route::domain('{name}.localhost:8087')->group(function () {
return 'Hello World';acrylic dns
});
I am using Laravel's basic server, i.e. php artisan serve --host=0.0.0.0 --port=8087
When I try and view the page, nothing happens. It just goes to the welcome screen. I have even tried adding 'test.localhost' to the /etc/hosts file. Couple questions:
1) Can you have the port in the host like I have it there (in the Laravel route)?
2) I have seem somewhat similar posts where the solution was to use acrylic dns (on windows). I am using a Mac. Is this something where I need an actual DNS server?
3) I am planning on using nginx, do I need a 'beefier' web server to accomplish this?
With the basic Laravel server I have tried hard coding test.localhost in the route, with and without the port. I'm sure I am goofing something up, just not sure where. I am on a Mac, and I am running Laravel 5.6. Thanks in advance!
1) No, the web server configuration will listen on the port.
// nginx
server {
listen 8080;
...
}
2) You add the subdomains in your /etc/hosts file and create separate nginx configurations:
// /etc/hosts
subdomain1.foo.localhost 127.0.0.1
subdomain2.foo.localhost 127.0.0.1
subdomain3.foo.localhost 127.0.0.1
// nginx subdomain1.foo.localhost.conf
server {
listen 8080;
server_name subdomain1.foo.localhost;
...
}
// nginx subdomain2.foo.localhost.conf
server {
# set different port if needed
# listen 8082
listen 8080;
server_name subdomain2.foo.localhost;
...
}
// nginx subdomain3.foo.localhost.conf
server {
# set different port if needed
# listen 8083
listen 8080;
server_name subdomain3.foo.localhost;
...
}
3) Nginx is a production ready web server, you may need load balancers and multiple instances of the web servers to scale out, but nginx will be more than sufficient.
If you're using Artisan serve, go to
/etc/hosts (or similar)
127.0.0.1 subdomain.localhost
And open in the browser
subdomain.localhost:8087

docker + haproxy on mac 10.11.5 doesn't work

I am running an haproxy configuration on mac that works perfect on linux but I can't get the proxy to even respond. Here is my config:
defaults
mode http
timeout connect 5000ms
timeout client 5000ms
timeout server 5000ms
frontend http
bind *:80
acl oracle_content hdr(ContentType) -i application/vnd.api+json
acl oracle_accept hdr(Accept) -i application/vnd.api+json
use_backend oracle_be if oracle_content
use_backend oracle_be if oracle_accept
default_backend matrix_be
backend oracle_be
balance roundrobin
server oracle1 theoracle.stage.company.com:8080
backend matrix_be
balance roundrobin
server matrix1 192.168.1.6:3000
docker run -d --name cc -v /Users/cbongiorno/development/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro haproxy
docker -v
Docker version 1.12.0, build 8eab29e
the only machine specific config is the IP adress of the matrix_be entry which has to be my local interface. It's not working on 2 macs and I have tried binding the proxy to multiple interfaces. I am not even getting a 504 which would indicate the proxy is fine but one of the backend services is misconfigured.
Ideas?
Due to current docker on mac limitations, the -p 80:80 flag must be passed even if the container declares port 80 open for business

Haproxy redirect configuration for plex?

Hope someone can help me :)
I try to configure HAProxy for plex redirection but didn't found the solution yet.
So basically to run plex home page you should go to => IPADRESS:PORT/web which redirect to IPADRESS:PORT/web/index.html
I made this kind of redirect:
use_backend plex if { hdr_beg(Host) -i plex. }
backend plex
server plex localhost:32400 check
This is ok, i can join plex => plex.mydomain.tld/web
But i would like to be able to join plex with this URL => plex.mydomain.tld
I tried to add this line:
reqrep ^([^\ :]*)\ /(.*) \1\ /web\2
Changing is fine, my URL switch to => plex.mydomain.tld/web/index.html
But i have a 404 ERROR...
What kind of trick i should do to acces plex from plex.mydomain.tld ?
Thanks !
Found some info that helped me figure it out:
global
log 127.0.0.1 syslog
maxconn 1000
user haproxy
group haproxy
daemon
tune.ssl.default-dh-param 4096
ssl-default-bind-options no-sslv3 no-tls-tickets
ssl-default-bind-ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
defaults
log global
mode http
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
option contstats
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout check 10s
listen stats
bind *:9090
mode http
maxconn 10
stats enable
stats hide-version
stats realm Haproxy\ Statistics
stats uri /
stats auth admin:admin
frontend ALL
bind *:80
bind *:443 ssl crt /etc/haproxy/certs/nomercy.myqnapcloud.com.pem crt /etc/haproxy/certs/nomercy.myqnapcloud.com.pem
mode http
# Define path for lets encrypt
acl is_letsencrypt path_beg -i /.well-known/acme-challenge/
use_backend letsencrypt if is_letsencrypt
# Define hosts
acl host_website hdr(host) -i nomercy.myqnapcloud.com
# Direct hosts to backend
use_backend website if host_website
# Redirect port 80 to 443
# But do not redirect letsencrypt since it checks port 80 and not 443
redirect scheme https code 301 if !{ ssl_fc } !is_letsencrypt
backend letsencrypt
server letsencrypt 127.0.0.1:8888
backend website
balance roundrobin
option httpchk GET /check
cookie SERVERID insert indirect nocache
http-check expect rstring ^UP$
default-server inter 3s fall 3 rise 2
server server1 192.168.2.151:8888 check
server server2 192.168.2.152:8888 check
server server3 192.168.2.153:8888 check
listen plex
bind *:32400 ssl crt /etc/haproxy/certs/nomercy.myqnapcloud.com.pem crt /etc/haproxy/certs/nomercy.myqnapcloud.com.pem
balance roundrobin
option httpchk GET /check
http-check expect rstring ^UP$
default-server inter 3s fall 3 rise 2
server server1 192.168.2.149:32400 check port 8888
server server2 192.168.2.148:32400 check port 8888
server server3 192.168.2.147:32400 check port 8888
You can remove the ssl credentials if you don't have it installed.
The problem here unfortunately has nothing to do with your HAProxy configuration. Instead it is Plex that is causing the issue.
Example
With your configuration, when you go to plex.mydomain.tld HAProxy is adding in the /web and as a result Plex gets the following url: plex.mydomain.tld/web. This is correct however Plex will then want to forward the browser on to plex.mydomain.tld/web/index.html. But when the browser sends a request or that url, HAProxy steps in and adds that extra /web again and the resulting url that is set to Plex is plex.mydomain.tld/web/web/index.html which doesn't exist and hence the 404 error you got.
While going to plex.mydomain.tld/index.html may work, I assume all links from that page to any other page won't work due to the say issue.
To solve this you could
Look through Plex's configuration to see if it is possible to run it with out the /web.
Taking inspiration from here, you could configure HAProxy something like this:
frontend http
mode http
bind *:80
acl plex hdr_beg(Host) -i plex.
acl root_dir path_reg ^$|^/$
acl no_plex_header req.hdr_cnt(X-Plex-Device-Name) -i 0
redirect location http://plex.mydomain.tld/web/index.html 301 if no_plex_header root_dir plex
use_backend plex if plex
backend plex
server plex localhost:32400 check
The key difference being the redirect location line which will redirect from / to /web/index.html if the header X-Plex-Device-Name isn't set. The reason you have to check for the header is that it appears that plex uses / for something else.
Note: This config is an example and I haven't tested this at all
Hope that helps.
I want to echo that I used the solution provided by JamesStewy and it worked, with the minor correction;
redirect location http://plex.mydomain.tld/web/index.html code 301 if no_plex_header root_dir plex
At least, that was necessary for me (running haproxy 1.7.2).

Ngrok configure multiple port in same domain

Is it possible to open multiples ports in ngrok in same domain?
Something like:
Fowarding http://example.ngrok.com:50001 -> 127.0.0.1:50001
Fowarding http://example.ngrok.com:50002 -> 127.0.0.1:50002
I´m working in windows and it'll be useful for debuging with IIS Express
Yes, it is possible using multiple simultaneous tunnels, within the same hostname !
All you need to do, is to declare them on your configuration file, like this:
authtoken: 4nq9771bPxe8ctg7LKr_2ClH7Y15Zqe4bWLWF9p
tunnels:
first-app:
addr: 50001
proto: http
hostname: example.ngrok.com
host_header: first-app.example.ngrok.com
second-app:
addr: 50002
proto: http
hostname: example.ngrok.com
host_header: second-app.example.ngrok.com
And run them with:
ngrok start --all
Look on the documentation for options, like hostname, subdomain, authtoken and host_header. Hope this help you !
P.S For Free plan remove custom host and header part
like this it will be different domains FYI.
authtoken: 6yMXA63qefMZqCWSCHaaYq_5LufcciP1rG4LCZETjC6V
tunnels:
first:
addr: 3002
proto: http
second:
addr: 8080
proto: http
NOTES:
To find your default config file read https://ngrok.com/docs#config-default-location.
All plans issues an auth token. You can find yours in the web dashboard: https://dashboard.ngrok.com/get-started
What worked for me with ngrok w/ multiple ports
So I had the issue where I needed the same domain origin policy to work for different ports but I was halted in my tracks because ultimately ngrok does not support this. They support a custom subdomain or custom domain but not on different ports since all must come through port 80 or 443.
Instead of quitting, I had to hack things together using nginx locally like so:
http {
server {
listen 7777;
server_name localhost;
location / {
proxy_pass http://127.0.0.1:5000;
}
location /api {
proxy_pass http://127.0.0.1:8000;
}
}
}
I was fortunate the api server prefixed all calls "api" so I could route the api calls to a specific port and still serve the other traffic on another web server and you may not be so lucky.
I then configured the public web server to route all api calls to the same ngrok address and let ngnix sort it out.
I hope this may help you think of a combination of solutions to get there as thinking only one way may get you stuck as I was.
Go To These location :
OS X: /Users/example/.ngrok2/ngrok.yml
Linux: /home/example/.ngrok2/ngrok.yml
Windows: C:\Users\example\.ngrok2\ngrok.yml
then open yml file in notepad and paste below code and save.
authtoken: your_token
tunnels:
first:
addr: 3002
proto: http
second:
addr: 8080
proto: http
now go to your ngrok location and run ngrok start --all
I used on ngrok process (on a reserved domain) pointing to port 80 locally.
ngrok http 80
Locally I have nginx running the following config. The only thing that matters to me are the 2 locations /admin and /api as those are what I was previously using multiple ngrok prcesses for. nginx allows you to use the same tunnel for separate locations.
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
server_name _;
location /admin {
proxy_pass http://127.0.0.1:3005;
}
location /api {
proxy_pass http://127.0.0.1:5001;
}
}
This is how you can do using subdomain (Following #robe007 answer)
authtoken: your_auth_token
region: au
tunnels:
frontend:
proto: http
addr: http://localhost:3000
bind_tls: true
subdomain: frontend-my-domain
host_header: rewrite
backend:
proto: http
addr: http://localhost:5001
bind_tls: true
subdomain: backend-my-domain
host_header: rewrite
Then run ngrok start --all
Unfortunatly none of the following solutions worked for me but after multiple hours typing code with my nose i figured a way to solve this problem:
authtoken: your_private_token
tunnels:
baseAPI:
proto: http
addr: https://localhost:44307/
host_header: localhost:44307
authAPI:
proto: http
addr: https://localhost:44305/
host_header: localhost:44305
The diference is instead of using only the port on the addr field, i used the full link and added the host_header too.
Using free plan
Actually, at 2023, I'm just supporting the original answer.
And, showing how to edit the ngrok config file (ngrok.yml).
In CMD do:
ngrok config edit
Something like this:
version: "2"
authtoken: your_token_here
tunnels:
any1:
addr: 8888
proto: http
any2:
addr: 8080
proto: http
any3:
addr: 50000
proto: http
Finally, again in CMD, start ngrok:
ngrok start --all
Be happy!

Resources