Using AWS, I want to:
Distribute http request sending over several different IPs
Send this requests without using proxy
Send this using Elastic Load Balancer and AutoScaling Group
Send these requests from one instance to several instances in AutoScaling Group
Each of those several instances assigns different IP to the incoming request so output the request in its IP
How do I do this? Is there anyway to set up load balancer just to send through http request? I want each http request to have different IP address.
So, basically you're willing to connect to EC2 instances behind a ELB and willing to know, on the EC2 instances, the original IP address of the connection, not the ELB's IP address.
If my understanding of your question is correct, then the answer is
Use TCP listener on the ELB, instead of HTTP listeners.
Enable Proxy Protocol on the ELB
on your EC2 instances, collect the original IP address
Full step by step and demo application is available on AWS' blog.
Related
I am trying to setup a loadbalancing lab for HAproxy in single-arm mode (when actual frontend IP and backend servers reside in same subnet, while actual clients are always remote). Another request is to make client source IPs visible to backend nodes. As we load-balance custom tcp-based app, it seems that option 'source 0.0.0.0 usesrc clientip' is a right choice here. Also, I have configured backends to have default-gateways pointing to HAproxy's IP address.
Although strange things happen once I enable this backend option: I see connection to frontend VIP was properly done and 3-way handshake formed. But when HAproxy server is trying to build a 2nd session to reach out to backend servers with spoofed IP of a client, I see exactly this happening:
Proxy is sending SYN with spoofed Client's IP address to one of the backends;
Backend is normally repsonds with SYN-ACK packet;
Proxy is NOT sending last ACK, just blindly sends SYN packets after timeout with same outcome;
On a proxy I see this connection is marked as SYN_SENT in netstat output, so it looks like proxy server doesn't accept actualy SYN-ACK packet for some reason.
Any comment would be appreciated.
The source option makes HAProxy bind to a specific IP address before it relays the request to the server. If you just need to load balance servers over TCP/IP (not HTTP), then you do not need this.
Set mode tcp in your frontend and backend, which enables load balancing of TCP-enabled applications.
To forward the client's IP address to the server, can you modify your custom application to support the Proxy Protocol? https://www.haproxy.com/blog/using-haproxy-with-the-proxy-protocol-to-better-secure-your-database/
Google Cloud Network load balancer is a pass-through load balancer and not a proxy load balancer. ( https://cloud.google.com/compute/docs/load-balancing/network/ ).
I can not find any resources in general on a pass through LB. Both HAProxy and Nginx seems to be proxy LBs. I'm guessing that pass through LB would be redirecting the clients directly to the servers. In what scenarios it would be beneficial?
Are there any other type of load balancers except pass-through and proxy?
It's hard to find resources for pass-through load balancing because everyone came up with a different way of calling it: pass-though, direct server return(DSR), direct routing,...
We'll call it pass-through here.
Let me try to explain the thing:
The IP packets are forwarded unmodified to the VM, there is no address or port translation.
The VM thinks that the load balancer IP is one of its own IPs.
In the specific case of Compute Engine Network Load Balancing https://cloud.google.com/compute/docs/load-balancing/: For Linux this is done by adding a route to this IP in the "local" routing table, Windows by adding a secondary IP on the network interface.
The routing logic has to make sure that packets for a TCP connection or UDP "connection" are always sent to the same VM.
For GCE network LB see here https://cloud.google.com/compute/docs/load-balancing/network/target-pools#sessionaffinity
Regarding other load balancer types there can't be a definitive list, here are a few examples:
NAT. An example with iptables is here https://tipstricks.itmatrix.eu/use-iptables-to-load-balance-web-trafic/.
TCP Proxy. In Google Cloud Platform you can use TCP Proxy Load Balancing https://cloud.google.com/compute/docs/load-balancing/tcp-ssl/tcp-proxy
HTTP Proxy. In Google Cloud Platform you can use HTTP(s) Load Balancing https://cloud.google.com/compute/docs/load-balancing/http/
DNS, called "DNS forwarder". For example: dnsmasq http://www.thekelleys.org.uk/dnsmasq/doc.html, or bind in "forwarding" mode https://www.digitalocean.com/community/tutorials/how-to-configure-bind-as-a-caching-or-forwarding-dns-server-on-ubuntu-14-04
Database communication protocols. For example the MySQL Protocol with https://github.com/mysql/mysql-proxy
SIP protocol. Big list of implementations here https://www.voip-info.org/wiki/view/Open+Source+VOIP+Software#SIPProxies
As for the advantages of pass-through over other methods:
Some applications won't work or need to be adapted if the addresses on the IP packets is changing, for example the SIP protocol. See the Wikipedia for more on applications that don't play along well with NAT https://en.wikipedia.org/wiki/Network_address_translation#NAT_and_TCP/UDP.
Here the advantage pass-through is that it does not change the source and destination IPs.
Note that there is a trick for a load balancer working at a higher layer to keep the IPs: the load balancer spoofs the IP of the client when connecting to the backends. As of this writing no load balancing product uses this method in Compute Engine.
If you need more control over the TCP connection from the client, for example to tune the TCP parameters. This is an advantage of pass-through or NAT over TCP (or higher layer) proxy.
In http the client supplies the hostname it used to connect to the service with. Now, for bare TCP connections, is there something similar one can do? My scenario is I have a service that has multiple open TCP ports and that works fine, but for convenience I would like to use the same port and subdomains. Is there any layer I can add on top (like a load balancer), or change the service? I have control over most things, basically anything goes.
Example:
Today I can connect to two TCP services like so: foobar.com:1001 and foobar.com:1002. Is it possible to have e.g. service-1.foobar.com:1000 go to foobar.com:1001 and service-2.foobar.com:1000 go to foobar.com:1002.
Different services can bind to same port but on different IP. Hence different domains shall resolve to different IPs : Port combination [where Port is same for all services]. And you can use Proxy service as from HA Proxy to route connections to final destination.
If I understand your question correctly based on your example then no it is not possible. In this case, there is no difference between an HTTP and TCP connection.
In both cases, the hostname is simply resolved to an ip address. If you setup DNS resolution for foobar.com, service-1.foobar.com, service-2.foobar.com to point to the same ip address then they will all go to the same machine.
I have at times needed to have a service running on a different port internally than it is accessible externally. For that, if you are running on Linux, you can simply use iptables to do the port forwarding.
You can find other stack overflow questions/answers for setting up the port forwarding.
https://serverfault.com/questions/140622/how-can-i-port-forward-with-iptables
I am trying to wrap my head around the ssl Tunneling process which is performed by an http proxy after receiving the CONNECT method from a client.
Stuff I can't seem to find or understand in docs, blogs, rfcs:
1) when setting up the tunnel, are the two connections from client-proxy and proxy-destination two separate connections or just one and the same? E.g. is there an tcp handshake between client-proxy and another between proxy-destination?
2) when starting the ssl handshake what node is targeted (ip address/hostname) by the client? The proxy or the destination host? Since ssl requires a point-to-point connection to make the authentication work my feeling tells me it should be the destination host. But then again that wouldn't make sense since the destination host isn't (directly) accessible from the clients perspective (hence the proxy).
when setting up the tunnel, are the two connections from client-proxy and proxy-destination two separate connections or just one and the same? E.g. is there an tcp handshake between client-proxy and another between proxy-destination?
Since the client makes the TCP connection to the proxy there is no other way than that the proxy is making another TCP connection to the server. There is no way to change an existing TCP connection to be connected to a different IP:port.
when starting the ssl handshake what node is targeted (ip address/hostname) by the client? The proxy or the destination host?
The SSL handshake is done with the destination host, not the proxy.
Since ssl requires a point-to-point connection to make the authentication
It doesn't need a point-to-point connection. It just needs that all data gets exchanged unmodified between client and server which is the case when the proxy simply forwards the data.
Suppose I have a VPS with private networking setup such that the only ports that are open are the port for SSHing into the server and the port that connects the server to other servers on the private network. Can this same server still send requests through the internet and receive back responses? If so, through what 'channel' are the requests/responses being sent/received?
It depends on what the outbound firewall settings are on the server. If the firewall allows all outbound connections then you can connect out to any server on any protocol.
However, depending on the hosting provider, they may limit the ports which you can use for outbound connections. Most likely (but not guaranteed) you'll be able to use HTTP (80) and HTTPS (443). It is quite possible that SSH (22) would be open as well. Those three should cover most, if not all, of the needs to would have.