Token导航 LogoToken导航

Agent Skill · 运维

ssl-setup(SSL 设置)

ssl-setup 用于辅助安全审计、权限检查和凭据风险排查,适合在 OpenClaw 中需要复核安全边界、认证流程或敏感配置时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

ssl-setup 是运维类 Agent Skill,可用宿主为 OpenClaw,通过ClawHub获取,权限为接触敏感数据;许可证为 MIT-0,第三方扫描已通过,按安装量在运维类的 954 个 Skill 里排第 729。

总安装 3,337周安装 135GitHub Stars 公开资料未说明下载 1,048核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT-0
版本
1.0.0

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:ssl-setup(SSL 设置)
来源仓库:https://github.com/llcsamih/ssl-setup
安装命令:
openclaw skills install ssl-setup
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install ssl-setup

这个 Skill 是做什么的

运维类 Skill 处理部署、监控、日志和云资源,多数需要较高的执行权限。

为 Nginx 配置 Let's Encrypt SSL 与反向代理。集成 HTTP/2、gzip 压缩与安全标头优化。适用于 VPS 上任意应用的 HTTPS 快速部署。安装命令:openclaw skills install ssl-setup。需提前准备域名解析与防火墙端口开放。

ssl-setup 属于运维类 Skill,可作为该场景下的辅助能力补充。

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 OpenClaw;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 openclaw skills install ssl-setup;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要接触敏感数据,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

ssl-setup 怎么安装?

在终端执行 openclaw skills install ssl-setup。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

ssl-setup 支持哪些 AI 工具?

公开资料标注支持 OpenClaw。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

ssl-setup 需要什么权限?

权限级别是接触敏感数据。该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

ssl-setup 是免费的吗?

来源标注的许可证是 MIT-0。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

ssl-setup 用的人多吗?

公开数据是累计安装 3,337 次,近一周安装 135 次,下载 1,048 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

ssl-setup 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 专注 OpenClaw 一种宿主,触发方式和使用习惯不用来回切换。
  • 许可证明确为 MIT-0,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 需要接触敏感数据,装到常用环境前要先评估影响面。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 OpenClaw,想直接扩展它能力的人。
  • 需要处理运维类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 环境里有大量密钥、凭证,不方便给第三方 Skill 读取的人。
  • 需要厂商级技术支持和 SLA 的生产系统。

运维类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
docker-essentials

Docker 基础 · OpenClaw

1,005,15130接触敏感数据MIT-0通过
playwright-scraper-skill

Playwright scraper 技能 · OpenClaw

923,55754接触敏感数据MIT-0有提醒
moltguard

moltguard 搜索 · OpenClaw

825,096110接触敏感数据MIT-0通过
finance-news

财经新闻 · OpenClaw

275,51210需要联网MIT-0有提醒
security-monitor

安全监视器 · OpenClaw

224,1695需要联网MIT-0有提醒
ssl-setup

SSL 设置 · 本页

3,337—接触敏感数据MIT-0通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

name
ssl-setup
description
Configure Nginx as a reverse proxy with SSL/TLS via Let's Encrypt, security headers, HTTP/2, and gzip compression for any application on any VPS. Use when the user says 'set up SSL', 'add HTTPS', 'configure Nginx', 'reverse proxy setup', 'secure my site', 'add SSL certificate', 'nginx proxy', or needs to go from HTTP to production HTTPS on a VPS.

SSL + Nginx Setup

Configure Nginx as a production-grade reverse proxy with automated SSL, security headers, and performance tuning. Works with any app, any domain, any VPS provider running Ubuntu/Debian.

When to Use

  • User wants SSL/HTTPS on a VPS-hosted application
  • User needs Nginx configured as a reverse proxy
  • User says "set up SSL", "add HTTPS", "configure Nginx", "secure my domain"
  • User has an app running on a port and needs it accessible via a domain with TLS
  • User needs to add or fix security headers
  • User needs wildcard certificates for subdomains

When NOT to Use

  • Managed platforms (Vercel, Netlify, Cloudflare Pages) -- they handle SSL automatically
  • Cloudflare-proxied domains where SSL terminates at Cloudflare (orange cloud)
  • Kubernetes ingress -- use an ingress controller instead
  • The user only needs a self-signed cert for local development

Prerequisites

  • SSH access to a VPS running Ubuntu 20.04+ or Debian 11+
  • A domain with DNS A record pointing to the VPS IP
  • An application running on a local port (e.g., 3000, 8000, 8080)
  • Ports 80 and 443 open in the firewall

Phase 1: Gather Information

Collect these before doing anything. Detect what you can, ask for the rest.

ParameterHow to detectFallback
DomainAsk the userRequired
App portCheck Dockerfile EXPOSE, docker-compose ports, or running processesAsk
VPS IPcurl -4 ifconfig.me on the serverAsk
EmailNeeded for Let's Encrypt registrationAsk
Wildcard?If user mentions subdomains or *.domain.comDefault: single domain
Extra domainswww.domain.com, other subdomainsAsk if relevant

Phase 2: Verify DNS Before Anything Else

CRITICAL: Always verify DNS first. Certbot will fail if the domain does not resolve to this server.

# Get the server's public IP
SERVER_IP=$(curl -4 -s ifconfig.me)

# Check what the domain resolves to
DOMAIN_IP=$(dig +short <DOMAIN> A | head -1)

echo "Server IP:  $SERVER_IP"
echo "Domain IP:  $DOMAIN_IP"

if [ "$SERVER_IP" = "$DOMAIN_IP" ]; then
  echo "DNS is correctly pointed."
else
  echo "ERROR: Domain does not point to this server."
  echo "Set an A record for <DOMAIN> -> $SERVER_IP at your DNS provider."
  echo "DNS propagation can take up to 48 hours (usually 5-15 minutes)."
  exit 1
fi

If DNS is not pointed, stop here. Tell the user exactly what A record to create and where. Do not proceed to Certbot -- it will fail and may trigger rate limits.

For wildcard certs, also verify the base domain resolves:

dig +short <BASE_DOMAIN> A

Phase 3: Install Dependencies

apt update
apt install -y nginx certbot python3-certbot-nginx

Verify Nginx is running:

systemctl enable nginx
systemctl start nginx
nginx -v

Phase 4: Configure Nginx Reverse Proxy

4a: Create the site configuration

SAFETY: Always back up existing configs before overwriting.

# Back up any existing config
[ -f /etc/nginx/sites-available/<DOMAIN> ] && cp /etc/nginx/sites-available/<DOMAIN> /etc/nginx/sites-available/<DOMAIN>.bak.$(date +%s)

Write the initial HTTP-only config (Certbot will upgrade it to HTTPS):

# /etc/nginx/sites-available/<DOMAIN>

server {
    listen 80;
    listen [::]:80;
    server_name <DOMAIN> <EXTRA_DOMAINS>;

    location / {
        proxy_pass http://127.0.0.1:<APP_PORT>;
        proxy_http_version 1.1;

        # WebSocket support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Preserve client information
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;

        # Timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 86400s;  # Long timeout for WebSockets

        # Buffering
        proxy_buffering on;
        proxy_buffer_size 16k;
        proxy_buffers 4 32k;
        proxy_busy_buffers_size 64k;

        proxy_cache_bypass $http_upgrade;
    }
}

4b: Enable the site

ln -sf /etc/nginx/sites-available/<DOMAIN> /etc/nginx/sites-enabled/
rm -f /etc/nginx/sites-enabled/default

4c: Test and reload

SAFETY: ALWAYS run nginx -t before reloading. Never skip this.

nginx -t
if [ $? -eq 0 ]; then
  systemctl reload nginx
  echo "Nginx reloaded successfully."
else
  echo "ERROR: Nginx config test failed. Fix the config before proceeding."
  exit 1
fi

4d: Verify HTTP is working

curl -sI http://<DOMAIN> | head -10

If this returns a non-200 response or connection refused, debug before proceeding to SSL. Common issues:

  • App not running on the expected port: ss -tlnp | grep <APP_PORT>
  • Firewall blocking port 80: ufw status
  • Nginx not running: systemctl status nginx

Phase 5: SSL Certificate via Let's Encrypt

5a: Single Domain Certificate (default)

certbot --nginx \
  -d <DOMAIN> \
  -d www.<DOMAIN> \
  --non-interactive \
  --agree-tos \
  -m <EMAIL> \
  --redirect

The --redirect flag automatically adds HTTP-to-HTTPS redirection.

5b: Wildcard Certificate (subdomains)

Wildcard certs require DNS-01 challenge. This requires manual DNS TXT record creation (or a DNS plugin for automated providers).

Manual method:

certbot certonly \
  --manual \
  --preferred-challenges dns \
  -d <BASE_DOMAIN> \
  -d *.<BASE_DOMAIN> \
  --agree-tos \
  -m <EMAIL>

Certbot will prompt to create a TXT record at _acme-challenge.<BASE_DOMAIN>. Tell the user to:

  1. Add the TXT record at their DNS provider
  2. Wait for propagation: dig TXT _acme-challenge.<BASE_DOMAIN>
  3. Press Enter in Certbot once the record propagates

Automated method (Cloudflare DNS plugin example):

apt install -y python3-certbot-dns-cloudflare

# Create credentials file
cat > /etc/letsencrypt/cloudflare.ini << 'EOF'
dns_cloudflare_api_token = <CLOUDFLARE_API_TOKEN>
EOF
chmod 600 /etc/letsencrypt/cloudflare.ini

certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d <BASE_DOMAIN> \
  -d *.<BASE_DOMAIN> \
  --agree-tos \
  -m <EMAIL>

Other DNS plugins: python3-certbot-dns-digitalocean, python3-certbot-dns-route53, python3-certbot-dns-google.

After obtaining a wildcard cert, you must manually configure Nginx to use it (Certbot's --nginx plugin does not handle wildcard certs):

ssl_certificate /etc/letsencrypt/live/<BASE_DOMAIN>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<BASE_DOMAIN>/privkey.pem;

5c: Verify SSL

# Check certificate details
echo | openssl s_client -servername <DOMAIN> -connect <DOMAIN>:443 2>/dev/null | openssl x509 -noout -dates -subject

# Check HTTPS response
curl -sI https://<DOMAIN> | head -10

# Check HTTP redirects to HTTPS
curl -sI http://<DOMAIN> | grep -i location

Phase 6: Harden the Nginx Configuration

After Certbot has modified the config, enhance it with security headers, TLS hardening, HTTP/2, and gzip.

Replace the Certbot-generated server block with this production config:

# /etc/nginx/sites-available/<DOMAIN>

# HTTP -> HTTPS redirect
server {
    listen 80;
    listen [::]:80;
    server_name <DOMAIN> <EXTRA_DOMAINS>;
    return 301 https://$host$request_uri;
}

# HTTPS server
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name <DOMAIN> <EXTRA_DOMAINS>;

    # --- SSL/TLS Configuration ---
    ssl_certificate /etc/letsencrypt/live/<DOMAIN>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<DOMAIN>/privkey.pem;

    # TLS 1.2 + 1.3 only (no legacy protocols)
    ssl_protocols TLSv1.2 TLSv1.3;

    # Strong ciphers -- TLS 1.3 ciphers are managed by OpenSSL automatically
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
    ssl_prefer_server_ciphers off;  # Let client choose (TLS 1.3 best practice)

    # Session caching for performance
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 1d;
    ssl_session_tickets off;

    # NOTE: OCSP stapling is NOT configured because Let's Encrypt
    # discontinued OCSP support in 2025. Their certificates no longer
    # include OCSP URLs. The ssl_stapling directives would have no effect.

    # --- Security Headers ---
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always;
    add_header X-XSS-Protection "0" always;  # Disabled per modern best practice (CSP replaces it)

    # Content Security Policy -- CUSTOMIZE per application
    # Start restrictive, loosen as needed. This is a reasonable default.
    add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self'; frame-ancestors 'self'; base-uri 'self'; form-action 'self';" always;

    # --- Gzip Compression ---
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_min_length 256;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml
        application/xml+rss
        application/xhtml+xml
        application/atom+xml
        image/svg+xml
        font/woff2;

    # --- Reverse Proxy ---
    location / {
        proxy_pass http://127.0.0.1:<APP_PORT>;
        proxy_http_version 1.1;

        # WebSocket support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Preserve client information
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Port $server_port;

        # Timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 86400s;

        # Buffering
        proxy_buffering on;
        proxy_buffer_size 16k;
        proxy_buffers 4 32k;
        proxy_busy_buffers_size 64k;

        proxy_cache_bypass $http_upgrade;
    }

    # Block dotfiles (except .well-known for ACME challenges)
    location ~ /\.(?!well-known) {
        deny all;
    }

    # Favicon and robots.txt -- suppress logging
    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }
}

After writing the hardened config:

nginx -t && systemctl reload nginx

Phase 7: Auto-Renewal

Certbot installs a systemd timer or cron job automatically. Verify it exists and add a deploy hook to reload Nginx after renewal:

# Check the renewal timer
systemctl list-timers | grep certbot

# Add deploy hook so Nginx picks up new certs
cat > /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh << 'EOF'
#!/bin/bash
nginx -t && systemctl reload nginx
EOF
chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh

# Test renewal (dry run)
certbot renew --dry-run

If the timer does not exist, create a cron job:

echo "0 3 * * * root certbot renew --quiet --deploy-hook 'nginx -t && systemctl reload nginx'" > /etc/cron.d/certbot-renew

Phase 8: Verification Checklist

Run all of these and report results to the user:

echo "=== SSL Certificate ==="
echo | openssl s_client -servername <DOMAIN> -connect <DOMAIN>:443 2>/dev/null | openssl x509 -noout -dates -subject

echo ""
echo "=== HTTPS Response ==="
curl -sI https://<DOMAIN> | head -15

echo ""
echo "=== HTTP Redirect ==="
curl -sI http://<DOMAIN> | grep -i "location\|HTTP"

echo ""
echo "=== Security Headers ==="
curl -sI https://<DOMAIN> | grep -iE "strict-transport|x-frame|x-content-type|referrer-policy|permissions-policy|content-security"

echo ""
echo "=== TLS Version ==="
echo | openssl s_client -servername <DOMAIN> -connect <DOMAIN>:443 2>/dev/null | grep "Protocol"

echo ""
echo "=== Nginx Status ==="
systemctl is-active nginx

echo ""
echo "=== Certbot Renewal Timer ==="
systemctl list-timers | grep certbot

Report to the user:

  • Whether HTTPS is working with the certificate details
  • Whether HTTP correctly redirects to HTTPS
  • Which security headers are present
  • TLS version in use
  • Whether auto-renewal is configured
  • The live URL

