EC2 instance refusing connection to localhost from itself - amazon-web-services

I'm trying to get a Flask app to run on an EC2 instance. I have a few JS functions that send requests to the localhost in the backend to retrieve data from an API.
For instance:
if(topicQueryString != null && topicQueryString != ''){
$.ajax({
url: 'http://0.0.0.0:5000/search/t/'+topicQueryString,
type: 'GET',
dataType: 'json',
success: function(data) { //do something }
})
}
However, when deploying the app on my EC2 instance, these requests fail with ERR_CONNECTION_REFUSED on localhost:5000/search/t/topics
Is there a way to allow the EC2 instance to make requests to itself in this way?

You're trying to connect to 0.0.0.0, not localhost. The address 0.0.0.0 doesn't mean localhost. You should replace that with localhost or 127.0.0.1 (which is what localhost means, most of the time).
EDIT: actually, I'm not even sure that I understood the problem correctly. Is that JS code running in a browser? You want that code to connect to a back-end service, presumably not running on localhost? If so, you should use the address of the back-end service, rather than 0.0.0.0 (which doesn't make sense in any context as a destination address to connect to) or localhost.

Related

Socket.IO connects but is not emitting

To prefice this is a MERN socket.io application unfortunately I can't share my source since it's also connected to my aws account.
When on localhost my entire app works perfectly, however when deploying to AWS the back end fails. There are no errors, and when looking at the network it does show up with a successful link to socket.io. I've changed and updated the server for nginx so that it doesn't give off a bad gateway error. However after doing this there is no other error, I just can't register or login, client side validation seems to work however back end validation does not. If you'd like to take a look it's currently on http://3.145.119.85/
I currently connect to socket.io like so
const [socket] = useState(() => io(":8000"));
My server side instantiating
> const express = require("express");
const app = express();
const cors = require("cors");
const fileUpload = require("express-fileupload");
const PORT = process.env.PORT || 8000;
require("./components/mongoose.config");
app.use(cors());
app.use(fileUpload());
app.use(express.json(), express.urlencoded({extended:true}));
const server = app.listen(PORT, () => console.log("listening at port " + PORT));
require("./components/puzzleio.sockets") (server);
Any help would be much appreciated
Ensure that you have changed the host address from localhost to the real aws address. It seemed natural that socket.io should connect to the root from where you serve your content.
Since you are using AWS and after each restart you get different DNS address you have sent to the page where you are initializing the socket.io then correct the req.headers.host (using express-expose).

Cannot reach the localhost of the server when using ssh port forwarding

I am using Flask and Vue to develop a single page app. So far I have been developing and running both Flask and Vue locally on my laptop. I have now moved both to a server and want to run them there long term. For now, I have kept the original "localhost:5000" setting. Both Flask and Vue work and the axios-requests from Vue arrive at the Flask app. However, to make the latter work not only on the server environment but also from my client laptop, I used ssh port forwarding. The actual problem now is: My website is displayed to me in my local browser and i can click-around, but the axios-requests don't work. This is because the requests are trying to reach the localhost of my laptop, but not the server's localhost (when I start my local Flask app, the requests work). I'm sure I'm just missing something important here - I don't have much experience with client-server architectures.
One of my Requests in Vue.js:
methods: {
getProjects() {
const path = 'http://localhost:5000/projects';
axios.get(path)
.then((res) => {
this.projects = res.data;
this.rows = this.projects.length;
this.setColumns();
})
.catch((error) => {
console.error(error);
});
},
...
The Flask app (server-side) is running on:
http://0.0.0.0:5000/
My ssh port forwarding:
ssh -o GatewayPorts=true -L 8081:0.0.0.0:8080 me_the_user#the_server
Any suggestions welcomed.
Ok, I got it working now. The problem was simply that I only forwarded the frontend/Vue port (8080:0.0.0.0:8080), but not the backend/Flask port (5000:0.0.0.0:5000).

AWS Load Balancer appends :80 to url on http to https 301 redirect

When I go to my example application: https://example.com/r/123 it works as expected.
If I go to http://example.com/r/123 it seems the load balancer changes the url to https://example.com:80/r/123.
This page results in a ERR_SSL_PROTOCOL_ERROR.
Is it possible to make AWS not add the port(:80) in the redirect?
My problem was solved by changing the server IP to 0.0.0.0 instead of the default value of localhost in the nuxt server config.
// nuxt.config.js
server: {
host: '0.0.0.0',
},

auth0+passport.js too many redirects with more than 1 instance

Infrastructure:
cloud:
aws beanstalk
turn on nginx for container proxy server
application load balancer - https only, default process (https)
2+ instance in private subnet
enabled end to end encryption following
https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-endtoend.html
https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/https-singleinstance-docker.html
self-signed certificate on instance
instance running docker
In local, we have a 3 container to mimic the infrastructure,
1 nginx: 443 as load balancer and https reverse proxy
2 app container: 3000:3000, 3001:3001 respectively
so, not end to end encryption yet
software:
autho
passport
(https://github.com/auth0/passport-auth0)
express
react
cookie-session package
const sessionConfig = {
name: 'sessionId',
secret: uid.sync(18),
secure: true,
httpOnly: true,
secureProxy: true,
maxAge: 1800 * 1000
};
workflow:
open website, click login link, it then redirect us to auth0 login page, after input username/passport, we click submit.
We are encountering "redirect too many times" when we have more than 1 instance running. The issue goes away if I turn on sticky session on the target group in aws.
We are seeing the same when trying on the local docker environment.
In this code,
router.get('/callback', (req, res, next) => {
authenticate('auth0', (authErr, user) => {
if (authErr) {
console.error(`Error authenticating user: ${authErr}`);
return next(authErr);
}
if (!user) {
console.info(`No user data, redirecting to login page`);
return res.redirect('/login');
}
The logic always hits - if (!user), and we are not sure why this happens with multiple instance, load balancer setup.
Update:
Sorry I am new to this,
I am wondering if I can use cookie-session instead of express-session since JWT is supposed to not storing information in server.
I am asking because I have read a few tutorial of passport and Auth0, and it also mentioned about expression-session only.
Since Auth0 is using JWT, could I use cookie-session? if so, what could I do wrong?
PS.
Here is my session config:
const sessionConfig = {
name: 'sessionId',
domain: 'example.com',
secret: uid.sync(18),
secure: true,
httpOnly: true,
maxAge: 1800 * 1000
};
Please advise and help.
Thank you!
Jay
The issue is resolved.
It is because secret is random so a fixed secret was not shared between servers.

Frontend code directly access http instead of https and cause mix content error

As an academic project, we host our web application with Amazon S3 (For Angular) and Apache Server (For Django). We have made both sites https (for both frontend and backend). We can access the backend successfully on our localhost using ng serve. However, for the production site, it always gives us a mixed content error (try to connect HTTP for our backend). But we actually put https in our angular code. Are there any suggestions on that?
Attached is our frontend code
export class AuthenticationService {
private ip: string = 'https://sunrise.99jhs.com';
authenticate(username: string, password: string) {
const headers = new HttpHeaders();
headers.append('Access-Control-Allow-Origin', '*');
return this.http.post<any>(this.ip + '/api-token-auth/', {username, password}, {headers});
}
Attached is error message
Mixed Content: The page at 'https://sunrise.4jhs.com/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://sunrise.99jhs.com/api-token-auth'. This request has been blocked; the content must be served over HTTPS.
We build the angular code using
ng build --prod
Try not to specificity the protocol at all
private ip: string = '//sunrise.99jhs.com';
The problem is not with the private IP value. It specifies the https protocol.
The problem is with this code:
return this.http.post(this.ip + '/api-token-auth/', {
The URL resulting from that code is the problem. If you notice, this is the URL being referenced in the error message.
Add an https specifier there. That should resolve the issue.