简体   繁体   中英

AWS Network Load Balancer not forwarding connection to EC2 instances

I am trying to establish a connection between a local client program and a server program running on an AWS EC2 instance. When I'm directly connecting through the public IP address of the EC2 instance, I face no problem and the connection is established as expected (I am printing out the IP address of the connected server to check whether the connection proceeds correctly or not)

However, when I add the EC2 instance to a Network Load Balancer and pass the NLB's IP while running the client program, then the connection that is being established is between the client program and the Load Balancer, and not the server program (as suggested by the IP address printed). I was expecting that the Load Balancer would forward the connection to the server and the connection would be established, but apparently, it's not the case

Why is it so? And how to solve this and get the desired result (ie the connection to be between the client and server program as it was happening without the load balancer)

EDIT: This does not seem to be a problem with load balancer configuration or permissions, as it works well when I run a simple Web Application on an Apache server on the EC2 instances (instead of the C server program). I guess the client and server programs are not establishing the connection in the desired manner. What needs to be done?

This is my client program

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "openssl/ssl.h"
#include "openssl/err.h"

int OpenConnection(const char *hostname, int port) {
    int sd;
    struct hostent *host;
    struct sockaddr_in addr;
    if ( (host = gethostbyname(hostname)) == NULL )
    {
        printf("Could not find host\n");
        perror(hostname);
        abort();
    }
    else {
      printf("Succesfully found host - %s\n", host->h_name);
    }

    sd = socket(PF_INET, SOCK_STREAM, 0);
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = *(long*)(host->h_addr);
    if ( connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 )
    {
        printf("Connection Failed\n");
        close(sd);
        perror(hostname);
        abort();
    }
    else {
      char* address = inet_ntoa(addr.sin_addr);
      printf("Connection Succesful at socket %d\n", sd);
      printf("%s\n", address);
      printf("Port is: %d\n", ntohs(addr.sin_port));
    }
    return sd;
}

int main(int args, char* argv[]) {
  char* hostname = argv[1];
  char* port = argv[2];
  int portnum = atoi(port);

  int server;
  server = OpenConnection(hostname, portnum);

  close(server);
  return 0;
}

And this is my server program

#include <errno.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <resolv.h>
#include "openssl/ssl.h"
#include "openssl/err.h"

#define FAIL    -1

int OpenListener(int port) {
    int sd;
    struct sockaddr_in addr;
    sd = socket(PF_INET, SOCK_STREAM, 0);
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = INADDR_ANY;
    if (bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0 ) {
        perror("can't bind port");
        printf("Cannot bind port\n");
        abort();
    }
    else  printf("Port bind Succesful\n");


    if (listen(sd, 10) != 0 ) {
        perror("Can't configure listening port");
        abort();
    }
    else printf("Configured listening port\n");

    return sd;
}


int isRoot() {
    if (getuid() != 0) return 0;
    else return 1;
}

int main(int args, char *argv[]) {
    SSL_CTX *ctx;
    int server;
    char *portnum;

    if(!isRoot()) {
        printf("This program must be run as root/sudo user!!");
        exit(0);
    }

    if (args != 2 ) {
        printf("Usage: %s <portnum>\n", argv[0]);
        exit(0);
    }

    portnum = argv[1];

    int port = atoi(portnum);
    server = OpenListener(port);

    while(1) {
      struct sockaddr_in addr;
      socklen_t len = sizeof(addr);
      int client = accept(server, (struct sockaddr*)&addr, &len);
      printf("Connection: %s:%d\n",inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
    }

    close(server);
    return 0;
}

It's hard to understand what's going on, I'll try to suggest that you need to use Application Load Balancer, because:

Network Load Balancer — this is the distribution of traffic based on network variables, such as IP address and destination ports. It is layer 4 (TCP) and below and is not designed to take into consideration anything at the application layer such as content type, cookie data, custom headers, user location, or the application behavior.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM