openziti/ziti-sdk-c
GitHub: openziti/ziti-sdk-c
OpenZiti的C语言SDK,让开发者通过标准socket接口在C/C++应用中嵌入零信任网络能力,支持服务拨号、绑定及多种认证方式。
Stars: 84 | Forks: 26

# OpenZiti C SDK

OpenZiti C SDK 允许开发者创建自己的自定义 OpenZiti 网络终端应用程序。
OpenZiti 是一个现代化的、可编程的网络覆盖层,附带相关的边缘组件,用于应用嵌入式的零信任网络连接,由开发者专为开发者编写。
该 SDK 通过 API 利用这种能力,允许开发者构思和开发超越 OpenZiti 默认处理范围的解决方案。
此 SDK 具有以下功能:
- 启用网络终端客户端,允许设备 [dial (访问)](#dialing-a-service) 或 [bind (托管)](#binding-to-a-service) OpenZiti Services
- 为 [x509 证书](#example-code-configuration) 流程提供 [authentication](https://openziti.io/docs/learn/core-concepts/security/authentication/auth) 接口
- 收集并提交安全态势信息,用于 [Posture Checks](https://openziti.io/docs/learn/core-concepts/security/authorization/posture-checks)
- 允许应用程序通过标准 [`socket`](#high-level-zitilib-api) 接口绑定或拨号服务
## 配置您的应用程序以使用 OpenZiti C SDK
将 Ziti SDK 嵌入您的应用程序的最简单方法是将其拉入您的 CMake 构建中
```
FetchContent_Declare(ziti-sdk-c
GIT_REPOSITORY https://github.com/openziti/ziti-sdk-c.git
GIT_TAG ${LATEST_ZITI_RELEASE}
)
FetchContent_MakeAvailable(ziti-sdk-c)
# ...
# ...
add_executable(most-secure-app-ever ${my_sources})
target_link_libraries(most-secure-app-ever PRIVATE ziti)
```
您还需要 OpenZiti SDK 使用的其他库(它们在 [vcpkg.json](vcpkg.json) 中指定):
| 库 | 用途 |
|-------------|-------------------------------|
| `libuv` | 事件循环 |
| `openssl` | TLS |
| `zlib` | HTTPS 压缩 |
| `llhttp` | HTTP 解析 |
| `libsodium` | OpenZiti 端到端加密 |
有多种方法可以将这些第三方依赖项引入您的构建中:系统级别、CMake `FetchContent`、vcpkg 等。
我们推荐使用 [`vcpkg`](https://vcpkg.io/)。
如果您想在独立模式下贡献/构建/修改此 SDK,请参阅 [BUILD.md](BUILD.md) 了解如何操作。
## 在您的应用程序中使用 OpenZiti
### High-Level (`Zitilib`) API
高级 API 旨在简化在应用程序中嵌入 OpenZiti。
此 API 的主要特点是将 Ziti 连接呈现为常规套接字文件描述符(或 Windows 上的句柄)。
这些套接字可以在阻塞和非阻塞模式下使用。
#### SDK 初始化和关闭
只需三个函数即可完成 SDK 的初始化和关闭。
可能需要额外的步骤来完成身份验证。请参见下面的示例。
| 函数 | 用途 |
|-----------------------|------------------------------------------------------------|
| `Ziti_lib_init()` | 初始化 Ziti SDK 后台事件循环,该循环运行所有内部 SDK 任务 |
| `Ziti_load_context()` | 从提供的文件加载已注册的 [ziti identity](https://openziti.io/docs/learn/core-concepts/identities/overview) |
| `Ziti_lib_shutdown()` | 优雅地关闭所有已加载的身份并终止事件循环 |
```
#include
int main(int argc, char *argv[]) {
const char *identity_file = process_args(argc, argv);
Ziti_lib_init();
ziti_handle_t ztx = NULL;
int err = Ziti_load_context(&ztx, identity_file);
// simplest case, identity is loaded successfully with key/certificate
if (err == ZITI_OK) goto important_work;
// identity does not have key/certificate or requires secondary auth with external provider
if (err == ZITI_EXTERNAL_LOGIN_REQUIRED) {
// optional step: query supported external login providers
ziti_jwt_signer_array signers = Ziti_get_ext_signers(ztx);
// select
const char *singer = ...; // prompt user or use a known provider
char *url = Ziti_login_external(ztx, signer);
// prompt user to open URL in browser
// wait for external login to complete
err = Ziti_wait_for_auth(ztx, 60000); // wait for a minute
}
// identity requires TOTP code for secondary authentication
if (err == ZITI_PARTIALLY_AUTHENTICATED) {
char *code = ...; // prompt user for TOTP code
err = Ziti_login_totp(ztx, code);
}
if (err != ZITI_OK) {
fprintf(stderr, "Failed to load identity: %s\n", Ziti_strerror(rc));
// handle error, e.g. exit
}
important_work:
...
Ziti_lib_shutdown();
}
```
一旦加载了 `ziti_context`,它就可以用于拨号服务或绑定到服务(前提是身份拥有适当的访问权限)。
#### 拨号服务
| 函数 | 用途 |
|------------------------------------------------|------------------------------------------------|
| `Ziti_connect(sock, ztx, service, terminator)` | 将给定的套接字连接到上下文中的服务/终结器 |
| `Ziti_connect_addr(sock, hostname, port)` | 将给定的套接字连接到指定的拦截地址 |
```
ziti_socket_t sock = Ziti_socket(SOCK_STREAM);
int error = Ziti_connect(sock, ztx, "my-secure-service", NULL);
// use sock as normal socket
do {
write(sock, ...);
read(sock, ...);
} while (!done);
close(sock);
```
#### 绑定到服务
| 函数 | 用途 |
|--------------------------------------------|------------------------------------------------------|
| `Ziti_bind(srv, ztx, service, terminator)` | 将给定的套接字绑定到上下文中的服务/终结器 |
| `Ziti_listen(sock, backlog)` | 设置最大挂起入站连接数(类似于 TCP backlog) |
| `Ziti_accept(srv, caller, caller_len)` | 接受传入连接并返回对等套接字/句柄 |
```
ziti_socket_t srv = Ziti_socket(SOCK_STREAM);
int error = Ziti_bind(srv, ztx, "my-secure-service", NULL);
Ziti_listen(srv, 10); // sets accept backlog
do {
char caller[128];
ziti_socket_t clt = Ziti_accept(srv, caller, (int)sizeof(caller));
// use client as normal socket
process_client(clt);
} while (!done);
close(srv);
```
## 获取帮助
请利用这些社区资源获取帮助。我们使用 GitHub [issues](https://github.com/openziti/ziti-sdk-c/issues) 来跟踪错误和功能请求,但我们的处理能力有限。
- 阅读 [文档](https://docs.openziti.io/)
- 在 [Discourse](https://openziti.discourse.group/) 上提问
Copyright© NetFoundry Inc.
标签:API, Bash脚本, CMake, DNS 反向解析, IP 地址批量处理, JSONLines, x509证书, Zero Trust, 安全测试工具, 安全通信, 客户端加密, 客户端加密, 应用程序安全, 开源, 微隔离, 端点安全, 纵深防御, 网络安全, 网络编程, 网络覆盖, 补丁管理, 隐私保护, 隧道技术, 零信任