I have a scenario where i need to execute AWS CLI commands via 2 proxies against the AWS cloudwatch.
Server A(AWS CLI) -----> Server B (Apache proxy Web server) -----> Corporate Proxy IP (X.X.X.X) -----> Internet
My Challenge here is that the AWS CLI commands do not have a context (/something) based on which a rewrite rule (to be written on Server B) can be applied to forward the request from Server A to Corporate Proxy IP and finally to internet (AWS).
Connectivity from Corporate Proxy IP is already there to Internet.
My main motive is to fetch cloudwatch metrics on Server A via the 2 proxies. According to me this is not achievable but need inputs if this can be achieved and if YES, what Rewrite rule
should be written on Server B to proxy the AWS CLI commands to Corporate Proxy.
AWS CLI commands Eg. would be as below:
aws cloudwatch get-metric-statistics --namespace AWS/EC2 --metric-name CPUUtilization --dimensions Name=InstanceId,Value=i-xxx --statistics Average --start-time date -u '+%FT%TZ' -d '10 mins ago' --end-time date -u '+%FT%TZ' --period 60
I'm aware that we can use HTTP_PROXY to forward requests via proxy, however that would only forward my request from Server A to Server B (Apache proxy Web Server).
Thanks in advance & appreciate a quick response.
Ok, so I actually recently built out a reverse proxy server (nginx) specifically to forward AWS CLI requests to help with corporate firewalls. Unfortunately, I cannot publish the code used to make that work, but can give you some insights into the issues with setting up a system like this.
This ones the most obvious. You'll need to have a redirection rule that understands the request being pushed through it and rewrites it to a syntax that the upstream AWS server can understand. In default AWS commands, that context is part of the URL (e.g. https://ec2.us-west-2.amazonaws.com). If you're passing through an upstream reverse proxy, you'll need to pass that context up somehow. You can either have a star DNS record to capture all requests to your proxy the same way amazon does it (e.g. \*.\*.{proxy-address} => {proxy-ip} then aws ec2 --endpoint-url https://ec2.us-west-2.proxy describe-instances) or you can manually inject the information into the path (e.g. aws ec2 --endpoint-url https://proxy/ec2/us-west-2 describe-instances). Then, on your proxy server, you parse out the information and set your upstream based on it. My final solution was to place the full default AWS endpoint url into the path of my proxy https://proxy/ec2.us-west-2.amazonaws.com then have regex upstream to parse out the endpoint URL in case there is information in the path placed by amazon, then set the upstream server to the endpoint URL resolved by the regex.
After you complete #1, you'll now run into the second issue of generated signatures. If you're using the --endpoint-url flag to the CLI, it will sign the request with the Host header set to the proxy server URL. Now, when this is rewritten upstream, that Host header will no longer match the signature. So, you'll need to re-sign any request passing through the proxy. There's a couple sneaky ways around this. What I ended up doing was creating an AWS CLI wrapper which overloaded the signing mechanism to sign the request as if it was sending it to the default AWS endpoint, then overwriting the Host header to point towards my reverse proxy. Re-signing this way is advantageous because it removes proxy latency due to not having to translate the request, but is quite difficult to implement in a way that will dynamically ingest any new signature methods AWS may release.
It is also worth noting that if you dig deep enough into the botocore source code, you'll find some reverse proxy support that is build in, but appears to be defunct/not used (it is not exposed to the client). Hopefully, they flush out that functionality in the near future and this will no longer be an issue.
Related
I'm trying to implement a reverse proxy in our system, for a micro-services architecture.
The proxy server is HAProxy that works with SSL Termination and needs to proxy requests to a backend server with Https and Kerberos authentication.
I succeeded to terminate the ssl on the proxy server and pass the request to the https server (I need the termination in order to route requests by their body, to specific backend services) , but failing to authenticate with kerberos on the backend server.
Is it possible to implement Kerberos auth on the proxy server and then pass the TGT to the different backend services?
I have successfully done this and it took some work.
At the time I was using HDP so I used ambari to setup a hive server on the HAproxy node. (This was done solely for the purpose of having Ambari manage the kerberos principle. The hive server itself never ran)
Then I merged the keytab for my hive server (on the proxy) with my Hive server keytabs so that the principle could be used on the hive servers. I think I also allowed it as a principle to work with hive. I'm sure there is another path that would allow you to use delegation but this was the past of least resistance and made it so hive managed mostly managed the keytab. I did have to re-merge the keytab when they where regenerated but it wasn't as bad as manually managing keytabs.
I have an AWS EC2 server that hosts 3 domains with Apache 2. This server sits behind an AWS ELB load balancer which sends it requests. If I want to update this server, instead of taking the server down, I can create a new identical EC2 server and install all the software using the same scripts that built the first server and when it is ready I can add the new server to the ELB and then remove the old server. This gives me zero downtime which is great.
But before I remove the old server how do test the new server to prove everything is working and it is serving those 3 domains? DNS points to the ELB for these domains, the ELB sendsthe requests to the server, and the Apache install on the server routes the traffic to the appropriate site depending on what subdomain was requested. Is there a way make a request to the new server via IP address since that is the only way to address it before it is behind the ELB but tell it I want to make a request to a specific subdomain? If not how else can I prove all 3 sites are running and working properly without just adding it to the ELB, removing the old server, and crossing my fingers?
P.S. Sorry for the poor title. Please edit it if you can think of a better one that better represents what I am asking.
Use ELB healthcheck to perform the check. I recommend you to enable Apache server status mod. Use health check against /server-status and if it returns 200 for certain period of time, ELB will mark the instance as active and healthy.
I think it's pretty common to use nginx to proxy connections to ExpressJS, so all is done through ExpressJS.
I was thinking, why not use nginx to server the application since it's more simple to setup things like rewrites and let ExpressJS as backend only and then the application communicate to ExpressJS directly on 3000 port.
Is it a bad idea? If not, how often people does this ?
It's very common. But having your front end code directly talk to the node server adds complexity.
You have to handle CORS issues on the node server, including preventing cross site form submissions. See here Properly Understanding CORS with Same Host / Different Port & Security.
SSL is also going to be a bit more complicated. You'll need a wild card certificate.
However, there are some big advantages to using something like ngnix to host your assets. In addition to the ones you enumerated, it sets you up to go serverless. You can host your app out of an S3 bucket our through another content delivery network.
The site works perfectly fine on HTTP, however, does not work on HTTPS.
I've followed all the steps on this page to create a self-signed certificate and add it to my Elastic Beanstalk environment.
http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https.html
I'm also getting a successful certificate response back from IAM using the following command:
aws iam get-server-certificate --server-certificate-name
After updating Elastic Beanstalk with the certificate, I've also added add a rule to the security group that allows inbound traffic from 0.0.0.0/0 to port 443.
Finally, I've also validated that my load-balancer listener has HTTPS set up correctly.
In spite of all that, my calls to https is not resolving, while http is working perfectly fine.
Any other thoughts on this? Any help would be much appreciated.
Please let me know if you need any more information. Desperately looking for some insight/help into this.
Anyway, not being able to resolve this issue with my site/code, I tried to set up HTTPS on the sample site provided on Elastic Beanstalk. Interestingly enough, even that is not working.
I want to provide an update that I was finally able to resolve the issue.
The root-cause was because I missed to set up an Inbound Rule for the Security Group of the Load Balancer.
For whatever reason, when I read the documentation, I understood that the Inbound Rule needed to be set up for the Security Group of the Instance (and not the Load Balancer). Only after I started tracing the Load Balancer did I realize that I should perhaps try setting up the Rule for the Security Group of the Load Balancer. So, the problem is resolved. Below is the setting I used.
HTTPS 443 HTTP 80 <name of the certificate>
I'd have to say that the documentation could be a bit more clear to clearly identify the change required to the Security Group of the Load Balancer (and not the Instance).
Amazon recently released AWS Certificate Manager :
Go to https://console.aws.amazon.com/acm/home
Add your domain and validate it by email
After the certificate is issued, deploy it to your Elastic Load Balancers following the steps (and easily setup your security groups)
It's event better for a performance point of view:
Because ELB supports SSL offload, deploying a certificate to a load
balancer (rather than to the EC2 instances behind it) will reduce the
amount of encryption and decryption work that the instances need to
handle.
follow the doc for more information:
https://aws.amazon.com/fr/blogs/aws/new-aws-certificate-manager-deploy-ssltls-based-apps-on-aws/
I can't believe this...but it goes to show how bad the AWS console is...I had to scroll down and click "Apply" on an invisible button when it shows "Pending create" after add making me think it's working...facepalm.
Hello i was had like this and i follow this steps and works to me:
Generate certificate
the first thing is request a Request certificate on AWS Certificate Manager (ACM)
take a look on this video to create a new one https://youtu.be/bWPTq8z1vFY
Configurations of the Elastic Beanstalk
on the configuration -> load balancer
create a new listener:
in this step i get this :
Creat a new record on route 53
so i use route53 to host my site
go to route 53 ->select your host zone and create a new record
choose the option of alias to select your route traffic in your case Elastic Beanstalk, your region and the name of your application
this works if you use route 53 and EB but in other host providers i thing i woiuld work too.
It seems that nginx buffers requests before passing it to the updstream server,while it is OK for most cases for me it is very bad :)
My case is like this:
I have nginx as a frontend server to proxy 3 different servers:
apache with a typical php app
shaveet(a open source comet server) built by me with python and gevent
a file upload server built again with gevent that proxies the uploads to rackspace cloudfiles
while accepting the upload from the client.
#3 is the problem, right now what I have is that nginx buffers all the request and then sends that to the file upload server which in turn sends it to cloudfiles instead of sending each chunk as it gets it (those making the upload faster as i can push 6-7MB/s to cloudfiles).
The reason I use nginx is to have 3 different domains with one IP if I can't do that I will have to move the fileupload server to another machine.
As soon as this [1] feature is implemented, Nginx is able to act as reverse proxy without buffering for uploads (bug client requests).
It should land in 1.7 which is the current mainline.
[1] http://trac.nginx.org/nginx/ticket/251
Update
This feature is available since 1.7.11 via the flag
proxy_request_buffering on | off;
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_request_buffering
According to Gunicorn, they suggest you use nginx to actually buffer clients and prevent slowloris attacks. So this buffering is likely a good thing. However, I do see an option further down on that link I provided where it talks about removing the proxy buffer, it's not clear if this is within nginx or not, but it looks as though it is. Of course this is under the assumption you have Gunicorn running, which you do not. Perhaps it's still useful to you.
EDIT: I did some research and that buffer disable in nginx is for outbound, long-polling data. Nginx states on their wiki site that inbound requests have to be buffered before being sent upstream.
"Note that when using the HTTP Proxy Module (or even when using FastCGI), the entire client request will be buffered in nginx before being passed on to the backend proxied servers. As a result, upload progress meters will not function correctly if they work by measuring the data received by the backend servers."
Now available in nginx since version nginx-1.7.11.
See documentation
http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_request_buffering
To disable buffering the upload specify
proxy_request_buffering off;
I'd look into haproxy to fulfill this need.