AWS ALB sticky cookie issue - amazon-web-services

recently we had switched from aws elb to aws alb; but we are facing issue in aws alb; cookie stickiness is not working at all; for each request (event ajax request on the page) generates a new cookie;
if we switch back to aws elb again cookie stickiness working perfectly fine.

AWSALB is a cookie generated by the Application load balancer in the AWS. It works slightly different from AWSELB.
The ASWALB cookie is load balancer generated cookie. Once the load balancer routes your request to one of the servers, it generates a new cookie and sends it to the client in the response header. Though AWSALB works fine when you just send the webapp_session for consecutive request, it is better to integrate the AWSALB cookie along with the webapp_session and send it for each request to the server. This way, the load balancer will identify your target server and direct your request to the same target in each request call to the server. This preserves the stickyness of the server.
However, if you send AWSALB along with the webapp_session in the request header for each request to the sever, even if the target that processed your previous requests gets busy for future requests, the AWSALB generated in each call will help the load balancer identify your credentials and route your request to the new target. I faced similar situation and this helped me solve the problem.
The "STICKY SESSION" topic in this https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html#sticky-sessions will perhaps help you have some idea.

For Application LB you have to set up session stickiness in target group not directly in LB like in Classic LB. Session stickiness doesn't work when your browser blocks AWSALBCORS, AWSALB - this seems to be obvious, but Internet Explorer can block these cookies and doesn't show any warning/info in console.

Related

Allow Stripe webhook to access AWS EC2 instance

I do have a Stripe webhook which is successfully caught and processd in Stripe's TEST MODE, on http local host server.
However, when switching to Stripe's LIVE MODE DATA, the webhook returns status code 500, while the EC2 instance is untouched, no logs being generated.
There is no issue with Signing secrets or Stripe keys, the event never reaches the HTTPS endpoint of the EC2 created using a Load Balancer.
Stripe's support cannot pronounce to this so any suggestions of why this could happen or how to handle it is very welcome.
The error displayed on Stripe is:
HTTP status code 500 (Internal Server Error)
Response Failed to connect to remote host
I have added a whitelist middleware to the express server running on EC2:
app.use((req, res, next) => {
console.log('Always inside ', req.originalUrl);
next();
});
before handling the stripe webhook URL
app.use('/afterpayment', bodyParser.raw({ type: 'application/json' }), afterPaymentRoutes);
in order to see if Stripe event reaches the server, which is not happening.
However, if i manually enter into browser the Stripe Webhook URL, domain/afterpayment, the result is as expected: whitelist middleware prints the message and webhook handler takes over.
I was having a similar problem, and watching this thread. In my case, the issues were a few different things. I'm forcing https to my site (elb is redirecting any traffic from 80 to 443). The app on my ec2 was accepting connections over port 80. Access to the site was working. I thought maybe stripe sending the webhook data to the elb was breaking because of the redirect. This wasn't the case. However, I had a security group that was only allowing access from my IP address (for testing). Changing this to 0.0.0.0/0 from the internet (actual production access) didn't completely fix the problem but I wanted to get things set up to as close as real-world as possible. In the stripe dashboard I created a new webhook pointing to the app endpoint I exposed for testing. From the Stripe dashboard I hit the "Send a test webhook" button. This time instead of getting a timeout the error was invalid signature. So, I knew that exposing the site to the internet was part of the problem., (Yes, I could have created a security group that only allowed access from the IP addresses where the webhook data originates from, but again - I wanted to keep this as close to production as possible thanks #justin-michael for the nudge in the right direction). My app was still using the test webhook I set up for development. When I created the new webhook it also created a new signing secret. I pulled this new webhook signing secret into my app then ran the "send test webhook" again and it was successful. So, allowing the correct access from Stripe and making sure the signing secret was correct fixed the problem for me.
The problem was that the domain was not properly exposed on the internet.
So I have Elastic Beanstalk environment running a node.js server app on which I set a Load Balancer and exposed the server over HTTPS.
While trying to catch a webhook sent by a 3rd party app, like Stripe, nothing arrived on the server, even though I could successfully simulate POST request to the domain endpoint. The domain was also accessible through browser (or so it seemed).
The issue was that the domain name linked to load balancer was not resolvable publicly on the internet. Here are 2 useful links:
https://www.ssllabs.com/ssltest/index.html
https://dns.google.com/query?name=&rr_type=ALL&ecs=
Running tests on them unveiled problems related to DNSSEC configuration of my domain, which was not enabled on my domain.
While following this instructions i did:
On Hosted Zones, under DNSSEC signing -> Enable DNSSEC signing.
Created KSK and Customer managed CMK
Under DNSSEC signing, copied the information from View information to create DS record
On Route 53, on Registered Domains -> on the domain -> DNSSEC status, created a new key with info from previous step
After this, all tests passed and the webhook was successfully handled.

