check if request is ssl in an haproxy offload ssl environment - php

I have a pound server with ssl offload in front of a haproxy.
How can I check in my php code if the request has been done with ssl if I have offload ssl and the ssl doesn't hit the web server?
Maybe put some header tag or something in haproxy to the ssl request so I can check this header in the code?

From HAProxy and SSL
The configuration directive below must be inserted in the Frontend configuration. It tells HAProxy to add a header named X-SSL which contains the information about the type of frontend connection:
http-request set-header X-SSL %[ssl_fc]
This should then show up in $_SERVER['HTTP_X_SSL'].

The solution I came up is to add the header in Pound configuration and check this header in the code:
AddHeader "X-Pound: SSL"

Related

Nginx it is possible to add ssl_client_verify to request header without proxy to let Symfony know a client ssl certificate is being used?

For a website I'm using a nginx configuration that requires a client ssl certificate. I want my Symfony/php project to be able to verify that a client ssl certificate is being used (and provide some extra information from the certificate as well). So I was thinking of doing this by adding it to the request http header.
In my nginx site configuration I have set:
ssl_client_certificate /home/user/ssl/ca.crt;
ssl_verify_client on;
This works, the client certificate is obligatory.
But I want my underlaying Symfony/php project to be able to verify that a client certificate is being used. I was thinking of adding it to the http request header, but I seem only to be able to add it to the http response header (back to the browser) like this (in the same nginx site config):
location / {
try_files $uri /app.php$is_args$args;
add_header X-ssl-client-verify $ssl_client_verify;
}
In firefox I can see this response header indeed, but that is not what I want (and can be a security hazzard). I've also looked into this:
proxy_set_header X-ssl-client-verify $ssl_client_verify;
But this does not work because I'm not using a proxy.
Is there some other way to add an element to the request header? Or is there an alternative way to get client ssl certificate information into my Symfony / php project?

There is mismatch between HTTPS indicated on the server and client

This is the warning when I open my phpMyAdmin's login (index) page:
There is mismatch between HTTPS indicated on the server and client.
This can lead to non working phpMyAdmin or a security risk.
Please fix your server configuration to indicate HTTPS properly.
The error should be caused by a loadbalancer in between my client and phpmyadmin itself. SSL terminates on the loadbalancer so the URL being used (that phpmyadmin receives in request headers, I assume) is https://mydomain/phpmyadmin.
The loadbalancer communicates with phpmyadmin via http, so the URL being used between lb and pma is http://mydomain/phpmyadmin (not https).
I found this very fitting article on github: Possibility to deactivate SSL connection #170 which is for Docker containers and describes an env var to be passed to the container called "PMA_ABSOLUTE_URI" to fix the problem.
Which setting would this be in phpmyadmin NON Docker?
Any other solution to my problem is also highly appreciated.
Sidenote: Phpmyadmin works fine after the login. You can log in, there are no warnings after the log in and you can perform all interactions without problems. I am just worried about the warning.
I have exactly the same setup as you are describing. A front load balancer acts as reverse proxy and also as SSL/TLS terminator. The LB talks in plain http with the backend server where phpMyAdmin is running.
When I upgraded from 4.0.4.1 to 4.9.0.1 I got the same warning appearing at the phpMyAdmin login screen as you. I was able to solve this on the reverse proxy by "faking" the protocol from http to https. In my case my reverse proxy is a Nginx web server and just before I'd pass to the backend server, I added X-Forwarded-Proto:
server {
listen 443;
server_name my.phpmyadmin.example.com;
[... log and ssl settings ...]
location / {
include /etc/nginx/proxy.conf;
proxy_set_header X-Forwarded-Proto https;
proxy_pass http://backendserver;
}
}
By adding proxy_set_header X-Forwarded-Proto https; this tells the backend server that the client to proxy communication happens over https. Without setting this header, phpMyAdmin probably identifies (not sure, just a guess) that it was loaded on a https:// URL yet the communication (between reverse proxy and phpMyAdmin server) happened over http. Therefore it's a correct warning to be shown.
As soon as Nginx was reloaded, the warning disappared from the phpMyAdmin login screen.

HTTP forwarding PLAINTEXT warning

When I run this SSL test:
https://www.ssllabs.com/ssltest/analyze.html?d=rickschmitz.network
I get the following warning :
HTTP forwarding http://www.rickschmitz.network PLAINTEXT
What does this mean and how can I fix this?
This means that when requesting in HTTPS the response is a redirection to an HTTP URL (http://www.rickschmitz.network as given by SSLLabs). The browser is supposed to warn you when you are leaving the "secure" browsing. To fix it, check your Apache configuration at the SSL virtual host (should be in conf/extra/httpd-ssl.conf)

Configuring Haproxy to allow http CRUD (rewrite rules)

I'm using haproxy to loadbalance and get high availability of my (RESTFUL)API, the problem I'm facing is: I can't send REST requests to the API.
I mean haproxy does not support REST API by default and I've figured that I should configure an ACL to make it work, but I couldn't find anything about configuring RESTFUL Support and enabaling http rewrite rules for haproxy.
MY API is based on laravel framework.
For example If I hit 192.168.1.139/login I get 404 error message. the only route which is working is / Which shows the user "you are not logged in." message.
This is haproxy configuration :
listen http_front
bind *:80
mode http
stats enable
stats uri /haproxy?stats
option httpclose
option forwardfor
#acl api_exp hdr(host) -i domain_name.com
#use_backend api_servers if api_exp
default_backend api_servers
backend api_servers
balance roundrobin
server replica1 192.168.100.110:80 check
server replica2 192.168.100.111:80 check
It's a bit strange but I've solved my problem with this configuration :
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
timeout connect 5000
timeout client 100s
timeout server 100s
listen ha-www
bind 0.0.0.0:80
mode http
stats enable
stats uri /haproxy?stats
stats realm Strictly\ Private
balance roundrobin
option httpclose
option forwardfor
server app-www-1 192.168.100.110:80 check
server app-www-2 192.168.100.111:80 check

HTTPS Header Redirect Not Working with PHP

I have a load balanced dev site that I'm working out bugs for SSL on and I have ran into one last very annoying issue. On some pages I need to force it to SSL so easy enough, I just wanted to create a
header ("Location: https://www.example.com/mypage.php");
I thought that was easy enough and no worries. However, every time I do this it transforms it back to http. Well as you can figure it creates an endless loop that can't be resolved. I can't figure out how to keep that https in there so that it will pull the secure version of the page. If I navigate directly to the secure page with https it works just fine. The only issue is on this redirect.
Any help would be awesome! I'm using POUND as a load balance proxy. Apache on the web-server nodes. The SSL cert is setup at the Load Balancer.
When loadbalancing, 'internal' SSL usually goes out the door: Clients connect through a load-balancer with which you can do SSL encryption, but behind that in most loadbalancers I've seen is plain 'HTTP'. Try to get your loadbalancer to set a custom header to you indicating that there is a HTTPS connection between loadbalancer & client.
From http://www.apsis.ch/pound/index_html
WHAT POUND IS:
...
an SSL wrapper: Pound will decrypt HTTPS requests from client browsers and pass them as plain HTTP to the back-end servers.
And from more manual pages:
HTTP Listener
RewriteLocation 0|1|2
If 1 force Pound to change the Location: and Content-location:
headers in responses. If they point to the back-end itself or to
the listener (but with the wrong protocol) the response will be
changed to show the virtual host in the request. Default: 1
(active). If the value is set to 2 only the back-end address is
compared; this is useful for redirecting a request to an HTTPS
listener on the same server as the HTTP listener.
redirecting to https pages is no problem.
you can check for the port, scheme or server variable (probably server variable is the best) to see if https is on, and have it as a condition for redirecting
$_SERVER['SERVER_PORT'] == 443
parse_url($_SERVER['REQUEST_URI'],PHP_URL_SCHEME) == 'https'
$_SERVER['HTTPS'] == 'on'
but as you have an infinite loop there must be something else wrong!
try using the load blancer "balance" instead. it only takes about 5 minutes to set up, and instead of proxying, will do "real" load balancing. I would guess your proxy is currently redirecting https requests to the http address. Try making a request without using the balancer. you can do this by setting up the host name in your /etc/hosts file to point directly to a server instead of to the load balancer's IP

Categories