# PythonRadiusServer **Repository Path**: jlf8848/PythonRadiusServer ## Basic Information - **Project Name**: PythonRadiusServer - **Description**: PythonRadiusServer - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-11 - **Last Updated**: 2026-09-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Python RadSec Server ## 这是什么 一个用 Python 写的 RadSec(RADIUS over TLS)服务端,运行在 Windows 上。 配合 Java 端的 `RadSecClientExample` 做联调测试。 ## 快速开始(3 步) ### 第 1 步:安装 Python 去 [python.org](https://www.python.org/downloads/) 下载 Python 3.8+,安装时勾选 "Add to PATH"。 验证: ``` python --version ``` ### 第 2 步:双击 start.bat ``` start.bat ``` 首次运行会自动: 1. 检查 Python 2. 生成测试证书(CA + 服务端 + 客户端 + CRL + 合并文件) 3. 安装依赖(cryptography 库) 4. 启动服务端 看到 `RadSec Server 已启动,等待客户端连接...` 就说明启动成功。 ### 第 3 步:配置 Java 客户端 `start.bat` 生成的证书在 `certs/` 目录下。你需要把两个**合并文件**拷贝到 Java 端: **1. 拷贝 CA+CRL 合并文件给 Java 客户端** 把 `certs/ca-crl.pem` 拷贝到 Java 端 `RadSecClientExample` 的 `pemPath` 指向的路径。 ```java private final String pemPath = "/etc/radius/radsec-ca-crl.pem"; ``` `ca-crl.pem` 已包含 CA 证书和 CRL 吊销列表,无需手动拼接。 **2. 拷贝客户端私钥+证书合并文件给 Java 客户端** 把 `certs/client-cert-key.pem` 拷贝到 Java 端 `RadSecClientExample` 的 `keyPath` 指向的路径。 ```java private final String keyPath = "/etc/radius/client-key.pem"; ``` `client-cert-key.pem` 已包含客户端私钥和证书(私钥在前,证书在后),无需手动拼接。 **3. 确认密码配置** 默认情况下,`gen_certs.py` 生成的私钥是**加密的**,密码为 `Manor@441`。 Java 端的 `keyFilePassword` 保持默认值即可: ```java private final String keyFilePassword = "Manor@441"; ``` 如果你在 `gen_certs.py` 中设置了 `ENCRYPT_PRIVATE_KEYS = False`(私钥不加密), 则 Java 端的 `keyFilePassword` 需改为 `null`。 **4. 修改服务端地址** Java 端 `main()` 里的 IP 改为本机地址: ```java AuthResult result = client.auth( "127.0.0.1", // 或你运行 Python 服务端的机器 IP "radsec", "test-user", "test-password", 2 ); ``` ## 文件说明 ``` PythonRadiusServer/ ├── server.py 主程序(启动入口) ├── config.py 配置文件(端口、证书路径、私钥密码、用户文件等) ├── radius_packet.py RADIUS 报文解析与编码 ├── tls_layer.py TLS 服务端 + CRL 校验 ├── auth_handler.py PAP 认证 + 用户校验 ├── gen_certs.py 证书生成脚本(首次运行自动执行) ├── users.txt 用户名密码文件(直接编辑添加用户) ├── requirements.txt Python 依赖 ├── start.bat Windows 一键启动脚本 ├── README.md 本文件 └── certs/ 证书目录(gen_certs.py 自动生成) ├── ca.pem CA 证书(Python 服务端用) ├── ca-key.pem CA 私钥(生成证书用,不要分发) ├── server-cert.pem 服务端证书 ├── server-key.pem 服务端私钥(加密,密码 Manor@441) ├── client-cert.pem 客户端证书 ├── client-key.pem 客户端私钥(加密,密码 Manor@441) ├── crl.pem CRL 吊销列表(默认为空) ├── ca-crl.pem CA 证书 + CRL 合并文件 → 拷贝给 Java 的 pemPath ├── client-cert-key.pem 客户端私钥 + 证书合并文件 → 拷贝给 Java 的 keyPath ├── revoked-server-cert.pem [测试] 被吊销的服务端证书(测试 CRL 拒绝) ├── ca-crl-revoked.pem [测试] CA + 含吊销条目的 CRL(测试吊销检查) ├── ca-crl-expired.pem [测试] CA + 已过期的 CRL(测试过期 CRL 处理) └── empty.pem [测试] 空文件(测试异常处理) ``` ### 两个合并文件说明 | 文件 | 内容 | Java 端用途 | |------|------|------------| | `ca-crl.pem` | CA 证书 + CRL(CA 在前,CRL 在后) | `pemPath`:客户端校验服务端证书 + CRL 吊销检查 | | `client-cert-key.pem` | 客户端私钥 + 证书(私钥在前,证书在后) | `keyPath`:服务端校验客户端证书 | 这两个合并文件的格式与 Java 端 `SimpleKeyManager` / `RadSecEmbeddedCrlTrustManager` 期望的 PEM 格式完全一致,拷贝过去即可使用,无需手动拼接。 ### Java 单元测试用证书 以下 4 个文件专为 Java 端 `extended/src/test/` 下的单元测试生成, 测试代码中的默认路径直接指向 `C:/DevinProject/PythonRadiusServer/certs/`,无需拷贝。 | 文件 | 内容 | 测试场景 | |------|------|---------| | `revoked-server-cert.pem` | 被吊销的服务端证书 | 测 `checkServerTrusted` 拒绝被吊销证书 | | `ca-crl-revoked.pem` | CA + 含吊销条目的 CRL | 测 CRL 吊销检查逻辑 | | `ca-crl-expired.pem` | CA + nextUpdate 已过期的 CRL | 测 `rejectExpiredCrl` 开关 | | `empty.pem` | 空文件 | 测空 PEM 的异常处理 | 生成方式:运行 `gen_certs.py` 即自动生成(步骤 7-10)。 ## 私钥加密配置 在 `gen_certs.py` 中可以控制私钥是否加密: ```python ENCRYPT_PRIVATE_KEYS = True # True=加密,False=不加密 KEY_PASSWORD = b'Manor@441' # 加密密码(仅 ENCRYPT_PRIVATE_KEYS=True 时生效) ``` | 配置 | 私钥状态 | Java 端 keyFilePassword | Python 端 SERVER_KEY_PASSWORD | |------|---------|------------------------|-------------------------------| | `ENCRYPT_PRIVATE_KEYS = True` | 加密(ENCRYPTED PRIVATE KEY) | `"Manor@441"` | `'Manor@441'` | | `ENCRYPT_PRIVATE_KEYS = False` | 不加密(PRIVATE KEY) | `null` | `None` | **注意**:修改 `gen_certs.py` 的加密配置后,需要同步修改 `config.py` 中的 `SERVER_KEY_PASSWORD`,否则 Python 服务端无法加载加密的私钥。 ## 添加用户 编辑 `users.txt`,一行一个用户,格式 `用户名 密码`: ``` test-user test-password alice 123456 bob secret ``` 修改后无需重启服务端,下次认证自动读取最新内容。 ## 常见问题 ### Q: 启动报错 "证书文件不存在" 运行 `python gen_certs.py` 生成证书,或直接运行 `start.bat`(会自动生成)。 ### Q: 启动报错 "Could not deserialize key data" 或私钥加载失败 检查 `config.py` 中的 `SERVER_KEY_PASSWORD` 是否与 `gen_certs.py` 中的 `KEY_PASSWORD` 一致: - 私钥已加密(`ENCRYPT_PRIVATE_KEYS = True`):`SERVER_KEY_PASSWORD = 'Manor@441'` - 私钥未加密(`ENCRYPT_PRIVATE_KEYS = False`):`SERVER_KEY_PASSWORD = None` ### Q: Java 客户端连接超时 检查: 1. Python 服务端是否已启动(看到"等待客户端连接") 2. Java 端的 IP 地址是否正确(本机用 127.0.0.1) 3. 防火墙是否放行了 2083 端口 ### Q: Java 客户端报 "证书校验失败" 检查: 1. `ca-crl.pem` 是否拷贝到了 Java 端 `pemPath` 指向的路径 2. `client-cert-key.pem` 是否拷贝到了 Java 端 `keyPath` 指向的路径 3. `keyFilePassword` 是否与 `gen_certs.py` 中的 `KEY_PASSWORD` 一致 (加密时填 `"Manor@441"`,不加密时填 `null`) ### Q: Java 客户端报 "密码错误" 但密码明明对 检查: 1. Java 端 `setSharedSecret("radsec")` 是否与 Python 端 `config.SHARED_SECRET` 一致 2. `users.txt` 中的密码是否正确(注意前后空格) ### Q: 如何吊销客户端证书 目前 `crl.pem` 和 `ca-crl.pem` 中的 CRL 段是空的(无吊销)。如需吊销证书, 需要手动生成新的 CRL 并更新这两个文件。后续会提供 `revoke_cert.py` 脚本 来自动化这个操作。