зеркало из https://github.com/microsoft/lsvmtools.git
Mikbras (#6)
Updated readme, docs, added verification, fixed tests & typos
This commit is contained in:
Родитель
28cba2161c
Коммит
eadf6edb62
6
Makefile
6
Makefile
|
@ -27,7 +27,6 @@ DIRS = striplic 3rdparty posix lsvmutils lsvmtool lsvmload policy
|
|||
|
||||
all:
|
||||
$(foreach i, $(DIRS), $(MAKE) -C $(i) $(NL) )
|
||||
$(MAKE) -C lsvmtool autotests
|
||||
|
||||
##==============================================================================
|
||||
##
|
||||
|
@ -144,12 +143,13 @@ DISTEXCLUDE = \
|
|||
|
||||
|
||||
dist:
|
||||
@ rm -rf $(TOP)/$(SRCPKGNAME).tar.gz
|
||||
@ rm -rf $(SRCDIRNAME)
|
||||
@ cp -r $(TOP) $(SRCDIRNAME)
|
||||
@ rm -rf $(DISTEXCLUDE)
|
||||
@ ( cd $(SRCDIRNAME); $(MAKE) -s distclean )
|
||||
@ ( cd /tmp; tar zcf $(SRCPKGNAME).tar.gz $(SRCPKGNAME) )
|
||||
@ echo "Created /tmp/$(SRCPKGNAME).tar.gz"
|
||||
@ ( cd /tmp; tar zcf $(TOP)/$(SRCPKGNAME).tar.gz $(SRCPKGNAME) )
|
||||
@ echo "Created $(TOP)/$(SRCPKGNAME).tar.gz"
|
||||
|
||||
##==============================================================================
|
||||
##
|
||||
|
|
213
README.md
213
README.md
|
@ -1,33 +1,206 @@
|
|||
# vmshield
|
||||
Linux project for Microsoft Shielded VM project
|
||||
LSVMTools
|
||||
=========
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
### How to install LSVMTools:
|
||||
The LSVMTools project provides tools for shielding Linux VMs operating
|
||||
in the Microsoft(R) Windows Hyper-V environment. LSVMTools aims to protect
|
||||
Linux VMs from attack while at rest and in flight. It builds on the following
|
||||
technologies.
|
||||
|
||||
1. Configure the distribution:
|
||||
- Windows Server 2016 Guarded Fabric
|
||||
- Hyper-V Shielded VMs
|
||||
- UEFI
|
||||
- TPM 2.0
|
||||
- Linux Unified Key Setup (LUKS)
|
||||
- dm-crypt
|
||||
|
||||
`./configure`
|
||||
LSVMTools provides two main tools.
|
||||
|
||||
2. Build the distribution:
|
||||
- **LSVMPREP** - Prepares the image for shielding
|
||||
- **LSVMLOAD** - The primary boot loader for the image
|
||||
|
||||
`make`
|
||||
### LSVMPREP
|
||||
|
||||
3. Install LSVMTools (under /opt/lsvmtools-1.0.0):
|
||||
**LVSMPREP** prepares the Linux enviroment for shielding. After the image
|
||||
is prepared, it must be templatized and provisioned as described in the
|
||||
[LSVM How-To](doc/LSVM_How_To.pdf) document. LSVMPREP performs the following
|
||||
steps.
|
||||
|
||||
`make install`
|
||||
- Encrypts the boot partition with a well-known passphrase
|
||||
- Patches the system to automatically mount the encyrpted boot parition
|
||||
- Installs LSVMLOAD on the EFI System Partition (ESP)
|
||||
- TPM-seals the passphrases and stores them on the ESP
|
||||
- Copies the SHIM and GRUB2 to the encrypted boot partition
|
||||
- Patches the initial ramdisk configuration to get passphrases non-interactively
|
||||
- Regenerates the initial ramdisks and GRUB2 configuration
|
||||
- Applies any UEFI dbx updates (for black-listed boot loaders)
|
||||
|
||||
4. Prepare an image for shielding:
|
||||
After these steps are performed, the image is ready to be templatized. See
|
||||
the [LSVM How-To](doc/LSVM_How_To.pdf) document for details.
|
||||
|
||||
`cd /opt/lsvmtools-1.0.0`
|
||||
`./lsvmprep`
|
||||
### LSVMLOAD
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
**LSVMLOAD** becomes the primary EFI boot loader for the Linux VM. UEFI loads
|
||||
LSVMLOAD, assuming it passes certificate verification (**LSVMLOAD** must be
|
||||
signed by a certificate that Hyper-V trusts). **LSVMLOAD** performs the
|
||||
following steps.
|
||||
|
||||
### Code of Conduct
|
||||
- Uses TPM to unseal a **keyfile** (containing the disk partition passphrases)
|
||||
- Maps the ESP onto an **ESP ramdisk**
|
||||
- Maps the encrypted boot partition onto an unencrypted **boot ramdisk**
|
||||
- Patches the initial ramdisk with the **keyfile** (on the boot ramdisk)
|
||||
- Loads the Linux SHIM from the **boot ramdisk**
|
||||
- Launches the SHIM, which is redirected to the **ESP ramdisk**
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct]
|
||||
(https://opensource.microsoft.com/codeofconduct/). For more
|
||||
information see the [Code of Conduct FAQ]
|
||||
(https://opensource.microsoft.com/codeofconduct/faq/) or contact
|
||||
[opencode@microsoft.com](mailto:opencode@microsoft.com) with any
|
||||
additional questions or comments.
|
||||
The SHIM finds GRUB2 on the **ESP ramdisk** (copied from the encrypted boot
|
||||
partition by LSVMLOAD). The SHIM executes GRUB2, which is redirected to the
|
||||
**boot ramdisk**, where it finds:
|
||||
|
||||
- A patched GRUB2 configuration file
|
||||
- A patched initial ramdisk (patched by LSVMLOAD with the **keyfile**)
|
||||
- The Linux kernel
|
||||
|
||||
GRUB2 executes the kernel and the initial ramdisk. The initial ramdisk mounts
|
||||
the boot and root partitions using the **keyfile** injected by LSVMLOAD.
|
||||
|
||||
LSVMLOAD works using unmodified SHIM and GRUB2 executables, making it
|
||||
possible to configure a Linux environment for shielding without having
|
||||
to change any programs along the boot chain.
|
||||
|
||||
Supported Linux distributions
|
||||
-----------------------------
|
||||
|
||||
LSVMTool current supports the following Linux distributions.
|
||||
|
||||
- Ubuntu 16.04 LTS with the 4.4 kernel
|
||||
- Red Hat Enterprise Linux 7.3
|
||||
- SUSE Linux Enterprise Server 12 Service Pack 2
|
||||
|
||||
Installing
|
||||
----------
|
||||
|
||||
This section explains how to install from a binary distribution. Binary
|
||||
distributions can be downloaded from the following link.
|
||||
|
||||
- [Binary Distributions](binaries)
|
||||
|
||||
These distributions include **LSVMPREP** and a signed **LSVMLOAD**.
|
||||
|
||||
Use the following commands to install the distibution.
|
||||
|
||||
```
|
||||
# tar zxvf lsvmtools-1.0.0-x86_64.tar.gz
|
||||
# cd lsvmtools-1.0.0-x86_64
|
||||
# ./install
|
||||
|
||||
Created /opt/lsvmtools-1.0.0
|
||||
```
|
||||
|
||||
This installs LSVMTools in the following location.
|
||||
|
||||
```
|
||||
/opt/lsvmtools-1.0.0
|
||||
```
|
||||
|
||||
Running LSVMPREP
|
||||
----------------
|
||||
|
||||
**Caution: Running LSVMPREP encrypts the boot partition and makes irreversible
|
||||
configuration changes to a virtual machine. Only run LSVMPREP to prepare an
|
||||
image for templatization.**
|
||||
|
||||
To run LSVMPREP, execute the following commands as root.
|
||||
|
||||
```
|
||||
# cd /opt/lsvmtools-1.0.0
|
||||
# ./lsvmprep
|
||||
|
||||
***************************************************
|
||||
* ____ _ _ _ _____ ___ ___ _ _ *
|
||||
* / ___| / \ | | | |_ _|_ _/ _ \| \ | | *
|
||||
* | | / _ \| | | | | | | | | | | \| | *
|
||||
* | |___ / ___ \ |_| | | | | | |_| | |\ | *
|
||||
* \____/_/ \_\___/ |_| |___\___/|_| \_| *
|
||||
* *
|
||||
* *
|
||||
* LSVMPREP is about to encrypt the boot partition *
|
||||
* and make irreversible configuration changes to *
|
||||
* this machine. If you are certain you want to *
|
||||
* proceed, type YES in uppercase and then press *
|
||||
* enter; else press ENTER to terminate. *
|
||||
* *
|
||||
***************************************************
|
||||
|
||||
> _
|
||||
```
|
||||
|
||||
If LSVMPREP runs successfully, the image is ready to be templatized. See
|
||||
[LSVM How-To](doc/LSVM_How_To.pdf) for what to do next.
|
||||
|
||||
Building
|
||||
--------
|
||||
|
||||
This section explains how to build LSVMTools from source, but note that
|
||||
LSVMPREP requires a signed LSVMLOAD image, which must be downloaded separately
|
||||
(see the previous section for details).
|
||||
|
||||
To build LSVMTools, type these commands.
|
||||
|
||||
```
|
||||
# ./configure
|
||||
# make
|
||||
```
|
||||
|
||||
These commands build LSVMPREP and an unsigned LSVMLOAD.
|
||||
|
||||
To run the tests, type:
|
||||
|
||||
```
|
||||
# make tests
|
||||
```
|
||||
Recovering the LUKS keys
|
||||
------------------------
|
||||
|
||||
In case anything goes wrong, use the following command to recover LUKS keys.
|
||||
|
||||
```
|
||||
# dmsetup table --showkeys
|
||||
```
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
```
|
||||
LSVMTools
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE
|
||||
```
|
||||
|
||||
Code of Conduct
|
||||
---------------
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
|
||||
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
LSVMTools Binary Distributions
|
||||
==============================
|
||||
|
||||
Binary Distributions
|
||||
--------------------
|
||||
|
||||
- [lsvmtools-1.0.0-x86_64.tar.gz](lsvmtools-1.0.0-x86_64.tar.gz)
|
||||
|
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -136,7 +136,7 @@ int PatchInitrd(
|
|||
goto done;
|
||||
}
|
||||
|
||||
PutProgress(L"Pathching %a", Str(initrdPath));
|
||||
PutProgress(L"Patching %a", Str(initrdPath));
|
||||
|
||||
/* Inject keys into this initrd */
|
||||
{
|
||||
|
|
88
lsvmprep
88
lsvmprep
|
@ -150,6 +150,74 @@ case ${vendor} in
|
|||
exit 1
|
||||
esac
|
||||
|
||||
##==============================================================================
|
||||
##
|
||||
## Ask for permissio to change the system
|
||||
##
|
||||
##==============================================================================
|
||||
|
||||
|
||||
ask_permission()
|
||||
{
|
||||
cat<<EOF
|
||||
|
||||
***************************************************
|
||||
* ____ _ _ _ _____ ___ ___ _ _ *
|
||||
* / ___| / \ | | | |_ _|_ _/ _ \| \ | | *
|
||||
* | | / _ \| | | | | | | | | | | \| | *
|
||||
* | |___ / ___ \ |_| | | | | | |_| | |\ | *
|
||||
* \____/_/ \_\___/ |_| |___\___/|_| \_| *
|
||||
* *
|
||||
* *
|
||||
* LSVMPREP is about to encrypt the boot partition *
|
||||
* and make irreversible configuration changes to *
|
||||
* this machine. If you are certain you want to *
|
||||
* proceed, type YES in uppercase and then press *
|
||||
* enter; else press ENTER to terminate. *
|
||||
* *
|
||||
***************************************************
|
||||
|
||||
EOF
|
||||
|
||||
echo -n "> "
|
||||
read answer
|
||||
echo ""
|
||||
|
||||
if [ "${answer}" != "YES" ]; then
|
||||
echo "$0: no action taken"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
ask_permission
|
||||
|
||||
##==============================================================================
|
||||
##
|
||||
## check_root()
|
||||
##
|
||||
##==============================================================================
|
||||
|
||||
check_root_passphrase()
|
||||
{
|
||||
rootdev=`./scripts/rootdev`
|
||||
|
||||
if [ -z "${rootdev}" ]; then
|
||||
echo "$0: failed to resolve root partition"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -n "passphrase" | cryptsetup luksDump --dump-master-key --key-file=- $rootdev 2> /dev/null > /dev/null
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
echo "$0: ERROR: The root partition passphrase must be 'passphrase'"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_root_passphrase
|
||||
|
||||
##==============================================================================
|
||||
##
|
||||
## Resolve 'shim':
|
||||
|
@ -825,3 +893,23 @@ cp VERSION ${lsvmprepfile}
|
|||
|
||||
# Run sanity check:
|
||||
./sanity
|
||||
|
||||
##==============================================================================
|
||||
##
|
||||
## final_word()
|
||||
##
|
||||
##==============================================================================
|
||||
|
||||
final_word()
|
||||
{
|
||||
cat<<EOF
|
||||
|
||||
This image has been successfully prepared for templatization.
|
||||
|
||||
The passphrase for the root partition is: passphrase
|
||||
The passphrase for the boot partition is: passphrase
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
final_word
|
||||
|
|
|
@ -64,8 +64,6 @@ LIBRARIES += -lposixlinux
|
|||
#LINKFLAGS = -static
|
||||
LINKFLAGS = -Wl,-gc-sections
|
||||
|
||||
AUTOTESTS=$(TMPDIR)/autotests
|
||||
|
||||
CLEAN += $(EXT2)
|
||||
CLEAN += $(VFAT)
|
||||
CLEAN += $(LSVMCPIO)
|
||||
|
@ -80,7 +78,6 @@ CLEAN += boot.cfg
|
|||
CLEAN += lsvmhashes
|
||||
CLEAN += initrd.cpio
|
||||
CLEAN += initrd.cpio.gz
|
||||
CLEAN += $(AUTOTESTS)
|
||||
|
||||
PROGRAM=lsvmtool
|
||||
|
||||
|
@ -372,6 +369,8 @@ test-pcrs256:
|
|||
##
|
||||
##==============================================================================
|
||||
|
||||
HAS_TPM=$(shell $(BINDIR)/lsvmtool hastpm 2> /dev/null > /dev/null )
|
||||
|
||||
tests:
|
||||
@ $(MAKE) -s cpio-tests
|
||||
@ $(MAKE) -s ext2-tests MKE2FSFLAGS="-b 1024"
|
||||
|
@ -384,18 +383,12 @@ tests:
|
|||
@ $(MAKE) -s strtok-tests
|
||||
@ $(MAKE) -s test-crypt
|
||||
@ $(MAKE) -s sha-tests
|
||||
|
||||
tpm-tests:
|
||||
ifeq ($(HAS_TPM),yes)
|
||||
@ $(MAKE) -s test-seal
|
||||
@ $(MAKE) -s lsvmtool-tests
|
||||
@ $(MAKE) -s test-pcrs
|
||||
@ $(MAKE) -s test-pcrs256
|
||||
|
||||
$(AUTOTESTS): $(LSVMTOOL)
|
||||
@ $(MAKE) -s tests
|
||||
@ touch $(AUTOTESTS)
|
||||
|
||||
autotests: $(AUTOTESTS)
|
||||
endif
|
||||
|
||||
##==============================================================================
|
||||
##
|
||||
|
@ -423,3 +416,5 @@ seal:
|
|||
@ echo -n "ABCDEFGHIJKLMNOPQRSTUVWXYZ" > ALPHABET.in
|
||||
$(LSVMTOOL) seallsvmloadpolicy $(BOOTLOADER) ALPHABET.in ALPHABET.out
|
||||
|
||||
hastpm:
|
||||
$(BINDIR)/lsvmtool hastpm
|
||||
|
|
|
@ -124,6 +124,7 @@ static EFI_TCG2_PROTOCOL* _GetTPMProtocol()
|
|||
if (!(protocol = TCG2_GetProtocol()))
|
||||
{
|
||||
fprintf(stderr, "Warning: TCG2_GetProtocol() failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
|
@ -151,20 +152,25 @@ static EFI_TCG2_PROTOCOL* _GetTPMProtocol()
|
|||
return protocol;
|
||||
}
|
||||
|
||||
static void _TestIsTPMPresent()
|
||||
static BOOLEAN _IsTPMPresent()
|
||||
{
|
||||
EFI_TCG2_PROTOCOL* protocol = _GetTPMProtocol();
|
||||
EFI_STATUS status;
|
||||
static EFI_TCG2_PROTOCOL* protocol = NULL;
|
||||
EFI_TCG2_BOOT_SERVICE_CAPABILITY capability;
|
||||
TPM_RC rc;
|
||||
|
||||
printf("=== TestIsTPMPresent()\n");
|
||||
if (!(protocol = TCG2_GetProtocol()))
|
||||
return FALSE;
|
||||
|
||||
status = TCG2_GetCapability(protocol, &capability);
|
||||
if (TCG2_GetCapability(protocol, &capability) != EFI_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
if (status != EFI_SUCCESS)
|
||||
assert(0);
|
||||
if (capability.TPMPresentFlag != TRUE)
|
||||
return FALSE;
|
||||
|
||||
assert(capability.TPMPresentFlag == TRUE);
|
||||
if ((rc = TPM2X_SetDictionaryAttackLockReset(protocol)) != TPM_RC_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void _TestGetTPMRevision()
|
||||
|
@ -2015,7 +2021,6 @@ static int _tests_command(
|
|||
const char** argv)
|
||||
{
|
||||
EFI_TCG2_PROTOCOL* protocol = _GetTPMProtocol();
|
||||
_TestIsTPMPresent(protocol);
|
||||
_TestGetTPMRevision(protocol);
|
||||
#if !defined(_WIN32)
|
||||
_TestSetDictionaryAttackLockReset(protocol);
|
||||
|
@ -4624,6 +4629,29 @@ done:
|
|||
return status;
|
||||
}
|
||||
|
||||
static int _hastpm(
|
||||
int argc,
|
||||
const char **argv)
|
||||
{
|
||||
int status = 1;
|
||||
|
||||
if (argc != 1)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s\n", argv[0]);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (_IsTPMPresent())
|
||||
printf("yes\n");
|
||||
else
|
||||
printf("no\n");
|
||||
|
||||
status = 0;
|
||||
|
||||
done:
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
**==============================================================================
|
||||
**
|
||||
|
@ -5019,6 +5047,11 @@ static Command _commands[] =
|
|||
"Deserializes the specialization file",
|
||||
_deserialize_specfile_command,
|
||||
},
|
||||
{
|
||||
"hastpm",
|
||||
"Checks whether TPM is present or not",
|
||||
_hastpm,
|
||||
},
|
||||
};
|
||||
|
||||
static size_t _ncommands = sizeof(_commands) / sizeof(_commands[0]);
|
||||
|
@ -5110,6 +5143,4 @@ int lsvmtool_main(int argc, const char* argv[])
|
|||
|
||||
fprintf(stderr, "%s: unknown command: '%s'\n", argv[0], argv[1]);
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -66,3 +66,7 @@ install_lsvmtool()
|
|||
}
|
||||
|
||||
install_lsvmtool ${lsvmtool}
|
||||
|
||||
echo ""
|
||||
echo "Created ${destdirname}"
|
||||
echo ""
|
||||
|
|
Загрузка…
Ссылка в новой задаче