There are 3 servers on consumer side (A <-> B <-> C), 2 of them are our Apps (B (Node.js), C (Python)). All the communications among the servers are handled by WebSockets with TLS. C is not connected to A. I don't want a consumer to be able to run fake B or C server and connect it to real C or B server.

A - client 
B - server for A and separate server with different port for C
C - client

Also there is the external D license server, which is reached via the Internet.
So what is the best way to guarantee server identity?
If these are programs that your customer runs on machines that they own and host, and the customer is the attacker you're trying to protect against, then there really is no way to do this.

You can write a simple challenge-response protocol, where B and C only have to know each other's public keys to both be able to verify that the other side knows its own private key.
But where are you going to store that private key? Somewhere that the program can access it—which means somewhere that your customer can access it.

Of course you can try to obfuscate the keys. This works great if nobody cares about cracking your system—but then if nobody cares, you don't have to do anything. If cracking your system would be valuable to someone, they'll find a way to dig out the keys.
At which point you're in an arms race: every time someone finds your keys, you have to think of a new way to obfuscate them to make them start all over.
And even that won't work unless you can require your customers to stay up to date on all of their servers. Otherwise, once I've dug the keys out of your version 1.3.4, I can just keep running version 1.3.4 of server C, and my own fake server B.

If you can force the servers to communicate with another server that you run and control out on the internet, you can make it much harder to crack the handshake (and harder to stick with old versions), but it's still nowhere near impossible. And really, that just shifts the attack surface to modifying the servers so they don't do the upstream check. What you're basically talking about here is the equivalent of Windows Activation or online game verification—which, of course, people have cracked.

There are plenty of cases where it's worth doing something anyway:

Often a small amount of obfuscation is worth it to deter casual hackery.
Paying for one of the commercial solutions means you're now using "industry standard" protection, so you use the DMCA against anyone who attacks it, you can defend yourself if partners sue you over lost data, etc.
If $200K/year worth of engineering can knock even 10% of the losses off $200M/year worth of content, spend the effort.

But at this point, we're not talking about business issues, so you'll probably get better advice from a security consultant who can ask you the right questions about your business, than from a generic answer on a programming site.
How to guarantee server identity?