diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..92a36816d57be80297d688498a8a50f28a10eb2c --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +# Test data +*.pem +*.srl +*.csr +*.cert + +# Build file +virtrust/build/* + +.vscode + +*.claude + +transcript.txt + +.cache + +*.pb.cc +*.pb.h + +# ides + +.idea \ No newline at end of file diff --git a/.workflow/virtrust.yml b/.workflow/virtrust.yml new file mode 100644 index 0000000000000000000000000000000000000000..8c3a8a22ba07be7b1269cb89bfed99a8bdca661b --- /dev/null +++ b/.workflow/virtrust.yml @@ -0,0 +1,33 @@ +version: '1.0' +name: pipeline-20251111 +displayName: pipeline-20251111 +triggers: + trigger: auto + push: + branches: + prefix: + - '' +stages: + - name: stage-9b022c7d + displayName: virtrust + strategy: naturally + trigger: auto + executor: [] + steps: + - step: build@gcc + name: build_gcc + displayName: GCC 构建 + gccVersion: '9.4' + commands: + - '# 新建build目录,切换到build目录' + - 'mkdir build && cd build ' + - '# 生成Unix平台的makefiles文件并执行构建' + - cmake -G 'Unix Makefiles' ../ && make -j + artifacts: + - name: BUILD_ARTIFACT + path: + - ./bin + caches: [] + notify: [] + strategy: + retry: '0' diff --git a/virtrust/.clang-format b/virtrust/.clang-format new file mode 100644 index 0000000000000000000000000000000000000000..fe3bd44ae7cb48736e0f0c4060be7998f349723c --- /dev/null +++ b/virtrust/.clang-format @@ -0,0 +1,112 @@ +Language: Cpp +BasedOnStyle: Google +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +# AllowShortEnumsOnASingleLine: false +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^<.*\.h>' + Priority: 1 + - Regex: '^<.*' + Priority: 2 + - Regex: '.*\.pb\.h"$' + Priority: 5 + - Regex: '^"virtrust.*' + Priority: 4 + - Regex: '^".*' + Priority: 3 +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: true +IndentPPDirectives: None +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 80 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 80 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never \ No newline at end of file diff --git a/virtrust/.projectile b/virtrust/.projectile new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/virtrust/CLAUDE.md b/virtrust/CLAUDE.md new file mode 100644 index 0000000000000000000000000000000000000000..524f3789ac31214768f939b7e713904f7f1e9792 --- /dev/null +++ b/virtrust/CLAUDE.md @@ -0,0 +1,148 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is the **virtrust** project - a TSB (Trusted Security Boot) Agent for virtualized Trusted Computing Module (vTPCM) support on openEuler 24.03 LTS SP3. The project provides trusted computing virtualization capabilities with focus on virtual machine domain management and trust measurement. + +## Build System + +This project uses CMake with a custom dependency management system. + +### Build Commands + +```bash +# Configure build (Release build by default) +mkdir build && cd build +cmake .. + +# Configure with specific build type +cmake -DCMAKE_BUILD_TYPE=Debug .. +cmake -DCMAKE_BUILD_TYPE=Coverage .. +cmake -DCMAKE_BUILD_TYPE=Asan .. + +# Configure options +cmake -DBUILD_TEST=On .. # Enable tests (default: On) +cmake -DUSE_MOCK_TSB_AGENT=On .. # Use mock TSB agent (default: On, DO NOT USE IN PRODUCTION) + +# Build +cmake --build . + +# Run all tests +ctest --output-on-failure + +# Run single test (after build) +./build/bin/custom_logger_test + +# Format code +./format-all.sh + +# Generate coverage report (when built with Coverage type) +make coverage + +# Build script alternative +./build.sh # Build with Release configuration +./build.sh cicd_default # Same as above +``` + +### Key Build Targets + +- `virtrust-shared` - Main shared library +- `virtrust-obj` - Object library containing all components +- `mock-tsb-agent` - Mock TSB agent implementation for testing + +## Project Structure + +### Core Components + +- **src/virtrust/** - Main library implementation + - `api/` - Public API including domain management (`domain.cpp`, `context.cpp`) + - `base/` - Core utilities (logging, exceptions, string utils) + - `crypto/` - Cryptographic implementations (SM3 hash) + - `dllib/` - Dynamic library loading + - `link/` - Linking functionality + - `utils/` - Additional utilities + +- **src/mock/** - Mock TSB agent implementation + - `tsb_agent_itf.h` - TSB agent interface definitions + - `tsb_agent_impl.cpp` - Mock implementation + - `tsb_agent_adaptor.cpp` - Adaptation layer + +- **src/virtrust-sh/** - Shell interface components +- **src/libvirtrustd/** - Daemon library components + +### Testing Infrastructure + +Tests are co-located with source files (e.g., `domain_test.cpp` alongside `domain.cpp`). The project uses custom CMake macros for test creation: + +- `add_virtrust_test_if()` - For standard library tests +- `add_virtrust_sh_test_if()` - For shell interface tests +- `add_libvirtrustd_test_if()` - For daemon library tests + +### Dependencies + +Dependencies are managed through the CMake deps system in `cmake/deps/`: +- OpenSSL (crypto) +- libboundscheck (security) +- spdlog (logging) +- gtest (testing) +- rapidjson (JSON parsing) + +Dependencies are automatically downloaded and built as part of the CMake configuration process. + +## Key APIs and Concepts + +### Domain Management +The project provides virtual domain lifecycle management through the API in `src/virtrust/api/`: +- Domain creation, start, stop, destroy operations +- Domain listing with filtering (active/inactive) +- Trust measurement and verification for VMs + +### TSB Agent Interface +The TSB agent interface (`src/mock/tsb_agent_itf.h`) defines: +- Virtual TPM (vTPCM) management functions +- Trust measurement and reporting +- Migration support for trusted VMs +- Security policy management + +### Security Architecture +- SM3 cryptographic hash implementation +- Trust chain validation (BIOS → bootloader → kernel → TSB) +- Memory safety through bounds checking +- Secure logging and exception handling + +## Development Notes + +- **Mock vs Production**: Default build uses `USE_MOCK_TSB_AGENT=On` for development. Production builds must set this to Off. +- **Memory Management**: TSB agent interface uses malloc/free - remember to free allocated memory. +- **Error Handling**: Comprehensive error codes defined in `tsb_agent_itf.h` and `api/defines.h`. +- **Logging**: Custom logging adaptation in `base/` with spdlog backend. +- **Standards**: C17 and C++17 standards are enforced. + +## Testing + +Tests use gtest framework and can be run with `ctest`. The build automatically sets up proper library paths for test execution using environment variables. + +### Test Structure +- Tests are co-located with source files (e.g., `domain_test.cpp` alongside `domain.cpp`) +- Individual test executables are built in `build/bin/` directory +- Test certificates are auto-generated during build using OpenSSL + +### Running Tests +```bash +# Run all tests +ctest --output-on-failure + +# Run specific test +./build/bin/custom_logger_test +./build/bin/domain_test +``` + +Coverage reporting is available with `cmake -DCMAKE_BUILD_TYPE=Coverage` and `make coverage`. + +## Code Formatting + +The project includes automated code formatting: +- `./format-all.sh` - Formats C++ and CMake files using clang-format and cmake-format +- `.clang-format` configuration defines code style rules diff --git a/virtrust/CMakeLists.txt b/virtrust/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..162e9c1b8b45256553d7d66be031fb55cabd5db6 --- /dev/null +++ b/virtrust/CMakeLists.txt @@ -0,0 +1,192 @@ +cmake_minimum_required(VERSION 3.22) +project(virtrust CXX C) + +option(BUILD_TEST "Enable/Disable tests" On) +option(USE_MOCK_TSB_AGENT "Use Mocked Tsb Agent (DO NOT USE IN PRODUCTION)" On) + +set(USER_DEPS_DIR + "${PROJECT_SOURCE_DIR}/external" + CACHE + STRING + "Pre-Build Dependency Directory, default to ${PROJECT_SOURCE_DIR}/external" +) + +if(NOT BUILD_TEST AND CMAKE_BUILD_TYPE STREQUAL "Asan") + message( + WARNING + "CMAKE_BUILD_TYPE is Asan but BUILD_TEST has been set to Off, turn on BUILD_TEST automatically." + ) + set(BUILD_TEST On) +endif() + +if(NOT BUILD_TEST AND CMAKE_BUILD_TYPE STREQUAL "Coverage") + message( + WARNING + "CMAKE_BUILD_TYPE is Coverage but BUILD_TEST has been set to Off, turn on BUILD_TEST automatically." + ) + set(BUILD_TEST On) +endif() + +if(NOT BUILD_TEST AND CMAKE_BUILD_TYPE STREQUAL "Fuzz") + message( + WARNING + "CMAKE_BUILD_TYPE is Fuzz but BUILD_TEST has been set to Off, turn on BUILD_TEST automatically." + ) + set(BUILD_TEST On) + message(FATAL "Fuzz is not currently supported!") +endif() + +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE + "Release" + CACHE + STRING + "Choose the type of build, e.g. Debug, Release, Coverage, Asan, Fuzz" + FORCE) + message( + WARNING + "CMAKE_BUILD_TYPE not specified, defaulting to '${CMAKE_BUILD_TYPE}'") +endif() + +if(USE_MOCK_TSB_AGENT) + add_compile_definitions(USE_MOCK_TSB_AGENT) + if(CMAKE_BUILD_TYPE STREQUAL "Release") + message( + WARNING + "USE_MOCK_TSB_AGENT has been set to On while building with Release, please make sure this is intentional." + ) + endif() +endif() + +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set_property(CACHE CMAKE_INSTALL_PREFIX PROPERTY VALUE ${PROJECT_BINARY_DIR}) + message( + WARNING + "CMAKE_INSTALL_PREFIX not specified, defaulting to '${PROJECT_BINARY_DIR}'" + ) +endif() + +cmake_policy(GET CMP0097 NEW) + +set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/") +set(CMAKE_EXPORT_COMPILE_COMMANDS On) + +include(GNUInstallDirs) + +set(CMAKE_DEPS_PREFIX ${CMAKE_BINARY_DIR}/deps) +set(CMAKE_DEPS_SRCDIR ${CMAKE_DEPS_PREFIX}/src) +set(CMAKE_DEPS_LIBDIR ${CMAKE_DEPS_PREFIX}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_DEPS_BINDIR ${CMAKE_DEPS_PREFIX}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_DEPS_INCLUDEDIR ${CMAKE_DEPS_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}) + +# Explicitly create build/deps directory +file(MAKE_DIRECTORY ${CMAKE_DEPS_SRCDIR}) +file(MAKE_DIRECTORY ${CMAKE_DEPS_LIBDIR}) +file(MAKE_DIRECTORY ${CMAKE_DEPS_BINDIR}) +file(MAKE_DIRECTORY ${CMAKE_DEPS_INCLUDEDIR}) + +set(CMAKE_C_STANDARD 17) +set(CMAKE_CXX_STANDARD 17) + +set(CMAKE_POSITION_INDEPENDENT_CODE On) + +set(CMAKE_CXX_FLAGS_RELEASE "") +set(CMAKE_CXX_FLAGS_DEBUG "") + +include(SetToolchainFlags) +set_toolchain_flags() + +# HACK compiler flags, try remove this in the future +add_compiler_flags(-Wno-missing-field-initializers) # for dllib guestfs +add_compiler_flags(-Wno-unused-parameter) # for tsb interface +add_compiler_flags(-Wno-deprecated-declarations) # rapidjson headers +add_compiler_flags(-Wno-error=pragmas) # rapidjson headers +add_compiler_flags(-Wno-class-memaccess) # rapidjson headers +add_compiler_flags(-Wno-implicit-fallthrough) # rapidjson headers +add_compiler_flags(-Wno-template-body) # rapidjson headers + +get_property( + virtrust_link_options + DIRECTORY + PROPERTY LINK_OPTIONS) + +message(STATUS "=============================================================") +message(STATUS "User Options and Configurations") +message(STATUS "=============================================================") +message(STATUS "CMake Version :${CMAKE_VERSION}") +message(STATUS "Build Type :${CMAKE_BUILD_TYPE}") +message(STATUS "CPU Type :${CMAKE_SYSTEM_PROCESSOR}") +message(STATUS "Compiler :${CMAKE_CXX_COMPILER_ID}") +message(STATUS "Compiler Version :${CMAKE_CXX_COMPILER_VERSION}") +message(STATUS "C Standard :${CMAKE_C_STANDARD}") +message(STATUS "C++ Standard :${CMAKE_CXX_STANDARD}") +message(STATUS "Compiler Flags :\n${CMAKE_CXX_FLAGS}") +message(STATUS "Linker Flags :\n${virtrust_link_options}") +message(STATUS "Exe Linker Flags :\n${CMAKE_EXE_LINKER_FLAGS}") +message(STATUS "CMAKE_INSTALL_PREFIX :${CMAKE_INSTALL_PREFIX}") +message(STATUS "CMAKE_DEPS_SRCDIR :${CMAKE_DEPS_SRCDIR}") +message(STATUS "(opt) BUILD_TEST :${BUILD_TEST}") +message(STATUS "(opt) USE_MOCK_TSB_AGENT :${USE_MOCK_TSB_AGENT}") + +include(FetchContent) +include(ExternalProject) + +set(FETCHCONTENT_BASE_DIR ${CMAKE_DEPS_PREFIX}/src) + +include(ImportLibs) +include(deps/openssl) +include(deps/libboundscheck) +include(deps/spdlog) +include(deps/gtest) +include(deps/rapidjson) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY + ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY + ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) +set(CMAKE_INCLUDE_OUTPUT_DIRECTORY + ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIRDIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY + ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}) + +include(AddVirtrustTestIf) + +if(BUILD_TEST) + include(CTest) + enable_testing() + list(APPEND CMAKE_CTEST_ARGUMENTS "--output-on-failure") +endif() + +add_subdirectory(src) + +if(BUILD_TEST) + add_subdirectory(test) +endif() + +if(CMAKE_BUILD_TYPE STREQUAL "Coverage") + find_program(LCOV_PATH lcov) + find_program(GENHTML_PATH genhtml) + if(LCOV_PATH AND GENHTML_PATH) + add_custom_target( + coverage + COMMAND + ${LCOV_PATH} --capture --directory . --exclude "build/*" --exclude + "external/*" --exclude "/usr/*" --output-file coverage.info + --ignore-errors mismatch,inconsistent,unused + COMMAND ${GENHTML_PATH} coverage.info --output-directory + ${CMAKE_BINARY_DIR}/coverage_report --ignore-errors inconsistent + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Generating code coverage report..." + VERBATIM) + else() + add_custom_target( + coverage + COMMAND ${CMAKE_COMMAND} -E echo + "lcov and/or genhtml not found. Generating gcov files instead." + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/gcov_report + COMMAND find src -name "*.gcda" -exec gcov -pb {} + + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Generating gcov coverage report..." + VERBATIM) + endif() +endif() diff --git a/virtrust/README.md b/virtrust/README.md new file mode 100644 index 0000000000000000000000000000000000000000..6d2b216608215cadbc8d6df75a8e903717a9fe25 --- /dev/null +++ b/virtrust/README.md @@ -0,0 +1,332 @@ +# TSB-agent/virtrust + +A Trusted Security Boot (TSB) Agent that provides virtualized Trusted Computing Module (vTPCM) support for openEuler 24.03 LTS SP3. This project enables trusted computing virtualization capabilities with a focus on virtual machine domain management and trust measurement. + +## Project Overview + +TSB-agent/virtrust is a sophisticated trusted computing solution for virtualized environments that implements: + +- **Virtualized Trusted Computing Module (vTPCM)** management +- **Trust Chain Validation** for complete boot chain measurement and verification +- **Secure VM Migration** with encrypted certificate verification +- **Security Policy Management** for configurable security controls +- **Domain Management** for virtual machine lifecycle operations + +The project is particularly focused on Chinese cryptographic standards (SM3) and openEuler integration, providing a comprehensive security architecture for virtualized environments. + +## Architecture + +### Project Structure + +``` +TSB-agent/virtrust/ +├── cmake/ # 构建系统配置 +│ ├── AddVirtrustTestIf.cmake # 测试配置脚本 +│ ├── ImportLibs.cmake # 库导入配置 +│ └── SetToolchainFlags.cmake # 工具链配置 +├── docs/ # 项目文档 +│ ├── 001-introduction.md # 项目介绍 +│ ├── 002-virtrust-api.md # API文档 +│ ├── 003-virtrust-sh.md # Shell接口文档 +│ └── 004-virtrustd.md # 守护进程文档 +├── src/ # 源代码目录 +│ ├── libvirtrustd/ # 守护进程库 +│ │ ├── defines.h # 定义文件 +│ │ ├── main.cpp # 主程序 +│ │ ├── utils.cpp/.h # 工具函数 +│ │ └── CMakeLists.txt # 构建配置 +│ ├── tsb_agent/ # TSB代理模块 +│ │ ├── mock/ # 模拟实现 +│ │ │ ├── tsb_agent_adaptor.cpp # 适配器实现 +│ │ │ ├── tsb_agent_impl.cpp/.h # 代理实现 +│ │ │ ├── tsb_agent_impl_test.cpp # 单元测试 +│ │ │ ├── tsb_agent_test.cpp # 代理测试 +│ │ │ └── v_root.h # 虚拟根定义 +│ │ ├── tsb_agent.h # 代理头文件 +│ │ └── CMakeLists.txt # 构建配置 +│ ├── virtrust/ # 核心库实现 +│ │ ├── api/ # 公共API接口 +│ │ │ ├── context.cpp/.h # API上下文管理 +│ │ │ ├── define_private.h # 私有定义 +│ │ │ ├── defines.h # 公共定义 +│ │ │ ├── domain.cpp/.h # 虚拟机域生命周期操作 +│ │ │ ├── domain_test.cpp # 域操作测试 +│ │ │ ├── file_lock.h # 文件锁实现 +│ │ │ └── CMakeLists.txt # 构建配置 +│ │ ├── base/ # 核心工具库 +│ │ │ ├── custom_logger.cpp/.h # 高性能日志系统 +│ │ │ ├── custom_logger_test.cpp # 日志测试 +│ │ │ ├── exception.cpp/.h # 异常处理框架 +│ │ │ ├── exception_test.cpp # 异常测试 +│ │ │ ├── log_adapt.cpp/.h # 日志适配层 +│ │ │ ├── log_adapt_test.cpp # 日志适配测试 +│ │ │ ├── logger.h # 日志器定义 +│ │ │ ├── str_utils.cpp/.h # 字符串工具 +│ │ │ ├── str_utils_test.cpp # 字符串工具测试 +│ │ │ └── CMakeLists.txt # 构建配置 +│ │ ├── crypto/ # 加密算法实现 +│ │ │ ├── sm3.cpp/.h # 国密SM3算法 +│ │ │ ├── sm3_test.cpp # SM3算法测试 +│ │ │ └── CMakeLists.txt # 构建配置 +│ │ ├── dllib/ # 动态库加载抽象 +│ │ │ ├── common.h # 公共定义 +│ │ │ ├── libguestfs_defines.h # libguestfs定义 +│ │ │ ├── libguestfs.h # libguestfs接口 +│ │ │ ├── libguestfs_test.cpp # libguestfs测试 +│ │ │ ├── libvirt_defines.h # libvirt定义 +│ │ │ ├── libvirt.h # libvirt接口 +│ │ │ ├── libvirt_test.cpp # libvirt测试 +│ │ │ ├── libxml2_defines.h # libxml2定义 +│ │ │ ├── libxml2.h # libxml2接口 +│ │ │ ├── libxml2_test.cpp # libxml2测试 +│ │ │ ├── openssl_defines.h # OpenSSL定义 +│ │ │ ├── openssl.h # OpenSSL接口 +│ │ │ ├── openssl_test.cpp # OpenSSL测试 +│ │ │ ├── dllib_test.cpp # 动态库测试 +│ │ │ └── CMakeLists.txt # 构建配置 +│ │ ├── link/ # 链接功能模块 +│ │ │ ├── proto/ # 协议定义 +│ │ │ │ ├── migrate.grpc.pb.cc/.h # gRPC迁移协议 +│ │ │ │ ├── migrate.pb.cc/.h # 迁移协议 +│ │ │ │ ├── migrate.proto # 协议定义文件 +│ │ │ │ └── proto_tools.h # 协议工具 +│ │ │ ├── grpc_client.cpp/.h # gRPC客户端 +│ │ │ ├── grpc_client_test.cpp # gRPC客户端测试 +│ │ │ ├── grpc_server.cpp/.h # gRPC服务器 +│ │ │ ├── grpc_server_test.cpp # gRPC服务器测试 +│ │ │ ├── link_config_builder.h # 链接配置构建器 +│ │ │ ├── link_test.cpp # 链接测试 +│ │ │ ├── migration_service_impl.cpp/.h # 迁移服务实现 +│ │ │ ├── migration_service_impl_test.cpp # 迁移服务测试 +│ │ │ ├── migration_session.cpp/.h # 迁移会话管理 +│ │ │ ├── migration_session_test.cpp # 迁移会话测试 +│ │ │ ├── proto_tools_test.cpp # 协议工具测试 +│ │ │ ├── defines.h # 链接模块定义 +│ │ │ └── CMakeLists.txt # 构建配置 +│ │ ├── utils/ # 工具函数模块 +│ │ │ ├── async_timer.h # 异步定时器 +│ │ │ ├── async_timer_test.cpp # 异步定时器测试 +│ │ │ ├── enum_check.h # 枚举检查工具 +│ │ │ ├── file_io.cpp/.h # 文件I/O操作 +│ │ │ ├── file_io_test.cpp # 文件I/O测试 +│ │ │ ├── foreign_mounter.cpp/.h # 外部文件系统挂载 +│ │ │ ├── foreign_mounter_test.cpp # 外部挂载测试 +│ │ │ ├── migrate_helper.cpp/.h # 迁移辅助工具 +│ │ │ ├── migrate_helper_test.cpp # 迁移辅助测试 +│ │ │ ├── smart_deleter.h # 智能删除器 +│ │ │ ├── virt_xml_parser.cpp/.h # 虚拟化XML解析器 +│ │ │ ├── virt_xml_parser_test.cpp # XML解析器测试 +│ │ │ └── CMakeLists.txt # 构建配置 +│ │ └── CMakeLists.txt # 主构建配置 +│ ├── virtrust-sh/ # Shell接口 +│ │ ├── operator/ # 命令操作符 +│ │ │ ├── op_create.cpp/.h # 域创建操作 +│ │ │ ├── op_create_test.cpp # 创建操作测试 +│ │ │ ├── op_destroy.cpp/.h # 域销毁操作 +│ │ │ ├── op_destroy_test.cpp # 销毁操作测试 +│ │ │ ├── op_itf.cpp/.h # 操作接口 +│ │ │ ├── op_list.cpp/.h # 域列表操作 +│ │ │ ├── op_list_test.cpp # 列表操作测试 +│ │ │ ├── op_migrate.cpp/.h # 域迁移操作 +│ │ │ ├── op_migrate_test.cpp # 迁移操作测试 +│ │ │ ├── op_start.cpp/.h # 域启动操作 +│ │ │ ├── op_start_test.cpp # 启动操作测试 +│ │ │ ├── op_undefine.cpp/.h # 域取消定义操作 +│ │ │ ├── op_undefine_test.cpp # 取消定义测试 +│ │ │ ├── op_utils.h # 操作工具函数 +│ │ │ └── CMakeLists.txt # 构建配置 +│ │ ├── defines.h # Shell定义 +│ │ ├── main.cpp # 主程序入口 +│ │ └── CMakeLists.txt # 构建配置 +│ └── CMakeLists.txt # 主源码构建配置 +├── test/ # 测试基础设施 +│ ├── ca/ # 证书颁发机构 +│ │ ├── cert.pem # CA证书 +│ │ ├── cert.srl # 证书序列号 +│ │ └── sk.pem # CA私钥 +│ ├── client/ # 客户端证书 +│ │ ├── cert.pem # 客户端证书 +│ │ ├── client.csr # 客户端证书签名请求 +│ │ └── sk.pem # 客户端私钥 +│ ├── data/ # 测试数据 +│ │ ├── config.json # 配置文件 +│ │ ├── grub.cfg # GRUB配置 +│ │ ├── test.txt # 测试文本 +│ │ └── test.xml # 测试XML +│ ├── server/ # 服务器证书 +│ │ ├── cert.pem # 服务器证书 +│ │ ├── server.csr # 服务器证书签名请求 +│ │ └── sk.pem # 服务器私钥 +│ └── CMakeLists.txt # 测试构建配置 +├── build.sh # 构建脚本 +├── CLAUDE.md # Claude AI助手文档 +├── CMakeLists.txt # 主构建配置 +├── format-all.sh # 代码格式化脚本 +├── README.md # 项目说明文档 +└── transcript.txt # 项目记录文档 +``` + +### Core Components + +## External Dependencies +- **OpenSSL 3.3.2** - Cryptographic operations (built statically) +- **libboundscheck** - Memory safety and bounds checking +- **RapidJSON** - JSON parsing and generation +- **libvirt** - Virtualization API integration +- **libguestfs** - Guest filesystem access +- **libxml2** - XML processing + +## Features + +### Domain Management API +- **VM Lifecycle**: Create, start, stop, destroy, migrate, list virtual machine domains +- **Trust Measurement**: Boot chain validation and measurement verification +- **Security Policy**: Configurable security policies and controls +- **Resource Management**: Memory, CPU, and storage resource allocation + +### vTPCM Management +- **Virtual TPM**: Creation, startup, stop, and removal of virtual TPM instances +- **Trust Reporting**: Generation and verification of trust reports +- **Migration Support**: Secure migration of trusted VMs between hosts +- **Policy Control**: Security policy enforcement and management + +### Command Line Interface +- **virtrust-sh**: Interactive shell for domain management operations +- **Operators**: Specialized commands for different operations +- **Batch Processing**: Support for scriptable operations + +### Security Architecture +- **Trust Chain Validation**: BIOS → bootloader → kernel → TSB validation +- **Memory Safety**: Bounds checking and secure memory management +- **Cryptographic Security**: SM3 hash algorithm implementation +- **Secure Migration**: Encrypted VM migration with certificate verification + +## Building from Source + +### Prerequisites +- **openEuler 24.03 LTS SP3** or compatible Linux distribution +- **CMake 3.14.1+** +- **GCC 8+** or **Clang 10+** with C++17 support +- **Git** + +### Build Commands + +```bash +# Clone the repository +git clone https://gitee.com/jamie-cui/TSB-agent.git +cd TSB-agent/virtrust + +# Configure build (Release mode with tests) +cmake -B build -DCMAKE_BUILD_TYPE=Release -DENABLE_TESTING=ON + +# Build all components +cmake --build build -- -j$(nproc) + +# Run tests +cd build +ctest --output-on-failure + +# Install (optional) +sudo cmake --install build +``` + +### Build Options + +| Option | Description | Default | +|--------|-------------|---------| +| `CMAKE_BUILD_TYPE` | Build configuration (Debug/Release/RelWithDebInfo) | Release | +| `ENABLE_TESTING` | Enable unit tests | ON | +| `ENABLE_COVERAGE` | Enable code coverage reporting | OFF | + +### Memory Safety + +The project includes comprehensive bounds checking: + +```bash +# Build with libboundscheck +cmake -B build -DENABLE_BOUNDS_CHECK=ON +cmake --build build + +# Run with bounds checking +LD_LIBRARY_PATH=/path/to/libboundscheck ./build/bin/virtrust-sh +``` + +## Testing + +### Unit Tests +```bash +# Run all tests +cd build +ctest + +# Run specific test suite +./bin/custom_logger_test +./bin/domain_test +./bin/sm3_test +``` + +### Coverage Report +```bash +# Enable coverage +cmake -B build -DENABLE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug +cmake --build build +ctest + +# Generate coverage report +lcov --capture --directory build --output-file coverage.info +genhtml coverage.info --output-directory coverage_report +``` + +### Code Formatting +```bash +# Format all source code +./format-all.sh + +# Or use clang-format directly +find src -name "*.cpp" -o -name "*.h" | xargs clang-format -i +``` + +## Security Considerations + +### Trust Chain Validation +The system implements complete trust chain validation: +1. **BIOS/UEFI** measurements +2. **Bootloader** integrity verification +3. **Kernel** module verification +4. **TSB Agent** validation +5. **Application** layer measurements + +### Memory Safety +- Comprehensive bounds checking with libboundscheck +- Secure memory allocation and deallocation +- Protection against buffer overflows and memory corruption +- Automatic memory leak detection in debug builds + +### Cryptographic Security +- SM3 hash algorithm implementation for Chinese cryptographic standards +- Certificate-based authentication for migration +- Encrypted communication channels +- Secure key storage and management + +## Contributing + +### Development Workflow +1. Fork the repository +2. Create a feature branch (`git checkout -b feature/amazing-feature`) +3. Make your changes with proper tests +4. Ensure code formatting (`./format-all.sh`) +5. Run tests (`ctest --output-on-failure`) +6. Submit a pull request + +### Code Style +- Follow Google C++ Style Guide +- Use clang-format for consistent formatting +- Include comprehensive unit tests +- Document public APIs with Doxygen +- Use meaningful commit messages + +### Testing Requirements +- All new features must include unit tests +- Maintain code coverage above 80% +- Test both positive and negative scenarios +- Include integration tests for complex workflows diff --git a/virtrust/build.sh b/virtrust/build.sh new file mode 100755 index 0000000000000000000000000000000000000000..9c707e14ada85bc3a9077d0e9df0bd9eb622f56e --- /dev/null +++ b/virtrust/build.sh @@ -0,0 +1,110 @@ +#!/bin/bash + +# +# Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. +# + +### +### build.sh --- build project +### Usage: +### build.sh [-D] [-C] [-t ] +### Options: +### Build target useby Make +### -h, --help show this help message and exit +### -t || --target Specifying build target, default is `all` +### Support targets: +### cicd_default: build default target + + +# 函数内命令(后台命令) 失败时退出脚本 +#set -o errtrace +# 脚本内命令(前台命令)失败时,立即退出脚本 +#set -o errexit + +build_target='cicd_default' +build_type='Release' +build_asan='Off' +enable_test='On' + +# 获取项目根目录(目前为构建脚本所在目录) +PROJECT_ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +OUTPUT_DIR=${PROJECT_ROOT_DIR}/output + +echo "PROJECT_ROOT_DIR $PROJECT_ROOT_DIR" + +# 日志打印辅助函数 +function log_info() { + if [ $# -lt 1 ]; then + return + fi + + echo "$(date +"%F %T") [INFO] $*" +} + +function help() { + sed -rn 's/^### ?//;T;p;' "$0" +} + +# 解析命令行参数 +function parse_args() { + while [[ $# -gt 0 ]]; do + case "$1" in + -h | --help) + help + exit + ;; + -t | --target) + if [[ $# -gt 1 && "$2" != "-"* ]]; then + build_target="$2" + shift 2 + else + log_info "Error: Argument required after -t||--target." + exit 1 + fi + ;; + *) + [ "$1" != ""] && build_target="$1" + shift + ;; + esac + done +} + + +function build_output() { + log_info "***** start build cmake ${OUTPUT_DIR}*****" + mkdir -p build + pushd build + cmake .. -DCMAKE_BUILD_TYPE=${build_type} \ + -DBUILD_TEST=${enable_test}\ + -DUSE_MOCK_TSB_AGENT=On \ + -DCMAKE_INSTALL_PREFIX=${OUTPUT_DIR}/virtrust \ + make + make install + popd +} + +function build_cmake() { + log_info "***** start build cmake *****" + log_info "building target ${build_target}" + if [[ "${build_target}" == "cicd_default" ]]; then + build_type='Release' + enable_test='Off' + build_output + fi + + local ret=$? + if [[ $ret -ne 0 ]]; then + log_info "***** build cmake failed *****" + echo_failure + exit 1 + fi +} + +echo $(date +"%Y-%m-%d %H-%M"): "$0" "$@" +START_TIME=$(date +%s.%N) + +cd ${PROJECT_ROOT_DIR} + +parse_args "$@" +build_cmake diff --git a/virtrust/cmake/AddVirtrustTestIf.cmake b/virtrust/cmake/AddVirtrustTestIf.cmake new file mode 100644 index 0000000000000000000000000000000000000000..3ea6cc8ec2e56e3cd6035c5e55a262eda4c3f835 --- /dev/null +++ b/virtrust/cmake/AddVirtrustTestIf.cmake @@ -0,0 +1,81 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + +macro(add_virtrust_test_if NAME) + if(BUILD_TEST) + add_executable(${NAME} ${NAME}.cpp) + target_link_libraries(${NAME} PRIVATE virtrust-shared Deps::gtest) + add_test(NAME ${NAME} COMMAND ${NAME}) + target_include_directories( + ${NAME} + PRIVATE $ + ${CMAKE_BINARY_DIR}/src/virtrust # for protobuf + ${CMAKE_BINARY_DIR}/src # for protobuf + ${CMAKE_DEPS_INCLUDEDIR}) + set_tests_properties( + ${NAME} + PROPERTIES + WORKING_DIRECTORY + ${CMAKE_BINARY_DIR} + ENVIRONMENT + "LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}:${CMAKE_DEPS_LIBDIR}:$ENV{LD_LIBRARY_PATH}" + ) + # Set RPATH for the test executable + set_target_properties( + ${NAME} + PROPERTIES INSTALL_RPATH + "${CMAKE_LIBRARY_OUTPUT_DIRECTORY};${CMAKE_DEPS_LIBDIR}" + BUILD_WITH_INSTALL_RPATH TRUE) + endif() +endmacro() + +macro(add_virtrust_sh_test_if NAME) + if(BUILD_TEST) + add_executable(${NAME} ${NAME}.cpp) + target_link_libraries(${NAME} PRIVATE virtrust-sh-obj virtrust-shared + Deps::gtest) + add_test(NAME ${NAME} COMMAND ${NAME}) + target_include_directories( + ${NAME} PRIVATE $ + ${CMAKE_DEPS_INCLUDEDIR}) + set_tests_properties( + ${NAME} + PROPERTIES + WORKING_DIRECTORY + ${CMAKE_BINARY_DIR} + ENVIRONMENT + "LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}:${CMAKE_DEPS_LIBDIR}:$ENV{LD_LIBRARY_PATH}" + ) + # Set RPATH for the test executable + set_target_properties( + ${NAME} + PROPERTIES INSTALL_RPATH + "${CMAKE_LIBRARY_OUTPUT_DIRECTORY};${CMAKE_DEPS_LIBDIR}" + BUILD_WITH_INSTALL_RPATH TRUE) + endif() +endmacro() + +macro(add_libvirtrustd_test_if NAME) + if(BUILD_TEST) + add_executable(${NAME} ${NAME}.cpp) + target_link_libraries(${NAME} PRIVATE libvirtrustd-obj virtrust-shared + Deps::gtest) + add_test(NAME ${NAME} COMMAND ${NAME}) + target_include_directories( + ${NAME} PRIVATE $ + ${CMAKE_DEPS_INCLUDEDIR}) + set_tests_properties( + ${NAME} + PROPERTIES + WORKING_DIRECTORY + ${CMAKE_BINARY_DIR} + ENVIRONMENT + "LD_LIBRARY_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}:${CMAKE_DEPS_LIBDIR}:$ENV{LD_LIBRARY_PATH}" + ) + # Set RPATH for the test executable + set_target_properties( + ${NAME} + PROPERTIES INSTALL_RPATH + "${CMAKE_LIBRARY_OUTPUT_DIRECTORY};${CMAKE_DEPS_LIBDIR}" + BUILD_WITH_INSTALL_RPATH TRUE) + endif() +endmacro() diff --git a/virtrust/cmake/ImportLibs.cmake b/virtrust/cmake/ImportLibs.cmake new file mode 100644 index 0000000000000000000000000000000000000000..ffa6b695f6a7bf43104b5c46555f34804fde12fa --- /dev/null +++ b/virtrust/cmake/ImportLibs.cmake @@ -0,0 +1,19 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + +macro(import_static_lib_from LIBNAME LIB) + add_library(${LIBNAME} STATIC IMPORTED) + set_target_properties( + ${LIBNAME} + PROPERTIES IMPORTED_LOCATION + ${CMAKE_DEPS_LIBDIR}/${LIBNAME}${CMAKE_STATIC_LIBRARY_SUFFIX}) + add_dependencies(${LIBNAME} ${LIB}) +endmacro() + +macro(import_shared_lib_from LIBNAME LIB) + add_library(${LIBNAME} SHARED IMPORTED) + set_target_properties( + ${LIBNAME} + PROPERTIES IMPORTED_LOCATION + ${CMAKE_DEPS_LIBDIR}/${LIBNAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) + add_dependencies(${LIBNAME} ${LIB}) +endmacro() diff --git a/virtrust/cmake/SetToolchainFlags.cmake b/virtrust/cmake/SetToolchainFlags.cmake new file mode 100644 index 0000000000000000000000000000000000000000..1c90b9557d96bfe1ebb7c7bcab7d3c36c049fe16 --- /dev/null +++ b/virtrust/cmake/SetToolchainFlags.cmake @@ -0,0 +1,150 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + +include(CheckCXXCompilerFlag) +include(CheckCompilerFlag) +include(CheckLinkerFlag) + +# CXX Compiler Flags +function(add_compiler_flags flag) + string(FIND "${CMAKE_CXX_FLAGS}" "${flag}" flag_already_set) + if(flag_already_set EQUAL -1) + message(STATUS "Adding CXX compiler flag: ${flag} ...") + check_cxx_compiler_flag("${flag}" flag_supported) + if(flag_supported) + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} ${flag}" + PARENT_SCOPE) + endif() + unset(flag_supported CACHE) + endif() +endfunction() + +# C Compiler Flags +function(add_c_compiler_flags flag) + string(FIND "${CMAKE_CXX_FLAGS}" "${flag}" flag_already_set) + if(flag_already_set EQUAL -1) + message(STATUS "Adding C compiler flag: ${flag} ...") + check_compiler_flag(C "${flag}" flag_supported) + if(flag_supported) + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} ${flag}" + PARENT_SCOPE) + endif() + unset(flag_supported CACHE) + endif() +endfunction() + +# Linker Flags +function(add_linker_flags flag) + get_property( + virtrust_link_options + DIRECTORY + PROPERTY LINK_OPTIONS) + string(FIND "${virtrust_link_options}" "${flag}" flag_already_set) + if(flag_already_set EQUAL -1) + message(STATUS "Adding linker flag: ${flag} ...") + check_linker_flag(CXX "${flag}" flag_supported) + if(flag_supported) + add_link_options(${flag}) + endif() + unset(flag_supported CACHE) + endif() +endfunction() + +# Setup Toolchain + +macro(set_toolchain_flags) + + # do no add runtime path information + if(NOT BUILD_TEST) + set(CMAKE_SKIP_RPATH TRUE) + set(CMAKE_SKIP_BUILD_RPATH TRUE) + endif() + + # all warnings are treated as errors + add_compiler_flags(-Wall) + add_compiler_flags(-Wextra) + add_compiler_flags(-Werror) + + # compiler flags + add_compiler_flags(-pipe) + add_compiler_flags(-fno-common) + add_compiler_flags(-fstrong-eval-order) + add_compiler_flags(-fms-extensions) + add_compiler_flags(-fno-strict-aliasing) + add_compiler_flags(-freg-struct-return) + + # REVIEW additional warnnings + add_compiler_flags(-Winvalid-pch) + add_compiler_flags(-Wunused) + add_compiler_flags(-Wunused-variable) + add_compiler_flags(-Wunused-value) + add_compiler_flags(-Wcast-align) + add_compiler_flags(-Wcast-equal) + add_compiler_flags(-Wwrite-strings) + add_compiler_flags(-Wdata-time) + add_compiler_flags(-Wstrict-prototypes) + add_compiler_flags(-Wdelete-non-virtual-dtor) + add_compiler_flags(-Wtrampolines) + add_compiler_flags(-Woverloaded-virtual) + + # common linker flags (good-to-have) + add_linker_flags(-Wl, -Bsymbolic) + add_linker_flags(-rdynamic) + add_linker_flags(-Wl, --no-undefined) + + # + if(CMAKE_BUILD_TYPE STREQUAL "Release") + add_compiler_flags(-fstrack-protector-strong) + add_compiler_flags(-fPIC) + add_compiler_flags(-fPIE) + add_compiler_flags(-D_FORTIRY_SOURCE=2) + add_compiler_flags(-O2) + add_compiler_flags(-ftrapv) + + add_linker_flags(-pie) + add_linker_flags(-s) + add_linker_flags(-Wl,-z,relro,-z,now) + add_linker_flags(-Wl,-z,noexecstack) + elseif(CMAKE_BUILD_TYPE STREQUAL "Debug") + add_compiler_flags(-g) + elseif(CMAKE_BUILD_TYPE STREQUAL "Coverage") + add_compiler_flags(-g) + + # HACK it's strange that check_cxx_compiler_flags() function fail to add + # --coverage flag, so we add this manually + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftest-coverage") + + # NOTE the following liner flags only work on executables, which does not + # get included in general linker flags + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lgcov") + elseif(CMAKE_BUILD_TYPE STREQUAL "Asan") + add_compiler_flags(-g) + + # https://cmake.org/pipermail/cmake/2019-October/070180.html + set(_saved_CRT ${CMAKE_REQUIRED_LIBRARIES}) + set(CMAKE_REQUIRED_LIBRARIES "-fsanitize=address;asan") + + add_compiler_flags(-fsanitize=address) + add_compiler_flags(-fsanitize=leak) + add_compiler_flags(-fsanitize=undefined) + add_compiler_flags(-fsanitize=pointer-compare) + add_compiler_flags(-fsanitize=pointer-subtract) + + add_linker_flags(-fno-pie) + add_linker_flags(-fsanitize=address) + add_linker_flags(-fsanitize=leak) + add_linker_flags(-fsanitize=undefined) + add_linker_flags(-fsanitize=pointer-compare) + add_linker_flags(-fsanitize=pointer-subtract) + + set(CMAKE_REQUIRED_LIBRARIES ${_saved_CRT}) + elseif(CMAKE_BUILD_TYPE STREQUAL "Fuzz") + # TODO + add_compiler_flags(-g) + endif() + +endmacro() diff --git a/virtrust/cmake/deps/gtest.cmake b/virtrust/cmake/deps/gtest.cmake new file mode 100644 index 0000000000000000000000000000000000000000..aa5f158eab2add1b8527dea87fb1e0addcb9f255 --- /dev/null +++ b/virtrust/cmake/deps/gtest.cmake @@ -0,0 +1,40 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + +ExternalProject_Add( + googletest + URL https://github.com/google/googletest/archive/refs/tags/v1.15.2.tar.gz + URL_HASH + SHA256=7b42b4d6ed48810c5362c265a17faebe90dc2373c885e5216439d37927f02926 + CMAKE_ARGS -DCMAKE_POSITION_INDEPENDENT_CODE=On # + -DCMAKE_CXX_STANDARD=17 # + -DCMAKE_C_STANDARD_REQUIRED=Yes # + -DCMAKE_INSTALL_PREFIX=${CMAKE_DEPS_PREFIX} # + -DBUILD_GMOCK=On # + PREFIX ${CMAKE_DEPS_PREFIX} + UPDATE_COMMAND "" + BUILD_BYPRODUCTS ${CMAKE_DEPS_LIBDIR}/libgtest${CMAKE_STATIC_LIBRARY_SUFFIX} + BUILD_BYPRODUCTS + ${CMAKE_DEPS_LIBDIR}/libgtest_main${CMAKE_STATIC_LIBRARY_SUFFIX} + BUILD_BYPRODUCTS ${CMAKE_DEPS_LIBDIR}/libgmock${CMAKE_STATIC_LIBRARY_SUFFIX} + BUILD_BYPRODUCTS + ${CMAKE_DEPS_LIBDIR}/libgmock_main${CMAKE_STATIC_LIBRARY_SUFFIX} + EXCLUDE_FROM_ALL true + DOWNLOAD_EXTRACT_TIMESTAMP On + LOG_DOWNLOAD On + LOG_CONFIGURE On + LOG_BUILD On + LOG_INSTALL On) + +import_static_lib_from(libgtest googletest) +import_static_lib_from(libgtest_main googletest) +import_static_lib_from(libgmock_main googletest) +import_static_lib_from(libgmock googletest) + +target_link_libraries(libgtest_main INTERFACE libgtest) +target_link_libraries(libgmock_main INTERFACE libgmock) + +# ----------------------------- +# Alias Target for External Use +# ----------------------------- +add_library(Deps::gtest ALIAS libgtest_main) +add_library(Deps::gmock ALIAS libgmock_main) diff --git a/virtrust/cmake/deps/libboundscheck.cmake b/virtrust/cmake/deps/libboundscheck.cmake new file mode 100644 index 0000000000000000000000000000000000000000..561775b7034faa4d2975764427e16f799ff88d32 --- /dev/null +++ b/virtrust/cmake/deps/libboundscheck.cmake @@ -0,0 +1,31 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + +ExternalProject_Add( + libboundscheck-src + GIT_REPOSITORY https://github.com/openeuler-mirror/libboundscheck + GIT_TAG master + PREFIX ${CMAKE_DEPS_PREFIX} + CONFIGURE_COMMAND "" + BUILD_COMMAND ${CMAKE_MAKE_PROGRAM} + UPDATE_COMMAND "" + INSTALL_COMMAND cp include/securec.h ${CMAKE_DEPS_INCLUDEDIR} + COMMAND cp include/securectype.h ${CMAKE_DEPS_INCLUDEDIR} + COMMAND cp lib/libboundscheck${CMAKE_SHARED_LIBRARY_SUFFIX} + ${CMAKE_DEPS_LIBDIR} + BUILD_IN_SOURCE On + EXCLUDE_FROM_ALL true + LOG_DOWNLOAD On + LOG_CONFIGURE On + LOG_BUILD On + LOG_INSTALL On) + +add_library(libboundscheck-itf INTERFACE) +target_link_directories(libboundscheck-itf INTERFACE ${CMAKE_DEPS_LIBDIR}) +target_link_libraries(libboundscheck-itf + INTERFACE libboundscheck${CMAKE_SHARED_LIBRARY_SUFFIX}) +add_dependencies(libboundscheck-itf libboundscheck-src) + +# ----------------------------- +# Alias Target for External Use +# ----------------------------- +add_library(Deps::secure_c ALIAS libboundscheck-itf) diff --git a/virtrust/cmake/deps/openssl.cmake b/virtrust/cmake/deps/openssl.cmake new file mode 100644 index 0000000000000000000000000000000000000000..83f15cb4be98ae0fc5bf98fcd9c1b5cd509680ac --- /dev/null +++ b/virtrust/cmake/deps/openssl.cmake @@ -0,0 +1,34 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + +ExternalProject_Add( + openssl + PREFIX ${CMAKE_DEPS_PREFIX} + URL https://github.com/openssl/openssl/archive/refs/tags/openssl-3.3.2.tar.gz + URL_HASH + SHA256=bedbb16955555f99b1a7b1ba90fc97879eb41025081be359ecd6a9fcbdf1c8d2 + CONFIGURE_COMMAND + ./Configure no-legacy no-weak-ssl-ciphers no-tests no-shared no-ui-console + no-docs no-apps --banner=Finished --release --libdir=${CMAKE_INSTALL_LIBDIR} + --prefix=${CMAKE_DEPS_PREFIX} -w + BUILD_COMMAND make build_sw + UPDATE_COMMAND "" + INSTALL_COMMAND make install_sw + BUILD_IN_SOURCE On + DOWNLOAD_EXTRACT_TIMESTAMP On + BUILD_BYPRODUCTS ${CMAKE_DEPS_LIBDIR}/libcrypto${CMAKE_STATIC_LIBRARY_SUFFIX} + BUILD_BYPRODUCTS ${CMAKE_DEPS_LIBDIR}/libssl${CMAKE_STATIC_LIBRARY_SUFFIX} + EXCLUDE_FROM_ALL true + LOG_DOWNLOAD On + LOG_CONFIGURE On + LOG_BUILD On + LOG_INSTALL On) + +import_static_lib_from(libcrypto openssl) +import_static_lib_from(libssl openssl) + +target_link_libraries(libssl INTERFACE libcrypto) + +# ----------------------------- +# Alias Target for External Use +# ----------------------------- +add_library(Deps::openssl ALIAS libssl) diff --git a/virtrust/cmake/deps/rapidjson.cmake b/virtrust/cmake/deps/rapidjson.cmake new file mode 100644 index 0000000000000000000000000000000000000000..9a4afb2cd59e345706fc856307e7bff27c0dd5a3 --- /dev/null +++ b/virtrust/cmake/deps/rapidjson.cmake @@ -0,0 +1,33 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + +# HACK compiler flags +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=pragmas") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-class-memaccess") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-implicit-fallthrough") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-template-body") + +ExternalProject_Add( + rapidjson + URL https://github.com/Tencent/rapidjson/archive/refs/tags/v1.1.0.tar.gz + URL_HASH + SHA256=bf7ced29704a1e696fbccf2a2b4ea068e7774fa37f6d7dd4039d0787f8bed98e + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_DEPS_PREFIX} + -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DCMAKE_SKIP_RPATH=TRUE + PREFIX ${CMAKE_DEPS_PREFIX} + UPDATE_COMMAND "" + EXCLUDE_FROM_ALL true + DOWNLOAD_EXTRACT_TIMESTAMP On + LOG_DOWNLOAD On + LOG_CONFIGURE On + LOG_BUILD On + LOG_INSTALL On) + +# NOTE rapidjson is a header-only lib +add_library(librapidjson INTERFACE) +target_include_directories(librapidjson INTERFACE ${CMAKE_DEPS_INCLUDEDIR}) +add_dependencies(librapidjson rapidjson) + +# ----------------------------- +# Alias Target for External Use +# ----------------------------- +add_library(Deps::rapidjson ALIAS librapidjson) diff --git a/virtrust/cmake/deps/spdlog.cmake b/virtrust/cmake/deps/spdlog.cmake new file mode 100644 index 0000000000000000000000000000000000000000..90416d05d8a6e38a4049b44042f9c47abfcd7b5f --- /dev/null +++ b/virtrust/cmake/deps/spdlog.cmake @@ -0,0 +1,31 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + +# HACK spdlog installs in lib64 +file(MAKE_DIRECTORY ${CMAKE_DEPS_PREFIX}/lib64) + +ExternalProject_Add( + spdlog + URL https://github.com/gabime/spdlog/archive/refs/tags/v1.14.1.tar.gz + URL_HASH + SHA256=1586508029a7d0670dfcb2d97575dcdc242d3868a259742b69f100801ab4e16b + CMAKE_ARGS -DCMAKE_POSITION_INDEPENDENT_CODE=On + -DCMAKE_CXX_STANDARD=17 + -DCMAKE_C_STANDARD_REQUIRED=Yes + -DCMAKE_INSTALL_PREFIX=${CMAKE_DEPS_PREFIX} + -DCMAKE_CPP_FLAGS=-isystem\ ${CMAKE_DEPS_INCLUDEDIR} + PREFIX ${CMAKE_DEPS_PREFIX} + UPDATE_COMMAND "" + EXCLUDE_FROM_ALL true + DOWNLOAD_EXTRACT_TIMESTAMP On + BUILD_BYPRODUCTS ${CMAKE_DEPS_LIBDIR}/libspdlog${CMAKE_STATIC_LIBRARY_SUFFIX} + LOG_DOWNLOAD On + LOG_CONFIGURE On + LOG_BUILD On + LOG_INSTALL On) + +import_static_lib_from(libspdlog spdlog) + +# ----------------------------- +# Alias Target for External Use +# ----------------------------- +add_library(Deps::spdlog ALIAS libspdlog) diff --git a/virtrust/docs/001-introduction.md b/virtrust/docs/001-introduction.md new file mode 100644 index 0000000000000000000000000000000000000000..b204e8ffdb98569c078993d07776b0ee4dbbc24a --- /dev/null +++ b/virtrust/docs/001-introduction.md @@ -0,0 +1,151 @@ +# 简介 + +virtrust 是一个为 openEuler 24.03 LTS SP3 平台设计的可信安全启动(TSB)代理,提供虚拟化可信计算模块(vTPCM)支持,专注于虚拟机域管理和可信度量功能。本仓库实现了完整的可信虚拟机生命周期管理、安全迁移以及相关工具链。 + +## 项目概述 + +### 核心功能 + +- **可信虚拟机管理**:提供虚拟机完整的生命周期管理,包括创建、启动、停止、销毁和迁移操作 +- **可信计算支持**:基于国密 SM3 算法的信任链验证,支持 vTPCM(虚拟化可信计算模块)管理 +- **安全迁移**:支持虚拟机在不同主机间的安全迁移,具备证书验证和完整性检查 +- **开发工具**:提供命令行工具 virtrust-sh和守护进程 libvirtrustd,方便用户操作和系统集成 + +## 环境要求 + +### 支持的操作系统 +- openEuler 24.03 SP1 +- openEuler 24.03 SP2 + +### 编译依赖 + +```bash +# 基础编译工具 +sudo dnf install gcc g++ cmake make + +# 开发库 +sudo dnf install grpc grpc-devel grpc-plugins protobuf-devel protobuf-compiler +sudo dnf install libboundscheck-devel + +# 运行时依赖 +sudo dnf install libxml2-devel libguestfs-devel openssl-devel libvirt-devel + +# 其他依赖(项目会自动下载) +# - spdlog(日志) +# - gtest(测试框架) +# - rapidjson(JSON解析) +``` + +## 编译指南 + +### 使用 CMake 直接编译 + +```bash +# 创建构建目录 +mkdir -p build && cd build + +# 配置构建(Release 构建) +cmake .. + +# 配置构建(指定构建类型) +cmake -DCMAKE_BUILD_TYPE=Debug .. # 调试构建 +cmake -DCMAKE_BUILD_TYPE=Coverage .. # 覆盖率构建 +cmake -DCMAKE_BUILD_TYPE=Asan .. # 地址消毒构建 + +# 配置选项 +cmake -DBUILD_TEST=On .. # 启用测试(默认开启) +cmake -DUSE_MOCK_TSB_AGENT=Off .. # 生产构建(禁用模拟代理) + +# 编译 +cmake --build . -j$(nproc) + +# 安装 +make install +``` + +### 使用构建脚本 + +```bash +# 默认构建(Release,禁用测试) +./build.sh + +# 指定构建目标 +./build.sh cicd_default +``` + +## 单元测试 + +### 运行所有测试 + +```bash +cd build + +# 运行所有测试 +ctest --output-on-failure + +# 生成覆盖率报告(需要 Coverage 构建) +make coverage +``` + +## 产出物 + +### 库文件 + +- **`libvirtrust.so`** - 主要共享库,提供所有核心功能 +- **`libvirtrust.a`** - 静态库版本(可选) + +### 可执行文件 + +- **`virtrust-sh`** - 命令行工具,用于管理虚拟机 +- **`libvirtrustd`** - 守护进程,提供后台服务 +- **`mock-tsb-agent`** - 模拟 TSB 代理(开发测试用) + +### 测试可执行文件 + +在 `build/bin/` 目录下生成所有测试程序: + +- `domain_test` +- `custom_logger_test` +- `sm3_test` +- `str_utils_test` +- `exception_test` +- 以及其他模块的测试程序 + +### 配置和运行时文件 + +- **日志文件**:`/tmp/virtrust.log` +- **gRPC 套接字**:`/tmp/grpc.sock` +- **覆盖率报告**:`build/coverage/index.html`(Coverage 构建) + +## 开发指南 + +### 代码风格 + +项目使用自动化代码格式化: + +```bash +# 格式化所有代码 +./format-all.sh +``` + +- 使用 clang-format 格式化 C++ 代码 +- 使用 cmake-format 格式化 CMake 文件 +- 配置文件:`.clang-format` + +### 开发模式 vs 生产模式 + +- **开发模式**(默认):`USE_MOCK_TSB_AGENT=On` + - 使用模拟 TSB 代理 + - 启用完整测试套件 + - 便于开发和调试 + +- **生产模式**:`USE_MOCK_TSB_AGENT=Off` + - 使用真实 TSB 代理 + - 禁用测试以减小二进制体积 + - 用于生产环境部署 + +### 调试支持 + +- **Debug 构建**:包含调试信息,支持 gdb +- **Asan 构建**:启用地址消毒,检测内存错误 +- **Coverage 构建**:生成代码覆盖率报告 diff --git a/virtrust/docs/002-virtrust-api.md b/virtrust/docs/002-virtrust-api.md new file mode 100644 index 0000000000000000000000000000000000000000..bf2aae16841d1a1715a56c40bbcf8b568680b37e --- /dev/null +++ b/virtrust/docs/002-virtrust-api.md @@ -0,0 +1,234 @@ +# Virtrust API 接口文档 + +本文档描述了 virtrust 库对外提供的主要 API 接口,这些接口主要用于虚拟机域管理,包括创建、启动、停止、迁移和查询等操作。 + +## 核心数据结构 + +### 连接上下文 (ConnCtx) +- **作用**:表示与 libvirt 的连接上下文 +- **默认 URI**:`qemu:///session` +- **创建方式**:使用 `std::make_unique()` 创建,可通过 `SetUri()` 方法设置连接地址 + +### 返回值 (VirtrustRc) +所有 API 函数都返回 `VirtrustRc` 枚举类型的返回值: +- `OK = 0`:操作成功 +- `ERROR = 1`:一般错误 +- `CHECK_FAILED = 2`:检查失败 +- `INCONSISTENT_RESOURCE = 3`:资源不一致 + +## API 接口详情 + +### 1. DomainCreate - 创建虚拟机 + +```cpp +VirtrustRc DomainCreate(const std::unique_ptr &conn, const std::vector &args); +``` + +**参数说明**: +- `conn`:连接上下文,必须是有效的连接 +- `args`:参数向量,参考 `virt-install --help` 的参数格式 + - `args[0]`:必须为 virt-install 的路径,如 `/usr/bin/virt-install` + - 必须指定虚拟机名称字段 + - `--allow-store-measurements`:可选参数,允许更新 TSB 的度量值 + +**功能描述**: +创建一个新的虚拟机实例。该函数内部调用 virt-install 工具来创建虚拟机,并处理相关的 TSB 资源初始化。 + +**返回值**: +- 成功返回 `VirtrustRc::OK` +- 失败返回相应的错误码 + +**注意事项**: +- 名称字段是必须的 +- 确保 virt-install 路径正确且可执行 +- 支持所有 virt-install 的标准参数 + +### 2. DomainDestroy - 停止虚拟机 + +```cpp +VirtrustRc DomainDestroy(const std::unique_ptr &conn, const std::string &domainName, + unsigned int flags, bool isOnlyTsb = false); +``` + +**参数说明**: +- `conn`:连接上下文 +- `domainName`:虚拟机名称或 UUID + - 当 `isOnlyTsb` 为 true 时,只更新 TSB 相关资源 + - 当 `isOnlyTsb` 为 true 时,使用 UUID 时将忽略 flags 入参 +- `flags`:销毁标志,参考 `DomainDestroyFlags`(当前仅定义 `DOMAIN_DESTROY_NONE = 0`) +- `isOnlyTsb`:是否只更新 TSB 资源的标志 + - `true`:仅更新 TSB 资源,不执行实际的虚拟机销毁 + - `false`:执行完整的虚拟机销毁操作 + +**功能描述**: +停止指定的虚拟机。可选择是否只处理 TSB 资源或执行完整的销毁操作。 + +### 3. DomainMigrate - 迁移虚拟机 + +```cpp +VirtrustRc DomainMigrate(const std::unique_ptr &conn, const std::string &domainName, + const std::string &destUri, unsigned int flags = 0); +``` + +**参数说明**: +- `conn`:连接上下文 +- `domainName`:虚拟机名称 +- `destUri`:目标端地址,格式为 `://:/` + - 示例:`qemu+tls://7.7.7.7:8080/system` +- `flags`:迁移标志 + - 默认为 0:不删除源端虚拟机 + - `MIGRATE_UNDEFINE_SOURCE`:迁移成功后取消定义源端虚拟机 + +**功能描述**: +将虚拟机从当前主机迁移到目标主机。支持安全的迁移过程,包括 TSB 资源的同步。 + +**返回值**: +- 成功返回 `VirtrustRc::OK` +- 失败返回相应的错误码 + +### 4. DomainStart - 启动虚拟机 + +```cpp +VirtrustRc DomainStart(const std::unique_ptr &conn, const std::string &domainName, + unsigned int flags, bool isOnlyTsb = false); +``` + +**参数说明**: +- `conn`:连接上下文 +- `domainName`:虚拟机名称或 UUID + - 当 `isOnlyTsb` 为 true 时,只更新 TSB 相关资源 + - 当 `isOnlyTsb` 为 true 时,使用 UUID 时将忽略 flags 入参 +- `flags`:启动标志,参考 `DomainStartFlags`(当前仅定义 `DOMAIN_START_NONE = 0`) +- `isOnlyTsb`:是否只更新 TSB 资源的标志 + - `true`:仅更新 TSB 资源 + - `false`:执行完整的虚拟机启动操作 + +**功能描述**: +启动指定的虚拟机。可以选择仅处理 TSB 资源或执行完整的启动流程。 + +### 5. DomainUndefine - 删除虚拟机 + +```cpp +VirtrustRc DomainUndefine(const std::unique_ptr &conn, const std::string &domainName, + unsigned int flags = 0, bool isOnlyTsb = false); +``` + +**参数说明**: +- `conn`:连接上下文 +- `domainName`:虚拟机名称或 UUID + - 当 `isOnlyTsb` 为 true 时,只更新 TSB 相关资源 + - 当 `isOnlyTsb` 为 true 时,使用 UUID 时将忽略 flags 入参 +- `flags`:删除标志 + - 默认为 0:适用于不产生 NVRAM 文件的情况 + - `DOMAIN_UNDEFINE_NVRAM`:删除 NVRAM 文件 + - `DOMAIN_UNDEFINE_KEEP_NVRAM`:保留 NVRAM 文件 + - 注意:`DOMAIN_UNDEFINE_NVRAM` 和 `DOMAIN_UNDEFINE_KEEP_NVRAM` 不能同时指定 +- `isOnlyTsb`:是否只删除 TSB 资源 + - `true`:仅删除 TSB 资源 + - `false`:执行完整的虚拟机删除操作 + +**功能描述**: +删除虚拟机的定义。处理 NVRAM 文件和 TSB 资源的清理。 + +### 6. DomainList - 展示虚拟机 + +```cpp +VirtrustRc DomainList(const std::unique_ptr &conn, unsigned int flags, + std::unordered_map &domainInfos, + bool printErrToCli = false); +``` + +**参数说明**: +- `conn`:连接上下文 +- `flags`:列表标志,可组合使用 + - `LIST_DOMAINS_ACTIVE`:列出活动的虚拟机 + - `LIST_DOMAINS_INACTIVE`:列出非活动的虚拟机 + - 示例:`LIST_DOMAINS_ACTIVE | LIST_DOMAINS_INACTIVE` +- `domainInfos`:输出参数,查询到的虚拟机信息映射表 + - 键:虚拟机名称 + - 值:`DomainInfo` 结构体 +- `printErrToCli`:是否在命令行显示 TSB 和 libvirt 资源不一致的错误信息 + - `true`:显示错误信息(注意:libvirt 有但 TSB 没有的情况不会显示,但会有 warn 日志) + - `false`:不显示错误信息 + +**DomainInfo 结构体**: +```cpp +struct DomainInfo { + std::string domainName; // 虚拟机名称 + unsigned char state; // 运行状态,virDomainState 枚举值 + unsigned long maxMem; // 最大允许内存(KB) + unsigned long memory; // 当前使用内存(KB) + unsigned short nrVirtCpu; // 虚拟 CPU 数量 + unsigned long long cpuTime; // CPU 使用时间(纳秒) +}; +``` + +**功能描述**: +查询并列出符合条件的虚拟机信息,同时检查 TSB 资源和 libvirt 资源的一致性。 + +## 使用示例 + +### 基本使用流程 + +```cpp +#include "virtrust/api/domain.h" + +// 创建连接上下文 +auto conn = std::make_unique(); +conn->SetUri("qemu:///session"); + +// 创建虚拟机 +std::vector args = { + "/usr/bin/virt-install", + "--name", "test-vm", + "--memory", "2048", + "--vcpus", "2", + "--disk", "path=/var/lib/libvirt/images/test-vm.qcow2,size=10", + "--cdrom", "/path/to/install.iso", + "--network", "network=default", + "--allow-store-measurements" +}; + +auto result = DomainCreate(conn, args); +if (result != VirtrustRc::OK) { + // 处理错误 +} + +// 启动虚拟机 +result = DomainStart(conn, "test-vm", DOMAIN_START_NONE, false); + +// 查询虚拟机信息 +std::unordered_map domainInfos; +result = DomainList(conn, LIST_DOMAINS_ACTIVE, domainInfos, true); + +// 停止虚拟机 +result = DomainDestroy(conn, "test-vm", DOMAIN_DESTROY_NONE, false); + +// 删除虚拟机 +result = DomainUndefine(conn, "test-vm", 0, false); +``` + +## 错误处理 + +所有 API 函数都返回 `VirtrustRc` 枚举值,建议在调用后检查返回值: + +```cpp +auto rc = DomainCreate(conn, args); +switch (rc) { + case VirtrustRc::OK: + // 操作成功 + break; + case VirtrustRc::ERROR: + // 一般错误 + break; + case VirtrustRc::CHECK_FAILED: + // 检查失败 + break; + case VirtrustRc::INCONSISTENT_RESOURCE: + // 资源不一致 + break; + default: + // 未知错误 + break; +} +``` diff --git a/virtrust/docs/003-virtrust-sh.md b/virtrust/docs/003-virtrust-sh.md new file mode 100644 index 0000000000000000000000000000000000000000..5ca71f079808833b08dba8d4a022cbd5744766da --- /dev/null +++ b/virtrust/docs/003-virtrust-sh.md @@ -0,0 +1,238 @@ +# Virtrust Shell (virtrust-sh) 用户手册 + +## 概述 + +Virtrust Shell (virtrust-sh) 是 virtrust 项目的命令行界面工具,为用户提供了交互式的虚拟机管理功能。它基于 virtrust API 库构建,支持虚拟机的完整生命周期管理操作。 + +- **虚拟机生命周期管理**:创建、启动、停止、销毁、迁移和删除虚拟机 + +## 安装和使用 + +### 基本语法 + +```bash +virtrust-sh [options]... [] +virtrust-sh [options]... [args...] +``` + +### 命令行选项 + +| 选项 | 长选项 | 参数 | 描述 | +|------|--------|------|------| +| `-c` | `--connect=URI` | URI | 指定 hypervisor 连接 URI,默认为 `qemu:///session` | +| `-d` | `--debug` | 无 | 启用调试模式,显示详细日志 | +| `-h` | `--help` | 无 | 显示帮助信息 | +| `-v` | `--version` | 无 | 显示版本信息 | + +### 支持的命令 + +| 命令 | 描述 | +|------|------| +| `create` | 创建虚拟机实例 | +| `destroy` | 销毁(停止)虚拟机域 | +| `list` | 列出虚拟机信息 | +| `migrate` | 迁移虚拟机到其他主机 | +| `start` | 启动(先前定义的)非活动虚拟机域 | +| `undefine` | 取消定义虚拟机域 | + +## 详细命令说明 + +### 1. create - 创建虚拟机 + +创建新的虚拟机实例,基于 libvirt 的 virt-install 工具实现。 + +**基本语法**: +```bash +virtrust-sh create [virt-install 支持的参数...] +``` + +**参数说明**: +- 所有参数将传递给 virt-install 工具 +- 必须包含虚拟机名称参数 +- 支持所有 virt-install 的标准参数 + +**示例**: +```bash +# 创建基础虚拟机 +virtrust-sh create \ + --name test-vm \ + --memory 2048 \ + --vcpus 2 \ + --disk path=/var/lib/libvirt/images/test-vm.qcow2,size=10 \ + --cdrom /path/to/install.iso f + --network network=default + +# 使用自定义连接 URI +virtrust-sh -c qemu+tcp://host/system create \ + --name test-vm \ + --memory 1024 \ + --vcpus 1 \ + --disk path=/tmp/test.img,size=5 +``` + +### 2. start - 启动虚拟机 + +启动之前定义的虚拟机实例。 + +**基本语法**: +```bash +virtrust-sh start +``` + +**参数说明**: +- `domain_name`:要启动的虚拟机名称 + +**示例**: +```bash +# 启动虚拟机 +virtrust-sh start test-vm + +# 使用调试模式启动 +virtrust-sh -d start test-vm +``` + +### 3. destroy - 停止虚拟机 + +强制停止运行中的虚拟机。 + +**基本语法**: +```bash +virtrust-sh destroy +``` + +**参数说明**: +- `domain_name`:要停止的虚拟机名称 + +**示例**: +```bash +# 停止虚拟机 +virtrust-sh destroy test-vm +``` + +### 4. undefine - 删除虚拟机定义 + +删除虚拟机的配置定义,但不会删除磁盘镜像文件。 + +**基本语法**: +```bash +virtrust-sh undefine +``` + +**参数说明**: +- `domain_name`:要删除定义的虚拟机名称 + +**示例**: +```bash +# 删除虚拟机定义 +virtrust-sh undefine test-vm +``` + +### 5. migrate - 迁移虚拟机 + +将虚拟机迁移到其他主机。 + +**基本语法**: +```bash +virtrust-sh migrate [option] +``` + +**参数说明**: +- `domain_name`:要迁移的虚拟机名称 +- `dest_uri`:目标主机 URI,格式为 `://:/` +- `option`:-h 帮助信息,--undefinesource 删除源端虚拟机 + +**示例**: +```bash +# 迁移到远程主机 +virtrust-sh migrate test-vm qemu+tls://192.168.1.100:16509/system + +# 使用 TLS 加密迁移 +virtrust-sh migrate test-vm qemu+tls://dest-host/system +``` + +### 6. list - 列出虚拟机信息 + +显示系统中虚拟机的状态和信息。 + +**基本语法**: +```bash +virtrust-sh list [options] +``` + +**示例**: +```bash +# 列出所有虚拟机 +virtrust-sh list + +# 使用调试模式列出虚拟机 +virtrust-sh -d list +``` + +## 日志管理 + +virtrust-sh 会将详细的操作日志写入当前工作目录下的 `virtrust.log` 文件。 + +## 使用示例 + +### 完整虚拟机生命周期管理 + +```bash +# 1. 创建虚拟机 +virtrust-sh create \ + --name demo-vm \ + --memory 4096 \ + --vcpus 2 \ + --disk path=/var/lib/libvirt/images/demo-vm.qcow2,size=20 \ + --cdrom /tmp/ubuntu-22.04.iso \ + --network network=default \ + --graphics spice + +# 2. 启动虚拟机 +virtrust-sh start demo-vm + +# 3. 查看虚拟机状态 +virtrust-sh list + +# 4. 停止虚拟机 +virtrust-sh destroy demo-vm + +# 5. 删除虚拟机定义 +virtrust-sh undefine demo-vm +``` + +### 批量操作脚本 + +```bash +#!/bin/bash + +# 设置调试模式 +DEBUG_FLAG="-d" + +# 批量启动虚拟机 +for vm in vm1 vm2 vm3; do + echo "Starting $vm..." + virtrust-sh $DEBUG_FLAG start $vm +done + +# 批量列出虚拟机状态 +echo "Virtual machine status:" +virtrust-sh $DEBUG_FLAG list +``` + +### 远程管理示例 + +```bash +# 连接到远程 libvirt 守护进程 +REMOTE_URI="qemu+tcp://192.168.1.100/system" + +# 在远程主机上创建虚拟机 +virtrust-sh -c $REMOTE_URI create \ + --name remote-vm \ + --memory 2048 \ + --vcpus 2 \ + --disk path=/var/lib/libvirt/images/remote-vm.qcow2,size=10 + +# 迁移虚拟机到远程主机 +virtrust-sh migrate local-vm qemu+tls://192.168.1.100/system +``` + diff --git a/virtrust/docs/004-virtrustd.md b/virtrust/docs/004-virtrustd.md new file mode 100644 index 0000000000000000000000000000000000000000..7e2c2c8272c314218217afcafb2e718bd9e824b2 --- /dev/null +++ b/virtrust/docs/004-virtrustd.md @@ -0,0 +1,305 @@ +# Virtrust Daemon (virtrustd) 管理手册 + +## 概述 + +Virtrust Daemon (virtrustd) 是 virtrust 项目的守护进程服务,提供基于 gRPC 的远程 API 服务。它作为后端服务运行,接受来自客户端的虚拟机管理请求,并通过 virtrust API 库执行相应的操作。 + +- **默认服务器地址**:127.0.0.1 +- **默认服务器端口**:5031 +- **默认 Unix Socket**:/tmp/grpc.sock +- **默认日志文件**:/var/log/virtrustd.log + +## 系统架构 + +### 服务组件 + +``` +virtrustd 守护进程 +├── gRPC Server # gRPC 服务器 +├── LinkConfig # 链接配置管理 +├── 信号处理器 # SIGINT, SIGTERM, SIGPIPE 处理 +├── 日志系统 # 服务日志记录 +└── virtrust API # 虚拟机管理 API 调用 +``` + +### 通信流程 + +``` +客户端应用 + ↓ (gRPC/TLS) +virtrustd 守护进程 + ↓ (virtrust API) +libvirt 虚拟化层 +``` + +## 安装和部署 + +### 系统要求 + +- **操作系统**:openEuler 24.03 LTS SP1 或 openEuler 24.03 LTS SP2 +- **权限**:需要足够的权限来管理虚拟机 +- **依赖**:libvirt、gRPC 相关库 + +### 安装步骤 + +1. **编译安装**: +```bash +# 在 virtrust 项目目录下 +cmake -B build -DCMAKE_BUILD_TYPE=Release +cmake --build build + +# 安装服务 +sudo cmake --install build +``` + +2. **创建配置文件**: +```bash +sudo mkdir -p /etc/virtrust +sudo cp config-example.json /etc/virtrust/virtrustd.json +``` + +3. **创建日志目录**: +```bash +sudo mkdir -p /var/log +sudo touch /var/log/virtrustd.log +sudo chmod 644 /var/log/virtrustd.log +``` + +## 配置管理 + +### 基本语法 + +```bash +virtrustd --config [options] +``` + +### 命令行选项 + +| 选项 | 长选项 | 参数 | 描述 | +|------|--------|------|------| +| 无 | `--config` | 文件路径 | 配置文件路径(必需) | +| `-d` | `--debug` | 无 | 启用调试模式 | +| 无 | `--help` | 无 | 显示帮助信息 | +| 无 | `--version` | 无 | 显示版本信息 | + +### 配置文件格式 + +配置文件使用 JSON 格式,包含以下字段: + +```json +{ + "server": { + "addr": "127.0.0.1", + "port": 5031, + "uds_path": "/tmp/grpc.sock" + }, + "tls": { + "ca_path": "ca-cert.pem", + "cert_path": "server-cert.pem", + "key_path": "server-sk.pem" + } +} +``` + +#### 配置字段说明 + +**server 部分**: +- `addr`:服务器监听地址,默认为 "127.0.0.1" +- `port`:服务器监听端口,默认为 5031 +- `uds_path`:Unix Domain Socket 路径,默认为 "/tmp/grpc.sock" + +**tls 部分**: +- `ca_path`:CA 证书文件路径,默认为 "ca-cert.pem" +- `cert_path`:服务器证书文件路径,默认为 "server-cert.pem" +- `key_path`:服务器私钥文件路径,默认为 "server-sk.pem" + +### 示例配置文件 + +**基础配置 (basic.json)**: +```json +{ + "server": { + "addr": "127.0.0.1", + "port": 5031, + "uds_path": "/tmp/grpc.sock" + }, + "tls": { + "ca_path": "/etc/virtrust/certs/ca-cert.pem", + "cert_path": "/etc/virtrust/certs/server-cert.pem", + "key_path": "/etc/virtrust/certs/server-sk.pem" + } +} +``` + +**生产环境配置 (production.json)**: +```json +{ + "server": { + "addr": "0.0.0.0", + "port": 5031, + "uds_path": "/var/run/virtrustd.sock" + }, + "tls": { + "ca_path": "/etc/ssl/certs/virtrust-ca.pem", + "cert_path": "/etc/ssl/private/virtrust-server.pem", + "key_path": "/etc/ssl/private/virtrust-server.key" + } +} +``` + +## 运行和管理 + +### 启动服务 + +```bash +# 基础启动 +sudo virtrustd --config /etc/virtrust/virtrustd.json + +# 调试模式启动 +sudo virtrustd --config /etc/virtrust/virtrustd.json --debug +``` + +### 系统服务配置 + +创建 systemd 服务文件 `/etc/systemd/system/virtrustd.service`: + +```ini +[Unit] +Description=Virtrust Daemon +After=network.target libvirtd.service +Wants=libvirtd.service + +[Service] +Type=simple +User=root +Group=root +ExecStart=/usr/local/bin/virtrustd --config /etc/virtrust/virtrustd.json +ExecReload=/bin/kill -HUP $MAINPID +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +``` + +**服务管理命令**: +```bash +# 重新加载 systemd 配置 +sudo systemctl daemon-reload + +# 启动服务 +sudo systemctl start virtrustd + +# 停止服务 +sudo systemctl stop virtrustd + +# 重启服务 +sudo systemctl restart virtrustd + +# 查看服务状态 +sudo systemctl status virtrustd + +# 开机自启 +sudo systemctl enable virtrustd + +# 禁用开机自启 +sudo systemctl disable virtrustd +``` + +### 服务状态监控 + +```bash +# 检查服务是否运行 +sudo systemctl is-active virtrustd + +# 查看服务日志 +sudo journalctl -u virtrustd -f + +# 查看最近的错误日志 +sudo journalctl -u virtrustd --since "1 hour ago" -p err +``` + +## 日志管理 + +### 日志文件位置 + +- **日志文件**:`/var/log/virtrustd.log` +- **系统日志**:通过 systemd journal 记录 + +### 日志级别 + +- **默认级别**:INFO +- **调试模式**:DEBUG(使用 `--debug` 选项启用) + +### 日志轮转配置 + +创建 logrotate 配置文件 `/etc/logrotate.d/virtrustd`: + +``` +/var/log/virtrustd.log { + daily + missingok + rotate 30 + compress + delaycompress + notifempty + create 644 root root + postrotate + systemctl reload virtrustd + endscript +} +``` + +## 安全配置 + +### TLS 证书管理 + +1. **生成 CA 证书**: +```bash +# 创建 CA 私钥 +openssl genrsa -out ca-key.pem 4096 + +# 创建 CA 证书 +openssl req -new -x509 -days 365 -key ca-key.pem -out ca-cert.pem \ + -subj "/C=CN/ST=State/L=City/O=Organization/CN=Virtrust-CA" +``` + +2. **生成服务器证书**: +```bash +# 生成服务器私钥 +openssl genrsa -out server-key.pem 2048 + +# 生成证书签名请求 +openssl req -new -key server-key.pem -out server-req.pem \ + -subj "/C=CN/ST=State/L=City/O=Organization/CN=virtrustd-server" + +# 签发服务器证书 +openssl x509 -req -days 365 -in server-req.pem -CA ca-cert.pem \ + -CAkey ca-key.pem -CAcreateserial -out server-cert.pem +``` + +3. **权限设置**: +```bash +# 设置证书文件权限 +sudo chown root:root ca-cert.pem server-cert.pem server-key.pem +sudo chmod 644 ca-cert.pem server-cert.pem +sudo chmod 600 server-key.pem + +# 移动到安全位置 +sudo mv ca-cert.pem server-cert.pem server-key.pem /etc/virtrust/certs/ +``` + +4. **libvirt证书**: +```bash +参考 https://libvirt.org/kbase/tlscerts.html +``` + +### 防火墙配置 + +```bash +# 开放 gRPC 服务端口 +sudo firewall-cmd --permanent --add-port=5031/tcp +# 开放 libvirt tls方式端口 +sudo firewall-cmd --permanent --add-port=16514/tcp +sudo firewall-cmd --reload +``` diff --git a/virtrust/format-all.sh b/virtrust/format-all.sh new file mode 100755 index 0000000000000000000000000000000000000000..bfcbc17c1eddc58d26e1bb39f5185288bcba4524 --- /dev/null +++ b/virtrust/format-all.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Check if clang-format exists +if ! command -v clang-format &> /dev/null; then + echo "clang-format not found" + exit 1 +fi + +# Check if cmake-format exists +if ! command -v cmake-format &> /dev/null; then + echo "cmake-format not found" + exit 1 +fi + +# format c/c++ code +find . -name "*.cpp" -o -name "*.hpp" -o -name "*.h" | xargs clang-format -i + +# format cmake code +find . -name "CMakeLists.txt" -exec cmake-format -i {} \; diff --git a/virtrust/src/CMakeLists.txt b/virtrust/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..0e6714f3eff77a5b4bf0a88ffc29d9cbc5cfbbd6 --- /dev/null +++ b/virtrust/src/CMakeLists.txt @@ -0,0 +1,13 @@ +# Copyright (C) 2025 by Huawei Technologies Co., Ltd. All rights reserved. + +# api +add_subdirectory(virtrust) + +# cli +add_subdirectory(virtrust-sh) + +# daemon +add_subdirectory(libvirtrustd) + +# tsb_agent +add_subdirectory(tsb_agent) diff --git a/virtrust/src/libvirtrustd/CMakeLists.txt b/virtrust/src/libvirtrustd/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5d3c4f408bb770e2dd26bf420039844c85fa6336 --- /dev/null +++ b/virtrust/src/libvirtrustd/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + +# executable +add_executable(libvirtrustd ${CMAKE_CURRENT_LIST_DIR}/main.cpp + ${CMAKE_CURRENT_LIST_DIR}/utils.cpp) + +target_include_directories( + libvirtrustd PRIVATE ${CMAKE_DEPS_INCLUDEDIR} + $) + +target_link_libraries(libvirtrustd PRIVATE virtrust-shared Deps::rapidjson) diff --git a/virtrust/src/libvirtrustd/defines.h b/virtrust/src/libvirtrustd/defines.h new file mode 100644 index 0000000000000000000000000000000000000000..808a30f561beec887d87095ffde77e8913f08d84 --- /dev/null +++ b/virtrust/src/libvirtrustd/defines.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + */ + +#pragma once + +#include +#include + +namespace virtrust { +// version +constexpr std::string_view LIBVIRTRUSTD_VERSION = "1.0.0"; + +// default values +constexpr std::string_view LIBVIRTRUSTD_SERVER_ADDR = "127.0.0.1"; +constexpr std::string_view LIBVIRTRUSTD_CA_PATH = "ca-cert.pem"; +constexpr std::string_view LIBVIRTRUSTD_CERT_PATH = "server-cert.pem"; +constexpr std::string_view LIBVIRTRUSTD_SK_PATH = "server-sk.pem"; +constexpr std::string_view LIBVIRTRUSTD_UDS_PATH = "/tmp/grpc.sock"; +constexpr const char *VIRTRUSTD_LOGFILE_NAME = "/var/log/virtrustd.log"; +constexpr uint16_t LIBVIRTRUSTD_SERVER_PORT = 5031; +} // namespace virtrust diff --git a/virtrust/src/libvirtrustd/main.cpp b/virtrust/src/libvirtrustd/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dfad9721765e933e6ca5b4f16e85e0269cdd31ea --- /dev/null +++ b/virtrust/src/libvirtrustd/main.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + */ + +#include +#include + +#include +#include + +#include "libvirtrustd/defines.h" +#include "libvirtrustd/utils.h" +#include "spdlog/fmt/bundled/core.h" + +#include "virtrust/base/logger.h" +#include "virtrust/link/defines.h" +#include "virtrust/link/grpc_server.h" + +namespace virtrust { +namespace { +volatile sig_atomic_t g_stopFlag = 0; + +void SignalHandler(int signum) +{ + VIRTRUST_LOG_INFO("Received signal: {}", signum); + if (signum == SIGPIPE) { + VIRTRUST_LOG_INFO("SIGPIPE signal received, ignored."); + + return; + } + g_stopFlag = 1; +} + +void PrintVersion(std::string_view progname) +{ + fmt::print("{} version: {}\n", progname, LIBVIRTRUSTD_VERSION); +} + +void PrintUsage(std::string_view progname) +{ + fmt::print("\n" + " USAGE:\n" + " {} [options]\n" + "\n" + " REQUIRED ARGS:\n" + " --config path to config file\n" + "\n" + " OPTIONS:\n" + " -d | --debug run in debug mode\n" + " --help print this help\n" + " --version show version\n" + "\n", + progname); +} + +int ProcessArgs(int argc, char **argv) +{ + int arg = -1; + int longindex = -1; + std::vector