I'm preparing for system design interviews and don't have much hands-on experience with load balancers. There are a few questions that have been bugging me for a long time, so I'm just hoping for responses from the wonderful community.
How does LB map the response to the client's real request?
I believe that some mapping should be kept at LB which helps to send it back to client.
Flow should be - based on my limited understanding and the assumptions made above.
Client(C) sends request
Source IP
Target IP
Request Identifier
Request
10.11.11.12
15.12.14.74 (LB address )
R1
/getUsers
LB will forward this to Server
Source IP
Target IP
Request Identifier
Request >
15.12.14.74 (LB address )
115.12.14.80(Server Address)
R1
/getUsers
server will respond back the request,
Source IP
Target IP
Request Identifier
Response
15.12.14.80(Server Address)
15.12.14.74 (LB address )
R1
[Users]
LB will map it using "Request Identifier" and will send it back to client
Source IP
Target IP
Response
15.12.14.74 (LB address )
10.11.11.12
[Users]
The key, which is missing in your questions, is ports. Load balancers are, so called, operating on either L4 or L7 levels. Basically, the lowest they do is L4, which is transport layer.
L3 is the network layers, and IP protocol lives there. TCP is L4 and the difference to L3 is in ports.
So when a client A talks to server B - the request (L4) has both ip addresses and ports - tuples. For example, client's side will look like [10.11.11.12, 10023(random port above 1024)] and server side will be [15.12.14.74, 80] - the same tuple exists on the other side, where the LB connects to actual server, but in that case the LB plays client's role.
With ports in mind, LB have a mapping between connections it received from clients and connections LB established to servers. Having ports allow many to many mapping - same client may have more than one connection to many servers via LB.
The above was about L4; L7 works in similar way - just more processing is happening on the load balancer itself.
Related
I have read that the overhead is low. What does it really mean when compared to HTTP? Does it not use the ip address of the server to which a client tries to connect to? If not, how does a client connect to a server?
Low overhead means that for a given size of messages there is very little extra information sent. It has nothing to do with broker discovery.
E.g. for a HTTP message there us a relatively large amount of HTTP Headers sent before any of the message is transmitted.
The client will connect to the broker via it's IP address. This can either be known in advance, looked up from a host name via DNS or looked up via a TXT record in the DNS for a given domain. You can see examples of broker discovery on the mqtt.org site here
In C++ (I didn't include code because this is more of a protocol understanding matter) I am creating a SOCKS5 server and had a few questions because the client terminates the connection after I send it the approved message. In the RFC it says BND.ADDR and BND.PORT are used for: RFC 1928
o BND.ADDR server bound address
o BND.PORT server bound
port in network octet order`
In the reply to a CONNECT, BND.PORT contains the port number that the
server assigned to connect to the target host, while BND.ADDR
contains the associated IP address.
Here are my questions,
What is BND.PORT and what should I specify for it?.
What does it mean by "server assigned to connect to the target host" Is target host the "Client"?
I've read the RFC front to back like 5 times and I have yet to understand it, can someone go into more detail about the BND.PORT and what it means?
I was sniffing around in Wireshark and I found that BND.PORT was different for each request made. (I am not sure what port to enter because everything I tried resulted in Proxifer (The socks client) says "The server gave an unexpected replay - Connection terminated"
Wireshark connection hex-dump from an actual SOCKS5 server (not mine):
Just to make sure we're on the same page... This is the relationship between client, server and host. Notice that the client and host can't talk to each other directly.
CLIENT <-> SERVER <-> HOST
What does it mean by "server assigned to connect to the target host" Is target host the "Client"?
No. The "host" is the device the client is trying to connect to via the SOCKS5 server. The "client" is on the other side of the SOCKS5 server, furthest away from the host.
What is BND.PORT and what should I specify for it?.
BND.PORT is the source port of packets leaving the SOCKS5 server, bound for a host. You have no control over what port the server chooses. Think about it. Where does a host see packets coming from? It certainly isn't the client. From the perspective of the host, packets are all coming from the server, it doesn't know about the client. Additionally the BND.ADDR is the IP of the server.
What I've said is true under the condition that CONNECT is being used. I have no experience with BIND or UDP ASSOCIATE yet.
I have various routers which connect to my radius system, their IP might change as it's all over the net via NAT networks..
Each router has a unique secret. All known in a local DB
Now I'm looking to set radius up in a way that every router can authenticate with their custom secret, via whatever IP, but freeradius won't let me configure it like this:
client 0.0.0.0/0 {
shortname = test1
secret = AA
}
client 0.0.0.0/0 {
shortname = test2
secret = AB
}
Is there a way so I can either disable the freeradius IP check (and check on secret only?), or to force a client (/ip) to have more than 1 secret ?
Reconfigurating the secret to all the same is unfortunately not possible, as some routers already have been deployed with very limited network access.
I'm using:
freeradius: FreeRADIUS Version 2.2.8, for host x86_64-pc-linux-gnu, built on Apr 5 2016 at 13:40:43
Copyright (C) 1999-2015 The FreeRADIUS server project and contributors.
Why what you want doesn't work with RADIUS/FreeRADIUS alone
FreeRADIUS does the packet to client matching before the packet is decoded. Decoding the packet before performing the matching makes DoS attacks against the server easier, as spurious requests cause the server to use more CPU time.
Ignoring the secret isn't an option either. The secret is used by the Access point to decode protected attributes like the MPPE key attributes for WPA2 Enterprise.
For walled gardens with PAP the shared secret is used to encrypt the cleartext password provided by the user, so if you don't know the shared secret you can't get the plaintext value back for validation.
In v4.0.x the plan is to send packets from unknown IP addresses down to the worker threads for processing. At this point the worker would have full knowledge of all attributes, and could bind a secret to the IP address using that additional information.
It still wouldn't let you map incoming packets using RADIUS attributes, but you're unlikely to see a conflict where two APs swap their WAN IPs... Apart from possibly in a CGN environment with a small public pool.
Available options
Use RADSEC (DTLS/TLS). Clients are validated using a certificate, and the shared secret is fixed.
Establish a tunnel (L2TP/IPSEC/PPP) between the AP and your RADIUS server. Use that to provide consistent local IP addresses.
Run the APs dual stack, hopefully bypassing the NAT. Some ISPs have begun offering IPv6 connectivity with prefix delegation. In these cases, all devices behind the CPE get publicly accessible IPv6 addresses. The prefix may change occasionally, so you'd need to use some sort of 'phone home' system, where the AP could inform your servers of its public address.
Develop your own software, which snoops on incoming RADIUS packets, and checks to see if the IP matches one in your client database. If it doesn't, it tries all the shared secrets to see if any can be used to validate the packet contents, and then updates the IP binding for that client. This might work best with your set of restrictions.
I think there's also some patches out there for v2.x.x which allow dynamic clients to be created using decoded attributes, but v2.x.x was EOL'd a while back, and they're not officially supported.
I'm trying to get the underlying socket/stream or the IP address from a NSURLConnection as the request starts transmitting a response. I haven't been able to find a way to get the underlying lower level stream from an active request (which would then easily allow me to get the IP information).
The use case for this is to record the exact IP used to a debug log since the hostname in the URL request can return many different IPs from the load balancer.
I recognize that these are higher level APIs than plain sockets and I'm considering doing a parallel DNS resolve for the same hostname as a workaround, but that still doesn't gurantee that the DNS resolution will return the same IP that was used for the request in question.
Thanks in advance for the help!
first - it's not a question of "how to bind to port of another software".
now, i have a client-server app, based on TCP and i'd like to make it UDP, but i'm missing something..
i have 2 rules (which i put) to this app:
1) the "server" can stay behind router without any port forwarding configuration.
2) the "client" can listen to only one port.
in TCP i do it like this:
1) the server opens initial connection to the client on port X.
2) when the client wants to open communication channel to the server it uses the initial socket to ask the server for a new one.
3) the server creates a new socket and connect to the client on port X.
4) the client accept this new connection on port X, and now the client talk with the server on this new socket.
this way i can have multiple connections on the same port.
in UDP, i have a little problem..
1) the server sends the initial connection dgram to the client on port X.
2) when the client wants to open communication channel to the server it sends request for a new socket to the initial socket's addr.
3) the server receives the message, creates a new udp socket, and use it to send data to the client on port X.
4) the client receives the new dgram, and ....?
basically what i want to happen now is to "accept" this connection. meaning: to create a new UDP socket, to bind it also to port X and receive data only from that specific incoming socket addr (ip,port). but i cannot do that because i can't bind multiple socket to same port.
so what is the way to create multiple udp connections on one port? (in networking way, not just create a ring buffer of dgrams and send to the right socket)
thanks :)
As UDP is connectionless protocol, on step 4 you check the contents of UDP message and decide how to handle it. In other words, the type of message is defined only by it's contents.
However, I have a feeling that your whole design is a bit wrong. It's much more common for the client to be behind firewall (just because there exist more clients, than servers). If you need to put the server behind firewall, you just configure the firewall to allow connections to the set of ports. Even when you have just one more port opened, nothing prevents the client from connecting to the same server port several times in parallel.