Unable to access Go server when hosted on AWS - amazon-web-services

I have created a project in Go using gin and it is working fine locally. However, when I tried deploying this on an EC2 instance on AWS, I was unable to access the APIs on the server.
I did a ssh into the hosted machine and gave a curl request (curl localhost:8080) and it gave a proper response. But any request from outside is not reachable.
The server is running on port 8080. I have opened the ports in the AWS security groups.
Is there any setting in Go/gin that I need to make for it to be accessible from the internet?
Sample code:
package main
import (
"myConstants"
"myDatabase"
"myMiddleware"
"onboarding"
"github.com/gin-gonic/gin"
)
func main() {
var db = myDatabase.DBConnect()
router := gin.Default()
router.Use(myMiddleware.RestrictInputContent)
router.Use(myMiddleware.CheckToken(db))
router.Use(myMiddleware.RequestLoggerMiddleware())
router.POST("/signup", onboarding.Signup(db))
router.POST("/login", onboarding.Login(db))
router.POST("/logout", onboarding.Logout(db))
router.GET("/", onboarding.Hello(db))
defer db.Close()
//Listen and serve
router.Run("127.0.0.1:8080")
}

Changed the router.Run from router.Run("127.0.0.1:8080") to router.Run(":8080") and it works.
As suggested by #elithrar and #user3591723
127.0.0.1 (local host) is only the loop back interface on the machine
Binding to ":8080" means 0.0.0.0:8080 - which means all interfaces

Related

Nextjs 404s on buildManifest across multiple EC2 instances

Context: I have a simple Next.js and KeystoneJS app. I've made duplicate deployments on 2 AWS EC2 instances. Each instance also has an Nginx reverse proxy routing port 80 to 3000 (my apps port). The 2 instances are also behind an application load balancer.
Problem: When routing to my default url, my application attempts to fetch the buildManifest for the nextjs application. This, however, 404s most of the time.
My Guess: Because the requests are coming in so close together, my load balancer is routing the second request for the buildManifest to the other instance. Since I did a separate yarn build on that instance, the build ids are different, and therefore it is not fetching the correct build. This request 404s and my site is broken.
My Question: Is there a way to ensure that all requests made from instance A get routed to instance A? Or is there a better way to do my builds on each instance such that their ids are the same? Is this a use case for Docker?
I have had a similar problem with our load balancer and specifying a custom build id seems to have fixed it. Here's the dedicated issue and this is how my next.config.js looks like now:
const execSync = require("child_process").execSync;
const lastCommitCommand = "git rev-parse HEAD";
module.exports = {
async generateBuildId() {
return execSync(lastCommitCommand).toString().trim();
},
};
If you are using a custom build directory in your next.config.js file, then remove it and use the default build directory.
Like:
distDir: "build"
Remove the above line from your next.config.js file.
Credits: https://github.com/serverless-nextjs/serverless-next.js/issues/467#issuecomment-726227243

An Issue with an AWS EC2 instance WebSocket connection failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT

