Is it possible to compare compare two variables in an HAProxy ACL statement? For example, assuming that both the host header and X-CORRECT-HOST header are equal to "example.com".
acl correct_host hdr(host) -i example.com # THIS RETURNS TRUE
acl correct_host hdr(X-CORRECT-HOST) -i example.com # THIS RETURNS TRUE
I've tried a few things and read through the documentation, but can't seem to get anything to work. Here's a couple examples I tried that all return false:
acl correct_host hdr(host) -i hdr(X-CORRECT-HOST)
acl correct_host hdr(host) -m str hdr(X-CORRECT-HOST)
acl correct_host hdr(host) -i %[hdr(X-CORRECT-HOST)]
acl correct_host hdr(host) -m str %[hdr(X-CORRECT-HOST)]
You can use lua(need to build haproxy with lua support)
you can check with:
haproxy -vv|grep -i lua
somethig like this:
OPTIONS = USE_ZLIB=1 USE_OPENSSL=1 USE_LUA=1
Built with Lua version : Lua 5.3.1
or build with lua, something like:
make TARGET=linux2628 USE_LUA=1 LUA_LIB=/opt/lua-5.3.1/lib LUA_INC=/opt/lua-5.3.1/include
then
$ ./haproxy -v
Nuster version 2.0.0.18
Copyright (C) 2017-2018, Jiang Wenyuan, <koubunen AT gmail DOT com >
HA-Proxy version 1.8.12 2018/06/27
Copyright 2000-2018 Willy Tarreau <willy#haproxy.org>
conf:
global
debug
lua-load compare_header_value.lua
frontend web1
bind *:8080
mode http
default_backend app1
backend app1
mode http
http-request set-var(req.two_header_value_equal) lua.compare_header_value(hdr1,hdr2)
http-request deny unless { var(req.two_header_value_equal) -m bool }
server s1 127.0.0.1:8000
compare_header_value.lua
function compare_header_value(txn, h1, h2)
local hdr = txn.http:req_get_headers()
if hdr[h1] == nil or hdr[h2] == nil then
return false
end
if hdr[h1][0] == hdr[h2][0] then
return true
end
return false
end
core.register_fetches("compare_header_value", compare_header_value)
then you can use ACL like this:
http-request deny unless { var(req.two_header_value_equal) -m bool }
Test:
1 same header
curl -v http://127.0.0.1:8080/ -H "hdr1: 1" -H "hdr2: 1"
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.60.0
> Accept: */*
> hdr1: 1
> hdr2: 1
>
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
2 different header
curl -v http://127.0.0.1:8080/ -H "hdr1: 1" -H "hdr2: 2"
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.60.0
> Accept: */*
> hdr1: 1
> hdr2: 2
>
* HTTP 1.0, assume close after body
< HTTP/1.0 403 Forbidden
It can be done with strcmp
https://cbonte.github.io/haproxy-dconv/2.6/configuration.html#7.3.1-strcmp
e.g.
http-request set-var(txn.host) hdr(host)
# Check whether the client is attempting domain fronting.
acl ssl_sni_http_host_match ssl_fc_sni,strcmp(txn.host) eq 0
Related
Based on https://github.com/istio/istio/issues/23757 it's been quite some time now that I get no answer about it, so I realized that most likely I don't understand the internals and I need to shift the question in another diretion.
I have a case where vulnerability scan shows that we are vulnerable to custom origin domains. The expectation from the provider is to block request that don't match a predefined ORIGIN within a virtual service allowOrigin setting.
I am trying to send OPTIONS preflights or simple gets, but no matter what I do the mesh always returns 200:
curl -s -H "Origin: http://fake" --verbose http://192.168.223.10:31380/productpage | grep -i "HTTP/1.1 200 OK"
curl -s -H "Origin: http://testit.com" --verbose http://192.168.223.10:31380/productpage | grep -i "HTTP/1.1 200 OK"
curl -s -X OPTIONS -H "Origin: http://testit.com" --verbose http://192.168.223.10:31380/productpage | grep -i "HTTP/1.1 200 OK"
curl -s -X OPTIONS -H "Origin: http://fake" --verbose http://192.168.223.10:31380/productpage | grep -i "HTTP/1.1 200 OK"
Is this something that controls only client blocking (browser) and if so how am I supposed to test it with curl?
I know how to reject a origin like, but it will just return not found then:
- uri:
exact: /productpage
headers:
origin:
regex: "*test.com"
There is an answer to this issue on github:
Hi everyone. Testing CORS using curl can be a bit misleading. CORS is not enforced at the server side; it will not return a 4xx error for example. Instead, headers are returned back which are used by browsers to deny/accept. https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/cors.html?highlight=cors gives a good demo of this, and https://www.sohamkamani.com/blog/2016/12/21/web-security-cors/#:~:text=CORS%20isn't%20actually%20enforced,header%20in%20all%20its%20responses. is a good explanation.
So Istio's job here is simply to return these headers. I have added a test showing this works: https://github.com/istio/istio/pull/26231
I am trying to add a document to confluence page.
I am using this code :
E:\APP\"curl-7.53.1"\src\curl.exe -v -S -u user:password -X POST -H "X-Atlassian-Token: no-check" -F "file=#C:\Users\srvc_mdw_dev\Desktop\conf.txt" -F "comment=this is my file" "http://example.net/rest/api/content/36375143/child/attachment"
But i get the following error :
PS E:\PowerShell\script> ./conf
Note: Unnecessary use of -X or --request, POST is already inferred.
* timeout on name lookup is not supported
* Trying IPaddress...
* TCP_NODELAY set
* Connected to example.net (ip address) port 80 (#0)
* Server auth using Basic with user 'user'
> POST /rest/api/content/36375143/child/attachment HTTP/1.1
> Host: example.com
> Authorization: Basic c291aGFpbC5vdWFiaUBtZXRyb2V4dGVybmFsLmZyOm1ldHJvNDU2Kg==
> User-Agent: curl/7.53.1
> Accept: */*
> X-Atlassian-Token: no-check
> Content-Length: 333
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=------------------------646f724e33da0066
>
* HTTP 1.0, assume close after body
< HTTP/1.0 302 Found
< Location: https://example.net/rest/api/content/36375143/child/attachment
< Server: BigIP
* HTTP/1.0 connection set to keep alive!
< Connection: Keep-Alive
< Content-Length: 0
* HTTP error before end of send, stop sending
<
* Closing connection 0
Do Someone knows why I have this error ? thank you
Please review the following curl command the confluence rest api documentation.
curl -u admin:admin -X POST -H 'Content-Type: application/json' -d'{"type":"page","title":"new page",
"space":{"key":"TST"},"body":{"storage":{"value":"<p>This is a new page</p>","representation":
"storage"}}}' http://localhost:8080/confluence/rest/api/content/ | python -mjson.tool
https://developer.atlassian.com/server/confluence/confluence-rest-api-examples/
After apache rebuilt my cron jobs stopped working.
I used the following command:
wget -O - -q -t 1 http://example.com/cgi-bin/loki/autobonus.pl
Now my DC support suggests me to change the wget method to curl. What would be the correct value in this case?
-O - is equivalent to curl's default behavior, so that's easy.
-q is curl's -s (or --silent)
--retry N will substitute for wget's -t N
All in all:
curl -s --retry 1 http://example.com/cgi-bin/loki/autobonus.pl
try run change with the full path of wget
/usr/bin/wget -O - -q -t 1 http://example.com/cgi-bin/loki/autobonus.pl
you can find the full path with:
which wget
and more, check if you can reach the destination domain with ping or other methods:
ping example.com
Update:
based on the comments, seems to be caused by the line in /etc/hosts:
127.0.0.1 example.com #change example.com to the real domain
It seems that you have restricted options in terms that on the server where the cron should run you have the domain pinned to 127.0.0.1 but the virtual host configuration does not work with that.
What you can do is to let wget connect by IP but send the Host header so that the virtual host matching would work:
wget -O - -q -t 1 --header 'Host: example.com' http://xx.xx.35.162/cgi-bin/loki/autobonus.pl
Update
Also probably you don't need to run this over the web server, so why not just run:
perl /path/to/your/script/autobonus.pl
My domain is pointing to a Beanstalk app (DNS ALIAS).
I have already set up SSL certificates properly on my Beanstalk instance.
So now:
http://www.mysite.com -> Beanstalk app with http
https://www.mysite.com -> Beanstalk app with https
I would like to redirect all http requests to https. So http://www.mysite.com -> https://www.mysite.com
I already tried to create an AWS container to implement something like "server { listen 80; return 301 https://www.mysite.com/$request_uri;}" but it is not working.
I have already spent several hours on Google trying to find some guidance on how to do that. I found some clues such as the 301 redirect, rewrite... but I am not being able to apply any solution to my Beanstalk EC2 instance.
Perhaps I need a more detailed explanation on how to do that.
Could someone help me, please?
PS: one thing that I am struggling to understand is the fact that the Load Balancer says that Load Balancer Port 80 is pointing to Instance Port 80 and Load Balancer Port 443 (HTTPS) is also pointing to Instance Port 80, but with Cipher/SSL cert.
Well, when I examine the nginx configuration files on my EC2 instance I only find a "server { listen 8080", not "listen 80".
Thank you all.
I've online this solution.
Add .ebextensions/00_nginx_https_rw.config
files:
"/tmp/45_nginx_https_rw.sh":
owner: root
group: root
mode: "000644"
content: |
#! /bin/bash
CONFIGURED=`grep -c "return 301 https" /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf`
if [ $CONFIGURED = 0 ]
then
sed -i '/listen 8080;/a \ if ($http_x_forwarded_proto = "http") { return 301 https://$host$request_uri; } \n' /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf
logger -t nginx_rw "https rewrite rules added"
exit 0
else
logger -t nginx_rw "https rewrite rules already set"
exit 0
fi
container_commands:
00_appdeploy_rewrite_hook:
command: cp -v /tmp/45_nginx_https_rw.sh /opt/elasticbeanstalk/hooks/appdeploy/enact
01_configdeploy_rewrite_hook:
command: cp -v /tmp/45_nginx_https_rw.sh /opt/elasticbeanstalk/hooks/configdeploy/enact
02_rewrite_hook_perms:
command: chmod 755 /opt/elasticbeanstalk/hooks/appdeploy/enact/45_nginx_https_rw.sh /opt/elasticbeanstalk/hooks/configdeploy/enact/45_nginx_https_rw.sh
03_rewrite_hook_ownership:
command: chown root:users /opt/elasticbeanstalk/hooks/appdeploy/enact/45_nginx_https_rw.sh /opt/elasticbeanstalk/hooks/configdeploy/enact/45_nginx_https_rw.sh
Based on the code above, this is the code that I used to redirect the http requests to https for a standalone (i.e. not behind a load balancer) Docker image:
files:
"/tmp/000_nginx_https_redirect.sh":
owner: root
group: root
mode: "000644"
content: |
#!/bin/bash
sed -i 's/80;/80;\n return 301 https:\/\/$http_host$request_uri;\n/' /etc/nginx/sites-available/elasticbeanstalk-nginx-docker-proxy.conf
container_commands:
00_appdeploy_rewrite_hook:
command: cp -v /tmp/000_nginx_https_redirect.sh /opt/elasticbeanstalk/hooks/appdeploy/enact
01_configdeploy_rewrite_hook:
command: cp -v /tmp/000_nginx_https_redirect.sh /opt/elasticbeanstalk/hooks/configdeploy/enact
02_rewrite_hook_perms:
command: chmod 755 /opt/elasticbeanstalk/hooks/appdeploy/enact/000_nginx_https_redirect.sh /opt/elasticbeanstalk/hooks/configdeploy/enact/000_nginx_https_redirect.sh
03_rewrite_hook_ownership:
command: chown root:users /opt/elasticbeanstalk/hooks/appdeploy/enact/000_nginx_https_redirect.sh /opt/elasticbeanstalk/hooks/configdeploy/enact/000_nginx_https_redirect.sh
For those, who don't use the Load Balancer, the if block from user3888643's answer wouldn't work. So I've removed it completely (not sure if this solution has any problems) and it works for me:
sed -i '/listen 8080;/a \ if ($http_x_forwarded_proto = "http") { return 301 https://$host$request_uri; }\n' /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf
to:
sed -i '/listen 8080;/a \ return 301 https://$host$request_uri;\n' /etc/nginx/conf.d/00_elastic_beanstalk_proxy.conf
I wasn't sure if user3888643's answer was still the correct one, since aws updated the way some of their own setup scripts run on elastic beanstalk earlier this year, but I just checked with aws support, this is still the advised solution. Add a file to .ebextensions, e.g .ebextensions/00_nginx_https_rw.config with the following contents
files:
"/tmp/45_nginx_https_rw.sh":
owner: root
group: root
mode: "000644"
content: |
#!/usr/bin/env bash
CONFIGURED=`grep -c "return 301 https" /opt/elasticbeanstalk/support/conf/webapp.conf`
if [ $CONFIGURED = 0 ]
then
sed -i '/ location \/ {/a \ if ($http_x_forwarded_proto = "http") { \n return 301 https://$host$request_uri;\n }' /opt/elasticbeanstalk/support/conf/webapp.conf
logger -t nginx_rw "https rewrite rules added"
exit 0
else
logger -t nginx_rw "https rewrite rules already set"
exit 0
fi
container_commands:
00_appdeploy_rewrite_hook:
command: cp -v /tmp/45_nginx_https_rw.sh /opt/elasticbeanstalk/hooks/appdeploy/enact
01_configdeploy_rewrite_hook:
command: cp -v /tmp/45_nginx_https_rw.sh /opt/elasticbeanstalk/hooks/configdeploy/enact
02_rewrite_hook_perms:
command: chmod 755 /opt/elasticbeanstalk/hooks/appdeploy/enact/45_nginx_https_rw.sh /opt/elasticbeanstalk/hooks/configdeploy/enact/45_nginx_https_rw.sh
03_rewrite_hook_ownership:
command: chown root:users /opt/elasticbeanstalk/hooks/appdeploy/enact/45_nginx_https_rw.sh /opt/elasticbeanstalk/hooks/configdeploy/enact/45_nginx_https_rw.sh
04_reload_nginx:
command: /etc/init.d/nginx reload
One thing to look out for: I found I couldn't deploy this because of an interaction between a previous (incorrect) version of the file in .ebextensions, there would be an error and the deployment would fail, even though the file was no longer in the repo being deployed. :
[Instance: i-0c767ece] Command failed on instance.
Return code: 6
Output: nginx: [warn] duplicate MIME type "text/html" in /etc/nginx/nginx.conf:38 nginx:
[emerg] unknown directive "...." in /etc/nginx/conf.d/000_config.conf:4
nginx: configuration file /etc/nginx/nginx.conf test failed.
container_command 04_reload_nginx in .ebextensions/ssl_redirect.config failed.
For more detail, check /var/log/eb-activity.log using console or EB CLI.
It looks like each instance still had a copy of the previously deployed file in /etc/nginx/conf.d/, so I had to go into each instance and delete my previous config files in /etc/nginx/conf.d , once I did that the deployment went through fine.
There's plenty of info on how to prevent curl from showing header information when doing a request for the PHP version, but seemingly nothing for the CLI version.
my request is in the form
curl -i -X POST -H 'Content-Type: application/json; charset=UTF-8' -H 'X-Accept: application/json' -H '-d '{"somedata":"12ihiuhihihed994f63dbef6b012b"}' https://myurl.com/v3/oauth/request
Which works, but returns this:
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/json
Date: Wed, 27 Mar 2013 20:42:11 GMT
P3P: policyref="/w3c/p3p.xml", CP="ALL CURa ADMa DEVa OUR IND UNI COM NAV INT STA PRE"
Server: Apache/2.2.23 (Amazon)
Status: 200 OK
X-Powered-By: PHP/5.3.20
Content-Length: 54
Connection: keep-alive
{"code":"jkhjhhjhaa","state":null}
when all I really want is this:
{"code":"jkhjhhjhaa","state":null}
Simply remove the -i switch from your curl command.
man curl
said :
-i, --include
(HTTP) Include the HTTP-header in the output. The HTTP-header includes things like server-name, date of the document, HTTP-version and more...
In order to suppress output from CURL CLI --silent option can be used. It perfectly works when curl output is piped as well.
-s, --silent Silent mode (don't output anything)
In case this isn't obvious, also don't use the -v (verbose) switch with -s (silent)