Passing Cookies from Client to Load Balancer via Cloudflare Proxy

We have a load balancer that distributes traffic to a few servers.
In order to keep session integrity and some other bits we use a policy on the LB. Basically when a user hits the LB they receive a cookie that expires within 2 hours. This cookie tells the load balancer which server the user belongs to to stop them from switching server as they are progressing through the site.
This works fine in normal circumstances.
Now introduce Cloudflare CDN.
For some reason the cookie doesn't make it to the LB and it balances the traffic anyway. I'm assuming that there will be some kind of rule or setting within Cloudflare that will resolve this. Has anyone else came across this at all?
Cookie being used is jnAccel. It's value is a unique identifier as to which server that user belongs to. It's expiry is 2 hours.
As it would turn out the thing blocking Cookies was the HTTP/2 setting on CloudFlare.
You can find this in the network menu, It should be the first setting on the list.
The headers where scrambling and becoming non persistent with HTTTP/2.
If I find a solution to configure to load balancer to still enable HTTP/2 I will update my answer.

Sticky session with application cookie on AWS ELB

I have an application with multiple EC2 instances behind an ELB. Previously, we enabled sticky session on ELB using AWSELB cookie (AWS generated cookie strategy) and it was working smoothly.
Now, due to some requirement, we have to use application cookie to set up sticky session on ELB.
In the request we are sending this application generated cookie but it is not working.
Can anyone please assist me?

Is the most recent AWSALB cookie required? (AWS ELB Application Load Balancer)

Observations
When using an Amazon ELB Application Load Balancer and working with Sticky Sessions the load balancer inserts a cookie named AWSALB in the first request. To let the next request stick to the same target node (EC2 instance) the cookie should be included in that request. When doing so, it seems that the load balancer inserts a different cookie value in the response to the 2nd request. When including this new cookie value on the 3rd request, we get yet a new cookie value in the response. And so forth…
(This is different from how Sticky Sessions works with the Classic Load Balancer where the cookie is named AWSELB and retains its value until discarded by the client or the load balancer.)
The reason the AWSALB cookie changes value all the time seems to be (as stated by the docs):
The name of the cookie is AWSALB. The contents of these cookies are encrypted using a rotating key. You cannot decrypt or modify load balancer-generated cookies.
So even though the contents of the cookie might be the same, we cannot tell.
Question
The question is whether a request to the load balancer must always include the most recently received value of the AWSALB cookie or if it ok to send some previously received value (from the same sticky session, of course).
If this is a requirement the AWS ELB Application Load Balancer would not be able to serve a client that performs multiple parallel requests (after having received the first AWSALB cookie) but only clients that performs all requests in a sequential fashion (one at a time).
Can anybody shed some light on this?
After waiting for a reply here, I raised a support case with Amazon and got this reply:
I understand that you would like to confirm if it is required to provide the latest stickiness cookie for every request.
You are right in noting that the behaviour is different between CLB and ALB.
Due to the different functionality of Application Load Balancer to direct traffic to multiple Target Groups, each having its own stickiness, ALB encrypts the information needed to direct traffic and provides new cookie on each request. This ensures that different times for different groups are always respected correctly.
Clients can always obtain the latest cookie, as internally the information would ensure correct routing to the same target.
If you want to reuse single cookie it is also possible, ALB will respect it and correctly route the traffic as per the stickiness in the cookie. I would not recommend using the same cookie for periods longer than 60 seconds though. This is to ensure that in case of target becoming unavailable you can acquire new cookie with new stickiness information that would route you to new target.
The load balancer must always include the most recently received value of the AWSALB cookie - yes. Some text from the documentation:
The Application Load Balancer resets the expiry of the cookies it generates after every request.
Sticky sessions for your Application Load Balancer

AWS ELB Load Balancer: is it possible to set multiple session cookies?

I am running a tomcat web application on AWS Elastic Beanstalk using load balancing. I have two cookies for each session (1) JSESSIONID (2) XSRF-TOKEN (csrf token*).
I set the JSESSIONID as the application-controlled session stickiness cookie, in Load Balancer Port Configuration. It works perfectly. But I can not set the second session cookie as it is only possible to set ONE sticky cookie in the Load Balancer.
Any idea how I can set multiple cookies for a session in Elastic Beanstalk Load Balancer?
I appreciate your help as Im stuck with this big time!
Migan
*On every request to the backend, backend generates an CSRF-TOKEN and hands it over to the client by setting it as an HTTP response header. The client is required to submit this token on every state changing request in order to prevent cross-site request forgery.
Problem solved!
The reason I could not see my XSRF_TOKEN cookies was that in the test environment I was using http to access my ElasticBeanstalk environment. Once I generate an SSL certificate and accessed my instance using https, my lovely XSRF_TOKEN cookie appeared again!