As I tried to run the chat app from localhost connected to MySQL database which had been coded with PHP via WebSocket it was successful.
Also when I tried to run from the PuTTY terminal logged into SSH credentials, it was displaying as Server Started with the port# 8080
ubuntu#ec3-193-123-96:/home/admin/web/ec3-193-123-96.eu-central-1.compute.amazonaws.com/public_html/application/libraries/server$ php websocket_server.php
PHP Fatal error: Uncaught React\Socket\ConnectionException: Could not bind to tcp://0.0.0.0:8080: Address already in use in /home/admin/web/ec3-193-123-96.eu-central-1.compute.amazonaws.com/public_html/application/libraries/vendor/react/socket/src/Server.php:29
Stack trace:
#0 /home/admin/web/ec3-193-123-96.eu-central-1.compute.amazonaws.com/public_html/application/libraries/vendor/cboden/ratchet/src/Ratchet/Server/IoServer.php(70): React\Socket\Server->listen(8080, '0.0.0.0')
#1 /home/admin/web/ec3-193-123-96.eu-central-1.compute.amazonaws.com/public_html/application/libraries/server/websocket_server.php(121): Ratchet\Server\IoServer::factory(Object(Ratchet\Http\HttpServer), 8080)
#2 {main}
thrown in /home/admin/web/ec3-193-123-96.eu-central-1.compute.amazonaws.com/public_html/application/libraries/vendor/react/socket/src/Server.php on line 29
ubuntu#ec3-193-123-96:/home/admin/web/ec3-193-123-96.eu-central-1.compute.amazonaws.com/public_html/application/libraries/server$
So I tried to change the port#8080 to port# 8282, it was successful
ubuntu#ec3-193-123-96:/home/admin/web/ec3-193-123-96.eu-central-1.compute.amazonaws.com/public_html/application/libraries/server$ php websocket_server.php
Keeping the shell script running, open a couple of web browser windows, and open a Javascript console or a page with the following Javascript:
var conn = new WebSocket('ws://0.0.0.0:8282');
conn.onopen = function(e) {
console.log("Connection established!");
};
conn.onmessage = function(e) {
console.log(e.data);
};
From the browser console results:
WebSocket connection to 'ws://5.160.195.94:8282/' failed: Error in
connection establishment: net::ERR_CONNECTION_TIMED_OUT
websocket_server.php
<?php
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use MyApp\Chat;
require dirname(__DIR__) . '/vendor/autoload.php';
$server = IoServer::factory(
new HttpServer(
new WsServer(
new Chat()
)
),
8282
);
$server->run();
I even tried to assign Public IP and Private IP, but with no good it resulted in the same old result?
This was the composer files generated after executing and adding src folder $composer require cboden/ratchet
composer.json(On AmazonWebServer)
{
"autoload": {
"psr-4": {
"MyApp\\": "src"
}
},
"require": {
"cboden/ratchet": "^0.4.1"
}
}
composer.json(On localhost)
{
"autoload": {
"psr-4": {
"MyApp\\": "src"
}
},
"require": {
"cboden/ratchet": "^0.4.3"
}
}
How am I suppose to resolve/overcome while connecting it from the WebSocket especially from the hosted server with the domain name such as
http://ec3-193-123-96.eu-central-1.compute.amazonaws.com/
var conn = new WebSocket('ws://localhost:8282');
From the Security Group
Under Inbound tab
Under Outbound tab
When it comes to a connectivity issue with an EC2 there are few things you need to check to find the root cause.
SSH into the EC2 instance that the application is running and make sure you can access it from within the EC2 instance. If it works then its a network related issue that we need to solve.
If step 1 was successful. You have now identified it is a network issue to solve this you need to check the following.
Check if an Internet Gateway is created and attached to your VPC.
Next check if your subnets routing table has its default route pointing to the internet gateway. check this link to complete this and the above step.
Check your subnets Network ACLs rules to see if ports are not blocked
finally, you would want to check your Instances Security group as you have shown.
If you need access via a EC2 dns you will need to provision your ec2 instance in a public subnet and assign an elastic IP
If an issue still exists check if the EC2 status checks pass, or try provisioning a new instance.

Unable to connect to the AWS RDS database from ASP.NET Hangfire

I am developing an ASP.NET Core Web API project. In my project, I am using Hangfire to run the background task. Therefore, I am configuring the Hangfire to use the database like this.
public void ConfigureServices(IServiceCollection services)
{
services.AddHangfire(configuration =>
{
configuration.UseSqlServerStorage("Server=(LocalDB)\\MSSQLLocalDB;Integrated Security=true;");
});
//
}
In the above code, I am using Local DB. Now, I am trying to use AWS RDS database since I am deploying my application on the AWS Elastic Beanstalks. I created a function for getting the connection
public static string GetRDSConnectionString()
{
string dbname = "ebdb";
if(string.IsNullOrEmpty(dbname)) return null;
string username = "admin";
string password = "password";
string hostname = "cxcxcxcx.xcxcxcxc.eu-west-2.rds.amazonaws.com:1234";
string port = "1234";
return "Data Source=" + hostname + ";Initial Catalog=" + dbname + ";User ID=" + username + ";Password=" + password + ";";
}
I got the above code from the official AWS documentation. In the above code, what I am not clear is the database name, is the database name always be "ebdb"? I tried to find out the database name. But could not. In the tutorial, it is saying to use ebdb. So, I used it.
Then in configuration, I changed to this.
configuration.UseSqlServerStorage(AppConfig.GetRDSConnectionString());
When I run the code, it is giving me this error.
Win32Exception: The parameter is incorrect
Unknown location
SqlException: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 25 - Connection string is not valid)
System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, object providerInfo, bool redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, bool applyTransientFaultHandling)
Win32Exception: The parameter is incorrect
Basically, it cannot connect to the database when I run my application. But I set the correct credentials. the only thing I double is the database name (ebdb). What is wrong with my configuration and what is wrong? How can I fix it?
Calling a few things out here just incase...
You have your port specified both in your host variable and as a separate port variable...but never use port.
Can you confirm that you are able to access your SQLServer via another means, such as from SQL Management Studio?
RDS uses SSL by default now for connections, my .NET is rusty but would you need to inform the connection string that it needs to run over a secure protocol?
& finally, regarding the AWS Security Group on your RDS instance. Have you opened up the correct port to your machine/network/IP?
This is the screenshot of the RDS db instance security group section in the console.

DefaultHandshakeHandler's determineUser not called on Production Server

I have a grails project which uses Spring websockets. I have implemented the DefaultHandshakeHandler to create random principal name for each new session and use convertAndSendToUser to send messages.
Everything works fine in local run. I am also able to deploy the WAR file on an AWS EC2 Linux Instance running latest tomcat. The file deploys fine and the Connect and Disconnect events on websockets can be detected correctly.*
The only problem is, My CustomHandshakeHandler's determineUser does not get called on production. Due to this my StompHeaderAccessor's principal is always null and the code starts spitting NPEs.
This is how i have declared the CustomHandshakeHandler :
class CustomHandshakeHandler extends DefaultHandshakeHandler {
#Override
protected Principal determineUser(ServerHttpRequest request,
WebSocketHandler wsHandler,
Map<String, Object> attributes) {
// Generate principal with UUID as name
return new StompPrincipal(UUID.randomUUID().toString())
}
}
This is how i set the handshake handler configuration :
#Override
void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
stompEndpointRegistry.addEndpoint("/ws-ep") // Set websocket endpoint to connect to
.setHandshakeHandler(new CustomHandshakeHandler()) // Set custom handshake handler
.withSockJS() // Add Sock JS support for frontend
}
I tried deploying the same WAR file on local Tomcat 8 and it again works fine. It seems problem happens due to AWS. I also searched for some other AWS and websocket related issues. I came across some ELB compatibility related things but i Don't think that's my case since my websockets are working fine (Events are being received)
Can someone please help out or point me in right directions
Problem was with Nginx settings which upgrade the Http Request to WS request. This question helped a lot : Spring WebSocket: Handshake failed due to invalid Upgrade header: null

Can't reach wicket quickstart from outside firewall

I have a project which, for purposes of server configuration, is just a wicket quickstart archetype. I've added some application code, but haven't really done anything to change the default jetty configuration.
I can run and test my application locally using:
http://localhost:8080
or:
http://bekkar:8080 (my PC's network name)
or:
http://192.168.1.2:8080/ (my PC's local IP)
I want to access my wicket app from outside my router firewall. (I eventually will test it on my Blackberry, but for now I'm using Google Chrome to try to reach it externally.)
Using http://www.whatismyip.com/ I found my router's IP.
I use:
http://###.###.###.###:8080
and I get a screen that says Authentication Required, asking for a username and password. I don't have any kind of authentication set up in my wicket app.
I have a NetGear router, WGR614v7. Using the router admin, under port forwarding, I add the following custom service:
Service Name=wicket
Starting Port=8080
Ending Port=8080
Server IP Address=192.168.1.2 //my computer's local IP
After adding the port forwarding service definition, I get a different message from Chrome:
Oops! Google Chrome could not connect to ###.###.###.###:8080
How can I make my wicket jetty quickstart accessible from outside my router firewall? I don't know if this is a wicket/jetty issue (belonging on SO) or a firewall issue (belonging on serverfault), so I'll post it here, first.
Thanks!
First, try with just simple apache, or woof. Be sure to bind it to 0.0.0.0 (all IPs).
A) If you can't reach it, it's the router config problem.
B) If that works, you know it't jetty/wicket config.
case A) I don't know that router, but look for port forwarding. I wasn't able to get ASUS WL500gP passing requests in, so I am not the right one to advice here :)
case B) Does Jetty bind to 0.0.0.0? Can you reach it from other machine on the local network?
Not much useful answer, but I hope it helps a bit.
I run jetty/wicket apps on my system all the time and access them remotely. I don't think there is anything special that I've done with Jetty, and especially not wicket to make this work. But if it helps, here is an example Start.java file (this is from one of my apps -- not sure if it is the same as the one in quickstart, as I don't have a quickstart available right now):
public class Start {
public static void main(String[] args) throws Exception {
Server server = new Server();
SocketConnector connector = new SocketConnector();
// Set some timeout options to make debugging easier.
connector.setMaxIdleTime(1000 * 60 * 60);
connector.setSoLingerTime(-1);
connector.setPort(8080);
server.setConnectors(new Connector[] { connector });
WebAppContext bb = new WebAppContext();
bb.setServer(server);
bb.setContextPath("/");
bb.setWar("src/main/webapp");
// START JMX SERVER
// MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
// MBeanContainer mBeanContainer = new MBeanContainer(mBeanServer);
// server.getContainer().addEventListener(mBeanContainer);
// mBeanContainer.start();
server.addHandler(bb);
try {
System.out.println(">>> STARTING EMBEDDED JETTY SERVER, PRESS ANY KEY TO STOP");
server.start();
System.in.read();
System.out.println(">>> STOPPING EMBEDDED JETTY SERVER");
// while (System.in.available() == 0) {
// Thread.sleep(5000);
// }
server.stop();
server.join();
} catch (Exception e) {
e.printStackTrace();
System.exit(100);
}
}
}
I'm using a DLink router, so I'm not sure how to configure yours. However, you should also check your router to see if it has remote web admin turned on, and if it is on port 8080. If so, turn it off, as it might be interfering with your port forwarding.