跳到主要内容

安全配置与运维

生产环境的安全配置和日常运维同样重要。本章将介绍如何正确配置 Web 服务器、应用程序和基础设施的安全选项,以及日常安全运维的最佳实践。

Web 服务器安全配置

Nginx 安全配置

# nginx.conf

# 隐藏版本号
server_tokens off;

# 防止点击劫持
add_header X-Frame-Options "SAMEORIGIN" always;

# 防止 XSS
add_header X-XSS-Protection "1; mode=block" always;

# 防止 MIME 类型嗅探
add_header X-Content-Type-Options "nosniff" always;

# CSP 内容安全策略
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;" always;

# HSTS - 强制 HTTPS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

# 禁用不安全的加密协议
ssl_protocols TLSv1.2 TLSv1.3;

# 安全的加密套件
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';

# 禁用 SSL 重协商
ssl_prefer_server_ciphers on;

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;

# 上传文件大小限制
client_max_body_size 10M;

# 超时配置
client_body_timeout 10s;
client_header_timeout 10s;
keepalive_timeout 65;
send_timeout 10s;

# 访问日志(注意不要记录敏感信息)
log_format security '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';

access_log /var/log/nginx/access.log security;

Tomcat 安全配置

<!-- server.xml -->
<Connector port="8080" redirectPort="8443" />

<!-- 禁用不必要的 HTTP 方法 -->
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>TRACE</http-method>
<http-method>OPTIONS</http-method>
</web-resource-collection>
<auth-constraint />
</security-constraint>

<!-- 设置安全会话 Cookie -->
<Context>
<Manager pathname="" />
<!-- 使用独立的会话 Cookie 配置 -->
<CookieProcessor className="org.apache.tomcat.util.http.Rfc6265CookieProcessor"
sameSiteCookies="Strict"
validatePlainCookies="false" />
</Context>

应用安全配置

Spring Security 配置

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http
// 禁用 frames 以防止 clickjacking
.headers()
.frameOptions().deny()
.and()

// CSRF 防护
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())
.and()

// 安全头
.headers()
.contentTypeOptions().and()
.xssProtection().and()
.httpStrictTransportSecurity()
.includeSubDomains(true)
.maxAgeInSeconds(31536000)
.and()
.contentSecurityPolicy("default-src 'self'")
.and()

// 授权规则
.authorizeRequests()
.antMatchers("/public/**", "/auth/**").permitAll()
.antMatchers("/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()

// 登录配置
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/home", true)
.failureUrl("/login?error=true")
.and()

// 登出配置
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login?logout=true")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.and()

// 会话管理
.sessionManagement()
.maximumSessions(1)
.maxSessionsPreventsLogin(true);
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
}

日志配置

<!-- logback-spring.xml -->
<configuration>
<appender name="SECURITY_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/security.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/security.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>90</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<logger name="com.example.security" level="INFO" additivity="false">
<appender-ref ref="SECURITY_LOG" />
</logger>
</configuration>

依赖安全管理

Maven 依赖检查

<!-- pom.xml -->
<plugin>
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<version>8.4.0</version>
<configuration>
<failBuildOnCVSS>7</failBuildOnCVSS>
<cveValidForHours>24</cveValidForHours>
</configuration>
<executions>
<execution>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>

NPM 审计

# 运行安全检查
npm audit

# 修复漏洞
npm audit fix

# CI 中使用
npm audit --audit-level=high

安全监控

入侵检测

// 简单的登录失败监控
@Service
public class IntrusionDetectionService {

private static final int MAX_ATTEMPTS = 5;
private static final int LOCKOUT_MINUTES = 30;

public void recordLoginFailure(String username) {
String key = "login:failures:" + username;
Long count = redis.opsForValue().increment(key);

if (count == 1) {
redis.expire(key, LOCKOUT_MINUTES * 60);
}

if (count >= MAX_ATTEMPTS) {
lockAccount(username);
sendSecurityAlert(username, "账户已被锁定");
}
}

public boolean isLocked(String username) {
return redis.hasKey("account:locked:" + username);
}
}

安全日志分析

// 记录安全事件
@Service
public class SecurityEventLogger {

public void logSecurityEvent(SecurityEvent event) {
// 记录到专用日志
logger.info("SECURITY_EVENT: type={}, user={}, ip={}, details={}",
event.getType(),
event.getUserId(),
event.getIpAddress(),
event.getDetails());

// 发送到 SIEM
sendToSiem(event);
}
}

漏洞管理

定期扫描

# GitLab CI 中的安全扫描
stages:
- security

dependency_scanning:
stage: security
image: node:16
script:
- npm audit --audit-level=high
allow_failure: true

container_scanning:
stage: security
image: aquasec/trivy:latest
script:
- trivy image --exit-code 1 --severity HIGH myapp:latest

sast:
stage: security
script:
- npm install -g npm-audit-html
- npm audit --json | npm-audit-html -o audit.html
artifacts:
paths:
- audit.html

漏洞响应流程

发现漏洞 → 评估严重性 → 制定修复计划 → 实施修复 → 验证修复 → 发布更新 → 事后分析

时间线示例:
- 严重漏洞(Critical):24 小时内修复
- 高危漏洞(High):7 天内修复
- 中危漏洞(Medium):30 天内修复
- 低危漏洞(Low):下个版本修复

备份与恢复

备份策略

#!/bin/bash
# backup.sh

# 数据库备份
mysqldump -u root -p database > "backup_$(date +%Y%m%d_%H%M%S).sql"

# 加密备份
gpg --symmetric --cipher-algo AES256 backup.sql

# 备份到远程存储
aws s3 cp backup.sql.gpg s3://bucket/backups/

# 验证备份
aws s3 ls s3://bucket/backups/

恢复测试

#!/bin/bash
# restore_test.sh

# 创建测试环境
docker-compose up -d

# 恢复数据
mysql -u test -p test_db < backup_latest.sql

# 验证数据完整性
echo "SELECT COUNT(*) FROM users" | mysql -u test -p test_db

# 检查应用功能
curl -f http://localhost:8080/health || exit 1

安全检查清单

部署前检查

  • 禁用调试模式
  • 配置安全日志
  • 设置安全响应头
  • 启用 HTTPS
  • 配置 HSTS
  • 更新所有依赖
  • 运行安全扫描
  • 配置防火墙规则
  • 设置安全的 Cookie
  • 禁用不必要的 HTTP 方法

日常运维检查

  • 监控安全日志
  • 检查漏洞公告
  • 更新依赖库
  • 审计访问日志
  • 验证备份完整性
  • 测试恢复流程
  • 检查 SSL 证书有效期

定期任务

任务频率
漏洞扫描每周
依赖更新每月
渗透测试每季度
安全审计每半年
备份恢复测试每月

小结

生产环境安全需要关注:

  1. 服务器配置

    • Nginx/Tomcat 安全设置
    • 安全的响应头
    • HTTPS 和 HSTS
  2. 应用配置

    • Spring Security 配置
    • 安全的会话管理
    • 日志记录
  3. 依赖管理

    • 定期漏洞扫描
    • 及时更新依赖
    • 自动化检查
  4. 监控运维

    • 安全事件监控
    • 入侵检测
    • 漏洞响应
    • 备份恢复

记住:安全不是一次性的工作,而是持续的过程!