Client verification - security

Let's say that we have two machines machine one and machine two:
machine one has a static IP.
machine two has a dynamic IP.
now machine two wants to connect to machine one. how could machine one verify that the other machine is machine two?
I am searching for a scalable solution so I could use it for a server that has a number of clients.
my solution is to use a key which is already known by the two machines.
machine two will try to connect to machine one. which will respond with a randomly generated string,
that machine two will encrypt using the known key. and sends it back to machine one, which can check if the encrypted string is encrypted with the correct key.
my solution is easily scalable, but I am not sure if it is secure enough. is there a standard solution for doing this??

You're almost there but if you were to rely on this alone you'd be at risk of a man in the middle attack. Say a malicious machine 3 is pretending to be machine 1.
Machine 2 tries to connect to machine 1 but instead opens a connection with machine 3.
Machine 3 opens a connection with machine 1, machine 1 responds with
a string "encrypt_me_please"
Machine 3 responds to machine 2's connection request with
"encrypt_me_please"
Machine 2 encrypts "encrypt_me_please" as (say) "x10hsdapg" and sends
it back to machine 3
Machine 3 responds to machine 1 with the encrypted string "x10hsdapg"
Machine 1 verifies that Machine 3 used the correct encryption key and therefore must be machine 2.
All you can really establish with this is that machine 2 is on the network. But, in a sense that's all you really can do. What I mean is that you can never really be certain that the host you're connected to is who they say they are on an unsecured network. But what we can do is employ various cryptographic techniques so that messages we send can only be decrypted by their intended recipient. See for e.g., RSA.
I hope that helps at least, I'll admit its been a few years since I've studied cryptography.

Related

Ensuring virtual TPM is unique across instances

My code (C++ on Linux) needs to uniquely identify the machine (vm guest/container/physical) that it is running on, and I have been researching TPM (2) for this purpose. Since each physical TPM has a unique EK it seems that I could use the TPM API to verify the machine actually running on is the one expected.
However, with VM's/containers, it seems like a virtual TPM can be copied along with the guest/container to another hypervisor/host. In that case, I assume the EK is copied along with it and this defeats the ability to unique identify the machine (vm guest/container/physical) on which my code runs.
Is this correct? Or do virtual TPM's somehow connect to the host TPM to ensure uniqueness? If someone wanted to bypass my check, I assume running a TPM simulator would have the same effect?

Get unique code from client's machine?

I am trying to identify computers with a unique code based on their machine. However, I can't find any way to do this. I've tried to use mac addresses, but you can only the server's mac address when you're using a linux server. I would use the clients ip address, but it can change if they're using a proxy or vpn, or even if they just unplug their router for a bit.
Can anyone recommend something that would be good for this?
Thanks.
There is no secure way to uniquely identify computers based on hardware, and why should you?
The better practice would be to use an artificial key.
If you want to identify a person - you give it an ID (passport, driving license...), do the same here:
Use the session (apache generates automatically a session ID), or generate a UUID (there are many ways to do this). Or if you need to go beyond - use ssh key pairs, save them somewhere on the PC.
Now to the problem:
1. A client could lie about his hardware, his mac address, VIN/PID, serial number of the SATA cable. You can (and must) never trust such info!
2. Clients hardware could change, and then?

How to generate a host unique ID?

I have several applications which works together and need to communicate.
These applications can be installed on different host, which can be in different local networks, but all are connected together via a global network.
The host can be Linux (CenOS, Debian, Ubuntu) or Windows (7/10).
Now, I need to identify which host is running an application.
The requirements are :
- every application running on the same host have the same "host ID"
- every "host ID" is unique among all hosts
Since the host can be physical machines, virtual machines or even docker instances, I don't think I can use the hostname as a "global unique ID".
Since the host can be in different local networks, I don't think I can use local IP address as a "global unique ID".
So, which data can I use ? Maybe the Network adapter MAC address ? Is it
guaranteed to be unique, even between multiple instances of the same docker ?
Thanks.
On modern / recent Linux distro, linux generates for you a unique id in the /etc/machine-id file when the system is created the first time. Some distributed services such as etcd rely on this file to identify machines in a cluster.
Nothing prevents you from creating and persisting on disk something like a uuid. You can use uuidgen command on Linux for that.
You can say the MAC address is unique. However, if you are concerned about security, do not use the MAC address. The MAC address can be spoofed easily.
To generate a unique ID for the machine, you can use a combination of many items such as MAC Address, IP Address, hostname etc., throw in a random salt and take a sha256 hash of them. Since the host can run on many operating system, I would suggest against using any OS-specific parameters.
Without going into too much detail, the chances of finding a collision in sha256 is improbable to say the least.
You can see the SHA256 of different text here.
http://www.xorbin.com/tools/sha256-hash-calculator
Almost every programming language, these days, has a function/API for creating a SHA256 hash.
Looks like /var/lib/dbus/machine-id contains what you need.
read more here: http://man7.org/linux/man-pages/man5/machine-id.5.html
On linux I solved my problem just by changing the contents of the /var/lib/dbus/machine-id file

How to create a secure "call home" suport capability for an instrument?

I'm an embedded engineer (not a network guru) building a piece of Linux-based equipment (a portable measurement instrument) that is normally not connected to the Internet, but we need to make it possible for the equipment to "call home" for support, including updates and troubleshooting, in a manner that compromises neither the product's security, nor the customer's network security nor our own company network.
The "call home" capability will be completely controlled by the user, perhaps by pressing a physical button to activate it, after the equipment has been connected to whatever network the customer chooses to use. For prototype and demonstrations systems, this network could be at someone's home or office or even via a phone connection (the equipment will contain only a wired Ethernet port, and the customer would need to provide a wired AP if WiFi access is desired).
Making the connection should require no per-call configuration at the user's end, nor within our box, so I'm thinking we can require the customer to provide DHCP, and not much else. We can also require the customer to first contact us before pressing the "call home" button, so we can have our support interface up only when needed.
When a unit does "call home", it merely makes a connection to a company system, doing nothing else until an engineer (well, me) directly connects to it. Other than the existence of the connection, we should get no (or minimal) information about the network the customer is using. So I'm thinking some kind of SSH connection, but that's as far as I have gotten.
If possible, it should "feel" as if I'm connecting locally, as if the unit were on my desk (perhaps with much more latency, loss, and minimal bandwidth).
But I have no idea whatsoever how to make an SSH connection (if that's the right tool to use for this) as two separate halves: The remote unit "calls" somewhere, presumably on one of our company systems, then that system notifies an engineer (me) that a "call home" has been initiated, then waits for the engineer to connect, forming the other half of the connection.
The connection need not identify the remote system (make, model, serial number, version, etc.): I'd do that manually after logging in securely.
If needed, I can create a new system on our end (Linux, BSD, Windows, whatever, physical or VM) that can be dedicated to just this function. I can get at least one static port mapped out to our corporate WAN, if needed (but something I'd prefer to avoid, if possible).
Ideally, I'd also like for there to be minimal information in the equipment itself, so that possession of the equipment by an adversary (or competitor) could not compromise customer or company networks, other units, nor the call-home technique itself. From what little I know, I'd guess a hostname or IP address, a port number, and a key would be needed, but less would be better!
I'd also like the system to require manual intervention at both ends, with minimal automation that can be buggy or be compromised. Once we implement and test the initial system, automation could be added as our experience with it, and confidence in it, grows.
That's about as far as my thinking has taken me. Beyond this, I'm pretty much clueless. Am I on the right track? What pieces am I missing? Is this already a popular thing to do, and I simply don't know what it is called? How simple and stupid can this capability be made for a couple of prototype systems?
EDIT: If it wasn't obvious already, please assume I'm a networking idiot who can be trusted only to follow an explicit recipe, and not much more. KISS applies!
Disclaimer: as long as no "real" answer is there I just provide my more or less theoretical thoughts with hope it helps.
Without reading in detail, I found http://www.vdomck.org/2005/11/reversing-ssh-connection.html to reverse a ssh-connection. If that is easy to follow (it should be easy, just ssh -R basically, see also http://www.brandonhutchinson.com/ssh_tunnelling.html) it means your remote device could connect to your network (and "Pete" is your Partner at the customer). The problem is that initiating a ssh-connection without user/password requires a authentication- private key on that device (so in non-friendly hands).
You could place a dumb ssh-server with no private data and no special access and even the password you could set just for that single connection (and tell your partner "Pete" via phone), let your phantasie play a bit to get a static half "ImGenious$%" and a dynamic half "1243" so you can give a short easy dynamic half over phone.
Then from that dumb ssh-server you can connect to your device as in the article.
I would suggest the call home functionality uses SSH to connect to your office. This requires your customer's network provides DHCP, Internet access and DNS capability. It also requires them to allow outbound connections on port 22. The latter is possibly an issue for some security minded customers who want to prevent unknown egress of data.
You will need a certificate for your SSH server so the certificate is valid for the domain name you choose. You will also need to make sure the SSH client on the server is configured to accept the signature of your server.
It sounds like the number of devices you will be maintaining is relatively low. For this reason, I would suggest generating unique public/private key pairs for each device. You can then load the public key into your server so logins are accepted via keys only.
If a device is compromised or stolen, you can delete the appropriate key from your server. The device will not be able to login again. The private key on the device only has value because you have decided to accept the associated public key on login. Remove this and it has no value. The added benefit is that you can identify a device by the key it has used to login (e.g. you can associate each key with a different user). You can then tie up the login with the information about the device/customer that you store on your systems.
If you use reverse SSH you can have the device connect in. Once you're ready, you can use the reverse part to connect through the tunnel that the device and your server have already setup to perform the maintenance.

What is the unique piece of information for a client browser?

I am working in PHP. I need a computer dependent login system. I mean to say that a user cannot login using multiple computer it will be restricted to only one machine. If so, I will need administrator to handle this case. I tried to make this IP dependent, but I saw that in a network I can login with all computers as they are sharing the same internet connection.
You can try to get the MAC Address which is unique for every machine and is given by the Constructor of the machine.
PS:
#Emmanuel: You can have the same computer name on two machines.
UPDATE:
Some links form getting MAC address in PHP:
http://nazmulb.wordpress.com/2008/07/04/getting-mac-address-using-php/
http://forums.techarena.in/software-development/1179119.htm

Resources