完整的监控栈一键部署方案
一、目录结构
monitoring-stack/
├── docker-compose.yml # 主文件
├── prometheus.yml # Prometheus配置
├── prometheus_data/ # Prometheus数据目录(自动创建)
├── grafana_data/ # Grafana数据目录(自动创建)
└── README.md # 使用说明(可选)
二、修改后的文件内容
1. docker-compose.yml
yaml
version: '3.8'
services:
node_exporter:
image: prom/node-exporter:v1.6.0
container_name: node_exporter
command:
- '--path.rootfs=/host'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
- '--collector.netclass.ignored-devices=^(veth|docker|br-)[a-f0-9]+$$'
pid: host
restart: unless-stopped
network_mode: host
environment:
- TZ=Asia/Shanghai
volumes:
- '/proc:/host/proc:ro'
- '/sys:/host/sys:ro'
- '/:/rootfs:ro,rslave'
ports:
- '9100:9100'
prometheus:
image: prom/prometheus:v2.37.9
restart: always
container_name: prometheus
hostname: prometheus
environment:
- TZ=Asia/Shanghai
ports:
- '9090:9090'
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/usr/share/prometheus/console_libraries'
- '--web.console.templates=/usr/share/prometheus/consoles'
- '--storage.tsdb.retention.time=7d'
- '--web.enable-lifecycle'
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ./prometheus_data:/prometheus
depends_on:
- node_exporter
networks:
- monitoring
grafana:
image: grafana/grafana:10.1.0-ubuntu
restart: always
container_name: grafana
hostname: grafana
environment:
- TZ=Asia/Shanghai
- GF_SECURITY_ADMIN_PASSWORD=admin123
- GF_INSTALL_PLUGINS=grafana-piechart-panel
volumes:
- ./grafana_data:/var/lib/grafana
- ./grafana-provisioning:/etc/grafana/provisioning:ro
ports:
- '3000:3000'
depends_on:
- prometheus
networks:
- monitoring
networks:
monitoring:
driver: bridge
2. prometheus.yml
yaml
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_timeout: 10s
alerting:
alertmanagers:
- static_configs:
- targets: []
# - alertmanager:9093
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
scrape_configs:
# 监控 Prometheus 自身
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
scrape_interval: 10s
# 监控 node_exporter
- job_name: 'node_exporter'
static_configs:
- targets: ['node_exporter:9100']
labels:
instance: '${HOSTNAME}'
job: 'node'
scrape_interval: 15s
# 监控 cAdvisor(如果需要监控容器)
- job_name: 'cadvisor'
static_configs:
- targets: ['cadvisor:8080']
labels:
instance: '${HOSTNAME}'
job: 'docker'
scrape_interval: 30s
metrics_path: /metrics
# 监控 Docker Engine(可选)
- job_name: 'docker'
static_configs:
- targets: ['host.docker.internal:9323']
labels:
instance: '${HOSTNAME}'
job: 'docker-engine'
scrape_interval: 30s
metrics_path: /metrics
3. 创建必要的目录和配置文件
创建 grafana-provisioning 目录和配置文件:
bash
# 创建目录
mkdir -p grafana-provisioning/datasources
mkdir -p grafana-provisioning/dashboards
mkdir -p prometheus_data
mkdir -p grafana_data
# 设置权限
chmod -R 777 grafana_data prometheus_data
4. grafana-provisioning/datasources/datasource.yml
yaml
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: true
jsonData:
timeInterval: 15s
queryTimeout: 60s
httpMethod: POST
manageAlerts: true
alertmanagerUid: ''
secureJsonData:
tlsSkipVerify: true
5. grafana-provisioning/dashboards/dashboard.yml
yaml
apiVersion: 1
providers:
- name: 'default'
orgId: 1
folder: ''
type: file
disableDeletion: false
editable: true
options:
path: /etc/grafana/provisioning/dashboards
6. 启动脚本(可选) start.sh
bash
#!/bin/bash
echo "正在启动监控栈..."
# 检查 Docker 是否运行
if ! docker info > /dev/null 2>&1; then
echo "错误: Docker 未运行,请启动 Docker 服务"
exit 1
fi
# 创建必要的目录
echo "创建目录结构..."
mkdir -p prometheus_data grafana_data
chmod -R 777 prometheus_data grafana_data 2>/dev/null || true
# 设置环境变量(自动获取主机名)
export HOSTNAME=$(hostname)
echo "主机名: $HOSTNAME"
echo "Prometheus 配置文件中的主机名将被替换为: $HOSTNAME"
# 替换 prometheus.yml 中的变量
if [ -f prometheus.yml ]; then
sed -i "s/\${HOSTNAME}/$HOSTNAME/g" prometheus.yml
echo "已更新 Prometheus 配置中的主机名"
fi
# 启动服务
echo "启动 Docker Compose 服务..."
docker-compose up -d
# 检查服务状态
echo ""
echo "等待服务启动..."
sleep 10
echo ""
echo "=========================================="
echo "监控栈部署完成!"
echo "=========================================="
echo ""
echo "服务访问地址:"
echo "- Node Exporter 指标: http://localhost:9100/metrics"
echo "- Prometheus UI: http://localhost:9090"
echo "- Grafana 面板: http://localhost:3000"
echo ""
echo "Grafana 登录信息:"
echo "- 用户名: admin"
echo "- 密码: admin123"
echo ""
echo "导入仪表板的步骤:"
echo "1. 登录 Grafana"
echo "2. 点击左侧 '+' → Import"
echo "3. 输入仪表板 ID: 1860 (Node Exporter Full)"
echo "4. 选择 Prometheus 数据源"
echo "5. 点击 Import"
echo ""
echo "停止服务:"
echo " docker-compose down"
echo ""
echo "查看日志:"
echo " docker-compose logs -f"
echo "=========================================="
7. 停止脚本(可选) stop.sh
bash
#!/bin/bash
echo "正在停止监控栈..."
docker-compose down
echo "清理临时文件..."
# 恢复 prometheus.yml 中的变量占位符
if [ -f prometheus.yml ]; then
sed -i "s/instance: '.*'/instance: '\${HOSTNAME}'/g" prometheus.yml
echo "已恢复 Prometheus 配置"
fi
echo "服务已停止"
8. 重置脚本(可选) reset.sh
bash
#!/bin/bash
echo "警告:这将删除所有监控数据!"
read -p "确定要继续吗?(y/N): " confirm
if [[ $confirm != [yY] ]]; then
echo "操作取消"
exit 0
fi
echo "停止服务..."
docker-compose down
echo "删除数据目录..."
rm -rf prometheus_data/* grafana_data/*
echo "重新创建目录..."
mkdir -p prometheus_data grafana_data
chmod -R 777 prometheus_data grafana_data 2>/dev/null || true
echo "重置完成,可以重新启动服务:"
echo "./start.sh"
9. README.md(使用说明)
markdown
# 一体化监控栈
基于 Docker Compose 的一键部署监控系统,包含:
- Node Exporter (v1.6.0) - 主机指标采集
- Prometheus (v2.37.9) - 监控和时序数据库
- Grafana (v10.1.0) - 数据可视化
## 快速开始
### 1. 前提条件
- Docker Engine 20.10+
- Docker Compose v2.0+
- Linux 系统(推荐)
### 2. 启动服务
```bash
# 赋予脚本执行权限
chmod +x *.sh
# 一键启动
./start.sh
3. 访问服务
- Node Exporter: http://localhost:9100/metrics
- Prometheus: http://localhost:9090
- Grafana : http://localhost:3000
- 用户名:
admin - 密码:
admin123
- 用户名:
4. 管理命令
bash
# 查看状态
docker-compose ps
# 查看日志
docker-compose logs -f
# 停止服务
./stop.sh
# 重置数据(谨慎使用)
./reset.sh
导入 Grafana 仪表板
- 登录 Grafana (http://localhost:3000)
- 点击左侧 '+' → Import
- 输入以下任意一个仪表板 ID:
1860- Node Exporter Full (推荐)8919- Node Exporter Quickstart11074- Node Exporter for Prometheus Dashboard
- 选择 "Prometheus" 数据源
- 点击 Import
配置文件说明
docker-compose.yml- 服务定义prometheus.yml- Prometheus 配置grafana-provisioning/- Grafana 自动配置datasources/datasource.yml- 数据源配置dashboards/dashboard.yml- 仪表板配置
数据持久化
- Prometheus 数据:
./prometheus_data/ - Grafana 数据:
./grafana_data/
注意事项
- 首次启动可能需要等待 1-2 分钟所有服务完全就绪
- 默认密码请在生产环境中修改
- 默认保留 7 天监控数据,可在
docker-compose.yml中调整 - 如需监控其他主机,修改
prometheus.yml中的scrape_configs
端口说明
- 9100: Node Exporter
- 9090: Prometheus
- 3000: Grafana
故障排除
-
检查 Docker 服务状态:
systemctl status docker -
查看容器日志:
docker-compose logs [服务名] -
检查端口占用:
netstat -tlnp | grep :端口号三、使用步骤
- 复制整个目录到目标服务器
bashscp -r monitoring-stack user@server:/path/to/ -
在目标服务器上执行
bash
cd monitoring-stack
chmod +x *.sh
./start.sh
- 验证部署
bash
# 检查服务状态
docker-compose ps
# 查看日志
docker-compose logs -f
# 测试访问
curl http://localhost:9100/metrics | head -5
四、特点说明
- 完全自包含:所有配置文件都在同一目录
- 一键部署:提供启动、停止、重置脚本
- 数据持久化:监控数据保存在本地目录
- 自动配置:Grafana 自动配置数据源
- 可移植性强:可复制到任何 Docker 环境运行
- 易于定制:配置文件结构清晰,便于修改
这个方案实现了真正的"开箱即用",只需要复制目录,运行 ./start.sh 即可完成整个监控栈的部署。
version: '3.8'
services:
node_exporter:
image: prom/node-exporter:v1.6.0
container_name: node_exporter
command:
-
'--path.rootfs=/host'
-
'--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)( ∣ / ) ′ − ′ − − c o l l e c t o r . n e t c l a s s . i g n o r e d − d e v i c e s = ( v e t h ∣ d o c k e r ∣ b r − ) [ a − f 0 − 9 ] + |/)' - '--collector.netclass.ignored-devices=^(veth|docker|br-)[a-f0-9]+ ∣/)′−′−−collector.netclass.ignored−devices=(veth∣docker∣br−)[a−f0−9]+'
pid: host
restart: unless-stopped
network_mode: host
environment:
- TZ=Asia/Shanghai
volumes:
-
'/proc:/host/proc:ro'
-
'/sys:/host/sys:ro'
-
'/:/rootfs:ro,rslave'
ports:
- '9100:9100'
========== 容器监控 ==========
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.47.2 # 使用固定版本
container_name: cadvisor
restart: unless-stopped
privileged: true
devices:
- /dev/kmsg
volumes:
-
/:/rootfs:ro
-
/var/run:/var/run:rw
-
/sys:/sys:ro
-
/var/lib/docker:/var/lib/docker:ro
-
/dev/disk:/dev/disk:ro
ports:
- '8080:8080'
networks:
-
monitoring
prometheus:
image: prom/prometheus:v2.47.2
restart: always
container_name: prometheus
hostname: prometheus
environment:
- TZ=Asia/Shanghai
ports:
- '9090:9090'
command:
-
'--config.file=/etc/prometheus/prometheus.yml'
-
'--storage.tsdb.path=/prometheus'
-
'--web.console.libraries=/usr/share/prometheus/console_libraries'
-
'--web.console.templates=/usr/share/prometheus/consoles'
-
'--storage.tsdb.retention.time=7d'
-
'--web.enable-lifecycle'
volumes:
-
./prometheus.yml:/etc/prometheus/prometheus.yml:ro
-
./prometheus_data:/prometheus
depends_on:
-
node_exporter
-
cadvisor
networks:
- monitoring
grafana:
image: grafana/grafana:10.2.3
restart: always
container_name: grafana
hostname: grafana
environment:
-
TZ=Asia/Shanghai
-
GF_SECURITY_ADMIN_PASSWORD=admin123
#- GF_INSTALL_PLUGINS=grafana-piechart-panel # 注释自动上网安装插件
volumes:
-
./grafana_data:/var/lib/grafana
-
./grafana-provisioning:/etc/grafana/provisioning:ro
ports:
- '3000:3000'
depends_on:
- prometheus
networks:
- monitoring
networks:
monitoring:
driver: bridge
#########
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_timeout: 10s
alerting:
alertmanagers:
-
static_configs:
-
targets: []
- alertmanager:9093
rule_files:
- "first_rules.yml"
- "second_rules.yml"
scrape_configs:
监控 Prometheus 自身
- job_name: 'prometheus'
static_configs:- targets: ['localhost:9090']
scrape_interval: 10s
- targets: ['localhost:9090']
监控 node_exporter
- job_name: 'node_exporter'
static_configs:- targets: ['node_exporter:9100']
labels:
instance: '${HOSTNAME}'
job: 'host-metrics'
scrape_interval: 15s
- targets: ['node_exporter:9100']
监控 cAdvisor(如果需要监控容器)
-
job_name: 'cadvisor'
static_configs:- targets: ['cadvisor:8080']
labels:
instance: '${HOSTNAME}'
job: 'docker'
scrape_interval: 30s
metrics_path: /metrics
可以过滤掉一些不需要的指标
metric_relabel_configs:
- source_labels: [ name ]
regex: 'container_tasks_state|container_memory_failures_total'
action: drop
- targets: ['cadvisor:8080']
监控 Docker Engine(可选)
- job_name: 'docker'
static_configs:- targets: ['host.docker.internal:9323']
labels:
instance: '${HOSTNAME}'
job: 'docker-engine'
scrape_interval: 30s
metrics_path: /metrics
- targets: ['host.docker.internal:9323']
4. 监控其他服务示例
- job_name: 'nginx'
static_configs:- targets: ['nginx-exporter:9113']
labels:
service: 'web-server'
- targets: ['nginx-exporter:9113']
5. 监控其他主机
- job_name: 'other-servers'
static_configs:- targets:
- '192.168.1.101:9100'
- '192.168.1.102:9100'
labels:
group: 'production'
- targets:
####### Jshielder
关于 JSSHield ,我需要澄清一下:你可能指的是 JShielder 或类似的 Linux 安全加固工具。让我详细解释这两个常见的工具:
一、什么是 JShielder?
JShielder 是一个流行的 Linux 安全加固脚本,专门用于自动加固 Linux 服务器的安全配置。它不是 Docker 监控工具,而是系统安全工具。
JShielder 的主要功能:
- 🔒 系统安全加固:自动应用安全配置
- 🛡️ 漏洞修复:修复已知的安全漏洞
- 🔐 服务加固:加固 SSH、Apache、Nginx、MySQL 等服务
- 📊 安全审计:检查系统安全状态
- ⚔️ 入侵检测:安装和配置入侵检测系统(IDS)
二、如何安装和使用 JShielder
安装步骤:
bash
# 1. 下载 JShielder
cd /tmp
git clone https://github.com/shouc/jshielder.git
# 或者从备用源
git clone https://github.com/danielmiessler/SecLists.git # 需要 SecLists 字典
# 2. 进入目录
cd jshielder
# 3. 安装依赖
chmod +x install_dependencies.sh
./install_dependencies.sh
# 4. 运行加固脚本
chmod +x jshielder.sh
./jshielder.sh
或者使用简化的一键安装:
bash
# 下载并运行
wget https://raw.githubusercontent.com/shouc/jshielder/master/jshielder.sh
chmod +x jshielder.sh
./jshielder.sh
三、JShielder 的工作原理
脚本运行时会有交互式菜单:
==========================================
JSHIELDER v2.0
Linux Security Hardening
==========================================
[1] 基本系统加固
[2] SSH 服务加固
[3] Apache 加固
[4] Nginx 加固
[5] MySQL/MariaDB 加固
[6] PHP 加固
[7] 防火墙配置 (iptables)
[8] 安装安全工具
[9] 完整系统加固(所有选项)
[0] 退出
请选择 [0-9]:
它会自动执行以下操作:
1. 系统基本加固
bash
# 禁用不必要的服务
systemctl disable rpcbind
systemctl disable nfs-common
# 配置 sysctl 安全参数
echo "net.ipv4.tcp_syncookies = 1" >> /etc/sysctl.conf
echo "kernel.randomize_va_space = 2" >> /etc/sysctl.conf
# 限制核心转储
echo "* hard core 0" >> /etc/security/limits.conf
2. SSH 加固
bash
# 修改 /etc/ssh/sshd_config
Port 2222 # 修改默认端口
PermitRootLogin no # 禁止 root 登录
PasswordAuthentication no # 禁用密码认证
MaxAuthTries 3 # 限制尝试次数
3. 防火墙配置
bash
# 设置 iptables 规则
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -j DROP
四、如果你指的是 JB Shielder(Java 应用防护)
JB Shielder 可能是用于 Java 应用程序安全加固的工具,通常包括:
主要功能:
- 🔐 Java 应用加固:防止反编译、代码混淆
- 🚫 许可证控制:防止未授权使用
- 🔒 运行时保护:防止内存篡改
- 📦 代码混淆:保护知识产权
安装示例:
bash
# 通常是通过 Java 代理方式
java -javaagent:jbshielder.jar -jar your-application.jar
# 或在启动脚本中添加
export JAVA_OPTS="$JAVA_OPTS -javaagent:/path/to/jbshielder.jar"
五、如果你指的是其他 "Shield" 类工具
1. Wazuh(OSSEC HIDS) - 入侵检测系统
bash
# 安装 Wazuh
curl -sO https://packages.wazuh.com/4.7/wazuh-install.sh
bash wazuh-install.sh
# 或使用 Docker
docker pull wazuh/wazuh-manager:latest
2. Lynis - 安全审计工具
bash
# 安装 Lynis
apt-get install lynis # Debian/Ubuntu
yum install lynis # RHEL/CentOS
# 运行审计
lynis audit system
3. Fail2Ban - 防暴力破解
bash
# 安装
apt-get install fail2ban
# 配置
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
systemctl enable fail2ban
六、安全加固与监控栈的结合
如果你想让 安全工具 与 PGN 监控栈 结合:
方案1:监控安全事件
yaml
# 在 docker-compose.yml 中添加安全监控
version: '3.8'
services:
# ... 已有的 PGN 服务 ...
# 安全审计工具
lynis:
image: hdzitao/lynis:latest
container_name: lynis
volumes:
- /:/host:ro
- ./lynis-reports:/var/log/lynis
command: audit system --quick
# 文件完整性监控
osquery:
image: osquery/osquery:latest
container_name: osquery
volumes:
- ./osquery.conf:/etc/osquery/osquery.conf
- ./osquery-logs:/var/log/osquery
network_mode: host
pid: host
privileged: true
# 日志收集器(发送到 Prometheus)
promtail:
image: grafana/promtail:latest
container_name: promtail
volumes:
- /var/log:/var/log:ro
- ./promtail-config.yaml:/etc/promtail/config.yaml
command: -config.file=/etc/promtail/config.yaml
方案2:Prometheus 监控安全指标
创建 security-alerts.yml:
yaml
groups:
- name: security.rules
rules:
# SSH 暴力破解告警
- alert: SSHBru teForceDetected
expr: rate(sshd_failed_logins_total[5m]) > 10
for: 2m
labels:
severity: critical
annotations:
description: 'SSH 暴力破解检测,{{ $value }} 次失败登录/分钟'
# Root 登录告警
- alert: RootLoginDetected
expr: sshd_root_logins_total > 0
labels:
severity: warning
annotations:
description: '检测到 Root 用户登录'
七、生产环境安全建议
1. Docker 安全加固
bash
# 安全扫描 Docker 镜像
docker scan grafana/grafana:latest
# 使用非 root 用户运行容器
docker run --user 1001:1001 grafana/grafana
# 限制容器资源
docker run --memory="512m" --cpus="1.0" nginx:latest
# 使用只读根文件系统
docker run --read-only alpine:latest
2. 监控栈安全配置
yaml
# docker-compose.yml 安全增强
services:
prometheus:
security_opt:
- no-new-privileges:true
read_only: true # 只读根文件系统
user: "65534:65534" # 使用 nobody 用户
grafana:
environment:
- GF_SECURITY_ALLOW_EMBEDDING=false
- GF_SECURITY_COOKIE_SECURE=true
- GF_SECURITY_CONTENT_TYPE_PROTECTION=true
3. 网络隔离
yaml
networks:
monitoring:
driver: bridge
internal: true # 内部网络,不暴露给宿主机
public:
driver: bridge
services:
grafana:
networks:
- monitoring
- public # 只有 Grafana 暴露给外部
ports:
- '3000:3000'
八、如果你想问的是其他工具...
请提供更多上下文,可能是:
- JSShield - JavaScript 代码保护工具
- JShielder - Linux 服务器加固脚本 ✓(最可能)
- JB Shielder - Java 应用保护工具
- Cloud Shielder - 云安全工具
请确认一下:
- 你是在哪里看到这个工具名的?
- 是用于什么场景的?(服务器安全?应用保护?)
- 有没有具体的错误信息或使用场景?
总结
如果你想要 Linux 服务器安全加固:
- 使用 JShielder 进行自动安全配置
- 结合 PGN 监控栈 监控安全事件
- 定期运行安全审计(Lynis、OpenSCAP)
如果你想要 Docker 环境安全:
- 扫描镜像漏洞 :
docker scan - 最小权限原则:非 root 用户运行容器
- 网络隔离:使用内部网络
- 监控安全事件:集成到 Prometheus 告警
建议的完整方案:
bash
# 1. 安装监控栈
docker-compose up -d
# 2. 运行安全加固(谨慎操作!先测试)
cd /tmp
git clone https://github.com/shouc/jshielder.git
cd jshielder
# 仔细阅读每个选项后再执行!
./jshielder.sh
# 3. 配置安全监控
# 将 /var/log/auth.log, /var/log/secure 等日志导入 Prometheus
# 设置安全相关的告警规则
警告 :安全加固工具会修改系统配置,一定要先备份,并在测试环境中验证后再应用到生产环境!
python shielder
针对 Python 代码运行在 Docker 中的保护,主要有几种 Shield 方案。我来详细解释每种方案:
一、Python 代码保护方案概览
| 方案 | 保护级别 | 适用场景 | 复杂度 |
|---|---|---|---|
| 代码混淆 | 低-中 | 防止简单逆向 | 低 |
| 字节码保护 | 中 | 防直接查看源码 | 中 |
| 打包加密 | 高 | 商业软件保护 | 高 |
| 容器加固 | 高 | Docker 运行时保护 | 中 |
| 许可证控制 | 中-高 | 商业授权管理 | 高 |
二、Python 代码混淆方案
1. 使用 pyminifier - 最简单的混淆
dockerfile
# Dockerfile
FROM python:3.9-slim
# 安装混淆工具
RUN pip install pyminifier
# 复制源码
COPY src/ /app/src/
# 混淆代码
RUN pyminifier --obfuscate /app/src/main.py > /app/src/main_obf.py && \
mv /app/src/main_obf.py /app/src/main.py
WORKDIR /app
CMD ["python", "src/main.py"]
2. 使用 pyarmor - 专业的混淆加密
dockerfile
# Dockerfile
FROM python:3.9-slim
# 安装 PyArmor
RUN pip install pyarmor
COPY src/ /app/src/
# 混淆整个项目
RUN cd /app && \
pyarmor gen --output dist --src src --recursive \
--obf-code=1 --obf-module=1 --restrict=1
WORKDIR /app/dist
CMD ["python", "main.py"]
PyArmor 配置文件 pyarmor-config.yaml:
yaml
# 混淆配置
project:
name: "myapp"
input: "src"
output: "dist"
obfuscate:
mode: 1 # 1=平衡,2=最强
restrict: 1 # 限制运行
platform: "linux.x86_64"
runtime:
enable: true
extra: "--with-license"
license:
enable: true
type: "time" # 时间限制
expired: "2024-12-31"
三、Python 打包加密方案
1. 使用 Nuitka 编译为二进制
dockerfile
FROM python:3.9-slim as builder
# 安装编译工具
RUN apt-get update && apt-get install -y \
gcc g++ \
&& rm -rf /var/lib/apt/lists/*
RUN pip install nuitka
COPY src/ /app/src/
# 编译为二进制
RUN cd /app && \
python -m nuitka \
--standalone \
--onefile \
--include-package=myapp \
--output-filename=myapp.bin \
src/main.py
# 最终镜像
FROM debian:bullseye-slim
COPY --from=builder /app/myapp.bin /app/myapp
CMD ["/app/myapp"]
2. 使用 PyInstaller + 加密
dockerfile
FROM python:3.9-slim as builder
RUN pip install pyinstaller pycryptodome
COPY src/ /app/src/
COPY encrypt_key.bin /app/ # 加密密钥
# 打包并加密
RUN cd /app && \
pyinstaller --onefile src/main.py && \
# 使用 AES 加密二进制文件
python -c "
from Crypto.Cipher import AES
key = open('encrypt_key.bin', 'rb').read()
cipher = AES.new(key, AES.MODE_EAX)
with open('dist/main', 'rb') as f:
data = f.read()
ciphertext, tag = cipher.encrypt_and_digest(data)
with open('dist/main.enc', 'wb') as f:
[f.write(x) for x in (cipher.nonce, tag, ciphertext)]
"
# 运行时容器
FROM python:3.9-slim
COPY --from=builder /app/decrypt_runner.py /app/
COPY --from=builder /app/dist/main.enc /app/
COPY --from=builder /app/encrypt_key.bin /app/
CMD ["python", "/app/decrypt_runner.py"]
四、Docker 容器级保护方案
1. 使用 docker-slim 最小化镜像
bash
# 1. 安装 docker-slim
curl -sL https://raw.githubusercontent.com/docker-slim/docker-slim/master/scripts/install-dockerslim.sh | sudo bash
# 2. 压缩现有镜像
docker-slim build --target your-python-app:latest \
--http-probe=false \
--exclude-mounts \
--include-shell=false
# 生成的镜像只有必要的文件,更难逆向
2. 只读容器 + 非root用户
dockerfile
FROM python:3.9-slim
# 创建非root用户
RUN groupadd -r appuser && useradd -r -g appuser appuser
COPY --chown=appuser:appuser requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY --chown=appuser:appuser src/ /app/
# 切换到非root用户
USER appuser
# 只读文件系统
CMD ["python", "/app/main.py"]
yaml
# docker-compose.yml
version: '3.8'
services:
python-app:
build: .
read_only: true # 只读根文件系统
security_opt:
- no-new-privileges:true
tmpfs:
- /tmp # 只有 /tmp 可写
user: "1000:1000" # 非root用户
五、许可证控制系统
1. 基于时间的许可证
python
# license_manager.py
import hashlib
import datetime
import json
from cryptography.fernet import Fernet
import os
class LicenseManager:
def __init__(self):
self.license_file = "/config/license.lic"
self.key = os.getenv("LICENSE_KEY", "").encode()
def validate(self):
if not os.path.exists(self.license_file):
return False
try:
with open(self.license_file, 'rb') as f:
encrypted = f.read()
cipher = Fernet(self.key)
data = cipher.decrypt(encrypted)
license_data = json.loads(data.decode())
# 检查过期时间
expire_date = datetime.datetime.fromisoformat(license_data['expire'])
if datetime.datetime.now() > expire_date:
return False
# 检查硬件指纹(简化版)
machine_id = self.get_machine_id()
if license_data.get('machine_id') != machine_id:
return False
return True
except:
return False
def get_machine_id(self):
# 获取机器唯一标识
with open('/etc/machine-id', 'r') as f:
return f.read().strip()
# 在应用中调用
license_mgr = LicenseManager()
if not license_mgr.validate():
print("许可证无效或已过期")
exit(1)
2. Docker 环境变量控制
yaml
# docker-compose.yml
version: '3.8'
services:
python-app:
build: .
environment:
- LICENSE_KEY=${LICENSE_KEY}
- APP_ID=${APP_ID}
- MAX_USERS=10 # 限制用户数
volumes:
- ./license.lic:/config/license.lic:ro
六、完整的 Docker 保护方案
Dockerfile(综合保护)
dockerfile
# 构建阶段
FROM python:3.9-slim as builder
# 1. 安装保护工具
RUN pip install pyarmor nuitka
# 2. 复制源代码
COPY src/ /app/src/
COPY requirements.txt /app/
# 3. 混淆源代码
RUN cd /app && \
pyarmor gen --output dist_obf \
--src src \
--obf-code=2 \
--obf-module=2 \
--restrict=1 \
--platform linux.x86_64
# 4. 编译为 C 扩展(可选)
RUN cd /app && \
find dist_obf -name "*.py" -exec \
python -c "import py_compile; py_compile.compile('{}', '{}c')" \;
# 运行时阶段
FROM python:3.9-slim
# 创建非特权用户
RUN addgroup --system app && \
adduser --system --ingroup app appuser
# 复制混淆后的代码
COPY --from=builder --chown=appuser:appuser /app/dist_obf /app
# 安装依赖(无源码)
COPY --chown=appuser:appuser requirements.txt /app/
RUN pip install --no-cache-dir -r /app/requirements.txt
# 安全配置
USER appuser
WORKDIR /app
# 设置只读
RUN chmod -R 555 /app # 只读权限
# 运行保护检查
COPY --chown=appuser:appuser security_check.py /app/
RUN python security_check.py
CMD ["python", "main.py"]
security_check.py(安全检查)
python
#!/usr/bin/env python3
import sys
import os
import hashlib
def check_environment():
"""检查运行环境是否安全"""
# 1. 检查是否在容器中
if not os.path.exists('/.dockerenv'):
print("错误:必须在Docker容器中运行")
return False
# 2. 检查文件完整性
expected_hash = "abc123..." # 预计算的文件哈希
with open('/app/main.py', 'rb') as f:
actual_hash = hashlib.sha256(f.read()).hexdigest()
if actual_hash != expected_hash:
print("错误:文件已被修改")
return False
# 3. 检查调试器
try:
import ptrace
print("警告:发现调试器")
return False
except ImportError:
pass
# 4. 检查内存dump工具
if os.path.exists('/proc/self/exe'):
with open('/proc/self/status', 'r') as f:
if 'TracerPid:' in f.read():
print("警告:进程被跟踪")
return False
return True
if __name__ == "__main__":
if not check_environment():
sys.exit(1)
print("环境安全检查通过")
七、商业级保护方案
1. 使用 Cython 编译核心模块
python
# core_module.pyx - Cython 源代码
def sensitive_algorithm(data):
# 核心算法,会被编译为C
cdef double result = 0
for i in range(len(data)):
result += data[i] * 1.5
return result
# setup.py
from distutils.core import setup
from Cython.Build import cythonize
from Cython.Distutils import Extension
extensions = [
Extension("core_module",
["core_module.pyx"],
extra_compile_args=["-O3", "-fPIC"])
]
setup(
ext_modules=cythonize(extensions,
compiler_directives={'language_level': "3"})
)
dockerfile
# 编译 Cython 扩展
FROM python:3.9-slim as builder
RUN apt-get update && apt-get install -y gcc
RUN pip install cython
COPY . /app/
RUN cd /app && python setup.py build_ext --inplace
# 运行阶段
FROM python:3.9-slim
COPY --from=builder /app/core_module.cpython-39-x86_64-linux-gnu.so /app/
2. API 网关保护
yaml
# docker-compose.yml
version: '3.8'
services:
api-gateway:
image: nginx:alpine
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "80:80"
python-app:
build: .
environment:
- API_KEY=${API_KEY}
expose:
- "8000" # 不直接暴露
rate-limiter:
image: redis:alpine
auth-service:
image: oauth2-proxy/oauth2-proxy:latest
八、监控和审计
集成到 PGN 监控栈
yaml
# docker-compose.yml 扩展
services:
python-app:
# ... 原有配置 ...
labels:
- "prometheus.enable=true"
- "prometheus.port=8000"
- "prometheus.path=/metrics"
# 添加 Python 应用指标导出器
prometheus-python-exporter:
image: prom/python-exporter:latest
environment:
- TARGETS=python-app:8000
networks:
- monitoring
Python 应用自身暴露指标
python
# metrics.py
from prometheus_client import start_http_server, Counter, Gauge
import time
# 定义指标
api_requests = Counter('app_api_requests_total', 'Total API requests')
license_checks = Counter('app_license_checks_total', 'License validation checks')
active_users = Gauge('app_active_users', 'Currently active users')
class ProtectedApp:
def __init__(self):
# 启动指标服务器
start_http_server(8000)
def process_request(self, data):
api_requests.inc()
# 检查许可证
if not self.check_license():
license_checks.inc()
return {"error": "License invalid"}
return {"result": "success"}
九、部署流程
1. 开发阶段保护
bash
#!/bin/bash
# build-protected.sh
# 1. 代码混淆
pyarmor gen --output dist --src src --recursive \
--obf-code=2 --restrict=1
# 2. 生成许可证
python generate_license.py --days 365