Ensuring virtual TPM is unique across instances - linux

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?

Related

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

Linux uuidgen - uniqueness of output across VM instances

Background:
I have developed a software which runs on Linux and I distribute licenses for it to work.
For Linux installations I am using system UUID and my license is based on that.
For installing on various Cloud setups, I am packaging the OS with my software and providing to the User. User deploys it and requests license based on UUIDs shown in my software.
Issue:
When User deploys each instance, in few Cloud setups, UUIDs are same for different VM instances on same physical machine.
This causes a problem for license.
Solution:
What I have planned to do is simple: when OS boots up first time call uuidgen and generate UUID and store it to a file. After that for next reboot I will take it from this file so UUID will be same for the machine.
Questions on above solution:
1
uuidgen with random option calculates uuid by utilizing /dev/random
In a VM setup since there is no direct hardware access for generating this random seed, can /dev/random value possibly be same in different VM instances? which means uuidgen will operate on same seed?
2
if UUID generated in two different linux systems by uuidgen during first time bootup are same because the random seed was not good enough, then the next UUID generated will also be same in those Linux systems?
i.e.
While booting up, uuidgen is called and produces a UUID1 in VM1. Say it is same as UUID2 when uuidgen was called in another VM instance VM2.
If uuidgen is called again for next UUID in VM1, will it be again same if called in VM2?
Thank you.
The most probable thing to investigate is if the customer has generated those VM images from a common one, in which the uuid has already been generated. Having the lenght a uuid has, it's most improbable that you produce a colission of uuids.
By the way, requiring your software to depend on the uuid stored in a file allows your customer to clone your VM after your software has been installed, and all licenses validated by cloning.
If you want to protect your software licenses on VMs, you'll have to do some connecting to a license server and do some public key signing feature to validate licenses.
The main problem is that two cloned images from a virtual machine are exactly equal (hardware and software) and as so, can run the same software without having any difference from the point in time they where cloned.

Is it possible to simulate Linux on USB devices using VMware?

I have successfully installed RedHat Linux and run them on harddrive using VMware simulation. Things work quite smooth if I put all the nodes VM on my physical machine.
For management purposes, I want to use USB devices to store ISO and plug one if more nodes are needed. I would like to run VMware on my physical machines.
Can I just build one virtual machine on one USB device? So I can plug one node if needed.
I mean, if I simulate machine A one USB 1 and another machine B on USB 2, can I build a network using my physical machine as server?
(1) If so, are there problems I should pay attention to?
(2) If not, are there any alternative solution for my management purpose?(I do not want to make VMs on partitions of my physical machine now) Can I use multiple mobile hard drives instead?
Actually I want to start up master-slaves Hadoop2.x deployments using virtual machines. Are there any good reference for this purpose?
I shall explain that am not too lazy to have a try on my idea, however, it is now rather expensive to do so if I do not even know something about the feasibility of this solution.
Thanks for your time.
I'm not an expert on VMWare, but I know that this is common on almost any virtualization system. You can install a system :
on a physical device (a hard disk, a hard disk partition)
or on a file
The physical device way allows normally better performances since you only use one driver between the OS and the device, while the file way offer greater simplicity to add one VM.
Now for your questions :
Can I just build one virtual machine on one USB device? Yes, you can always do it on a file, and depending on host OS directly on the physical device
... can I build a network using my physical machine as server? Yes, VMWare will allow the VM to communicate with each other and/or with the host and/or with external world depending on how you configure the network interfaces of your VMs.
If so, are there problems I should pay attention to?
USB devices are pluggable and unpluggable. If you unadvertantly unplug one while the OS is active bad things could happen. That's why I advised you to use files on the hard disk to host your VMs.
memory sticks (no concern for USB disks) support a limited number of writes and generally perform poorly on writes. Never put temp filesystem of swap there but use a memory filesystem for that usage, as is done for live filesystems on read-only CD or DVD
every VMs uses memory from the host system. That is often the first limitation for the number of simultaneous VMs on a personnal system

Determine whether MAC address is physical or virtual on Linux

I have tried using several commands as well as couple of examples using C/C++ but am still not able to find a flawless method that can differentiate between physical or virtual ethernet adapters. Physical means, on that available on your board or installed externally and virtual means created by virtualization apps such as VirtualBox/VMWare/Virtual PC or VPN etc.
Any pointers?
There is no flawless method. A virtual adapter can have any MAC address, including one that might have been assigned by a constructor to a physical device. And the other way around, given that one can change the MAC address of a physical adapter. You can only make an educated guess.
You might find it easier to detect if you are running virtualized at all, rather than look for specific information about the NICs. The virt-what(1) tool looks through aspects of the running system to guess if the system is virtualized or not. (The script isn't as smart as you think, but it does have a lot of small information gathering tools in one place.)
Someone intentionally trying to bypass a license check would probably not find it difficult to defeat this mechanism.
Maybe one can use mii-tool and check if it fails, which it does for virtual:
mii-tool vmbr2
SIOCGMIIPHY on 'vmbr2' failed: Operation not supported
mii-tool eno1
eno1: negotiated 1000baseT-FD flow-control, link ok
EDIT:
What is mii-tool: view, manipulate media-independent interface status
This utility checks or sets the status of a network interface's
Media Independent Interface (MII) unit. Most fast ethernet
adapters use an MII to autonegotiate link speed and duplex
setting.
https://www.man7.org/linux/man-pages/man8/mii-tool.8.html

Resources