Safety Rules

  1. ALWAYS verify DNS points to the server before running Certbot. Failed attempts count against Let's Encrypt rate limits (5 failures per hostname per hour).
  2. ALWAYS run nginx -t before systemctl reload nginx. A bad config takes down all sites on the server.
  3. ALWAYS back up existing Nginx configs before overwriting them.
  4. NEVER delete /etc/letsencrypt/ contents. Certificates, keys, and renewal configs live there.
  5. NEVER use systemctl restart nginx when reload will do. Restart causes downtime; reload is zero-downtime.
  6. NEVER set HSTS preload without explicit user consent. Preload is irreversible -- once submitted to the HSTS preload list, the domain must serve HTTPS forever.
  7. ALWAYS check if port 80/443 are free before installing Nginx: ss -tlnp | grep -E ':80|:443'. Apache or another Nginx instance may already be bound.
  8. ALWAYS verify the app is actually running on the expected port before configuring the proxy: curl -s http://127.0.0.1:<APP_PORT>/.
  9. CSP headers will break apps if too restrictive. Start with a permissive policy and tighten. When in doubt, set CSP in report-only mode first: Content-Security-Policy-Report-Only.
  10. If anything fails, stop and diagnose. Do not chain workarounds.

Troubleshooting

DNS not pointing to server

dig +short <DOMAIN> A
# Compare with: curl -4 -s ifconfig.me

Fix: Add/update the A record at the DNS provider. Wait for propagation (check with dig).

Port conflict on 80 or 443

ss -tlnp | grep -E ':80|:443'
# or
lsof -i :80

Fix: Stop the conflicting service (systemctl stop apache2) or change its port.

Certbot fails with "too many failed authorizations"

Let's Encrypt rate limits: 5 failed validations per hostname per hour. Fix: Wait an hour. Verify DNS is correct before retrying.

Certbot fails with "connection refused" or "timeout"

Fix: Ensure port 80 is open in firewall (ufw allow 80/tcp) and Nginx is running on port 80.

Certificate renewal fails

certbot renew --dry-run
journalctl -u certbot.service --no-pager -n 50

Fix: Usually DNS changed, port 80 is blocked, or Nginx is down. Check all three.

502 Bad Gateway

The app is not responding on the proxy_pass port.

curl -s http://127.0.0.1:<APP_PORT>/
systemctl status <APP_SERVICE>
docker ps  # if dockerized
docker logs <CONTAINER>

Fix: Start or restart the app. Verify the port matches the Nginx config.

504 Gateway Timeout

The app is too slow to respond. Fix: Increase proxy_read_timeout in the Nginx config, or investigate app performance.

Mixed content warnings in browser

The app generates HTTP URLs instead of HTTPS. Fix: Ensure the app reads X-Forwarded-Proto header and generates HTTPS URLs. Many frameworks have a "trust proxy" setting (Express: app.set('trust proxy', true)).

Security headers breaking the app

Overly restrictive CSP or X-Frame-Options can break embedded content, iframes, or third-party scripts. Fix: Temporarily switch CSP to report-only mode, check the browser console for violations, and adjust the policy:

add_header Content-Security-Policy-Report-Only "..." always;

Wildcard cert renewal fails (manual DNS challenge)

Manual DNS challenges cannot auto-renew. You must use a DNS plugin for automation. Fix: Install the appropriate DNS plugin (python3-certbot-dns-cloudflare, etc.) and reconfigure with certbot certonly --dns-<provider>.


Multiple Domains on One Server

To add another domain to the same server, repeat Phases 2-7 for the new domain. Each domain gets its own file in /etc/nginx/sites-available/. Certbot manages certificates independently per domain.

# List all active sites
ls -la /etc/nginx/sites-enabled/

# List all certificates
certbot certificates

CSP Reference (Customize Per App)

The default CSP in this skill is restrictive. Common adjustments:

App typeCSP additions needed
Next.jsscript-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline';
React SPAscript-src 'self' 'unsafe-inline';
WordPressscript-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';
Uses Google Fontsfont-src 'self' fonts.gstatic.com; style-src 'self' 'unsafe-inline' fonts.googleapis.com;
Uses analyticsscript-src 'self' www.googletagmanager.com; connect-src 'self' www.google-analytics.com;
Embeds YouTubeframe-src 'self' www.youtube.com;

When unsure, deploy with Content-Security-Policy-Report-Only first and monitor the browser console.

平台分布

OpenClaw

73.75%
按下载量换算773

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

接触敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills