Initial skills documentation — 25 categories, all SKILL.md + references + scripts
This commit is contained in:
@@ -0,0 +1,195 @@
|
||||
# Netcup Server Provisioning — Initial Setup
|
||||
|
||||
Covers provisioning a fresh Netcup RS VPS (Manassas) — from order confirmation email to secure, usable server.
|
||||
|
||||
## SCP REST API Authentication
|
||||
|
||||
The Netcup SCP (Server Control Panel) provides a REST API at `https://www.servercontrolpanel.de/scp-core/api/v1/`. This is distinct from the CCP (Customer Control Panel) API.
|
||||
|
||||
### Auth Flow
|
||||
|
||||
The SCP uses Keycloak (OIDC) for authentication, NOT the CCP API key / API password method.
|
||||
|
||||
**Correct auth flow (password grant):**
|
||||
|
||||
```bash
|
||||
# Step 1: Get token
|
||||
curl -s "https://www.servercontrolpanel.de/realms/scp/protocol/openid-connect/token" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "grant_type=password&client_id=scp&username=${CUSTOMER_NUMBER}&password=${CCP_PASSWORD}" \
|
||||
-o /tmp/netcup_token.json
|
||||
|
||||
TOKEN=$(jq -r '.access_token' /tmp/netcup_token.json)
|
||||
|
||||
# Step 2: Use token
|
||||
curl -s "https://www.servercontrolpanel.de/scp-core/api/v1/servers" \
|
||||
-H "Authorization: Bearer ${TOKEN}"
|
||||
```
|
||||
|
||||
**⚠️ Cron mode:** `python3 -c` and `curl | python3` are blocked by the security scanner in cron. Use `jq` (as shown above) and two-step file approach instead of pipes.
|
||||
|
||||
### Key Details
|
||||
|
||||
| Parameter | Value |
|
||||
|-----------|-------|
|
||||
| Auth URL | servercontrolpanel.de/realms/scp/protocol/openid-connect/token |
|
||||
| Client ID | scp (from SCP web app) |
|
||||
| Grant type | password |
|
||||
| Username | Customer number (e.g. 389212) -- NOT the CCP API key |
|
||||
| Password | CCP login password -- NOT the API password |
|
||||
| Token lifetime | 300 seconds (5 min) |
|
||||
| API base | servercontrolpanel.de/scp-core/api/v1/ |
|
||||
| Auth header | Authorization: Bearer <token> |
|
||||
|
||||
### Auth Pitfalls
|
||||
|
||||
- The CCP API Key + API Password from Master Data are for a DIFFERENT API (DNS/domain management via XML-RPC)
|
||||
- The SCP REST API uses the CCP LOGIN credentials (customer number + password), not the API keys
|
||||
- Make sure the server's IP is whitelisted in SCP -> REST API Settings, or leave the whitelist empty to allow all
|
||||
- The X-API-Key header does NOT work with the SCP API -- only Authorization: Bearer with an OIDC token
|
||||
- The correct API path is /scp-core/api/ -- NOT /scp-ui/api/ (which serves the web UI, not data)
|
||||
- scp-ui/api/v1/servers returns the HTML login page instead of JSON -- this is how it behaves when auth is missing
|
||||
|
||||
### Available Endpoints (from this account)
|
||||
|
||||
| Endpoint | Purpose | Works? |
|
||||
|----------|---------|--------|
|
||||
| GET /scp-core/api/v1/servers | List all servers | Yes |
|
||||
| GET /scp-core/api/v1/servers/{id} | Server details | Yes |
|
||||
| POST /scp-core/api/v1/templates | Provisioning | Not found |
|
||||
|
||||
The provisioning endpoints (/templates, /images) may be scoped to reseller/partner accounts only. Standard customer accounts can create/view servers but not provision new ones via API.
|
||||
|
||||
## After Order Approval
|
||||
|
||||
Netcup sends two emails:
|
||||
1. **SCP access** — `https://www.servercontrolpanel.de/SCP/` with username + password
|
||||
2. **Server ready** — IP address, root password, hostname, OS info
|
||||
|
||||
### Data Processing Agreement (DPA)
|
||||
|
||||
New accounts must complete a DPA before payment processes. Standard EU GDPR boilerplate:
|
||||
- Navigate CCP → Master Data → Order Processing
|
||||
- "Conclude Data Processing Agreement" — pre-filled standard text, just review and accept
|
||||
- Netcup acts as processor (Art. 28 GDPR), you as controller
|
||||
- Required even for US businesses with US customers in Manassas
|
||||
|
||||
## First SSH — Do NOT change root password before capturing it
|
||||
|
||||
**CRITICAL PITFALL:** Do NOT change the root password inside the same SSH command that creates users. If the command errors mid-way (e.g. package install fails), the new password was set but never captured in the output. The original email password no longer works, and the server is unreachable.
|
||||
|
||||
**Correct procedure:**
|
||||
|
||||
```bash
|
||||
# Step 1: SSH in with original password, deploy SSH key immediately
|
||||
sshpass -p '<original-root-pw>' ssh -o StrictHostKeyChecking=accept-new root@<server-ip> '
|
||||
set -e
|
||||
mkdir -p /root/.ssh && chmod 700 /root/.ssh
|
||||
'
|
||||
# Pipe the SSH key in a separate step
|
||||
sshpass -p '<pw>' ssh root@<server-ip> 'cat >> /root/.ssh/authorized_keys' < ~/.ssh/wisp_rsa.pub
|
||||
|
||||
# Step 2: Test key-based auth, THEN create users + change passwords
|
||||
ssh -i ~/.ssh/wisp_rsa root@<server-ip> '
|
||||
useradd -m -s /bin/bash -G sudo ippadmin
|
||||
echo "ippadmin ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/ippadmin
|
||||
mkdir -p /home/ippadmin/.ssh && chmod 700 /home/ippadmin/.ssh
|
||||
cat /root/.ssh/authorized_keys >> /home/ippadmin/.ssh/authorized_keys
|
||||
chown -R ippadmin:ippadmin /home/ippadmin/.ssh && chmod 600 /home/ippadmin/.ssh/authorized_keys
|
||||
ROOT_PASS=$(tr -dc A-Za-z0-9 < /dev/urandom | head -c 20)
|
||||
echo "root:${ROOT_PASS}" | chpasswd
|
||||
echo "New root password: ${ROOT_PASS}"
|
||||
'
|
||||
```
|
||||
|
||||
## Debian 13 (Trixie) Package Names
|
||||
|
||||
Netcup deploys Debian 13 (Trixie) minimal by default. Package names differ from Debian 12:
|
||||
|
||||
| Package | Notes |
|
||||
|---------|-------|
|
||||
| docker.io | Available (Docker 26.1.5) |
|
||||
| docker-compose-plugin | NOT in Debian 13 repos — must use Docker's apt repo |
|
||||
| python3-pip | Available |
|
||||
| python3-venv | May need `python3.13-venv` |
|
||||
| ufw | Available |
|
||||
| gnupg | Not pre-installed, needed for apt-key management |
|
||||
| unzip | Not pre-installed |
|
||||
| awscli v2 | Must install manually via `curl + unzip` |
|
||||
|
||||
### Docker Compose — Dedicated apt repo
|
||||
|
||||
```bash
|
||||
apt-get install -y gnupg
|
||||
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bookworm stable" | tee /etc/apt/sources.list.d/docker.list
|
||||
apt-get update && apt-get install -y docker-compose-plugin
|
||||
```
|
||||
|
||||
Use **bookworm** (Debian 12 codename), not trixie — Docker doesn't have a trixie-specific repo yet. The bookworm packages work on trixie.
|
||||
|
||||
### AWS CLI v2
|
||||
|
||||
```bash
|
||||
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o /tmp/awscliv2.zip
|
||||
apt-get install -y unzip
|
||||
unzip -q /tmp/awscliv2.zip -d /tmp/
|
||||
/tmp/aws/install --update
|
||||
rm -rf /tmp/aws /tmp/awscliv2.zip
|
||||
```
|
||||
|
||||
### Wasabi S3 Credentials
|
||||
|
||||
```bash
|
||||
aws configure set aws_access_key_id GYH83FP0KL0K85N60JKQ
|
||||
aws configure set aws_secret_access_key <key-from-control-box>
|
||||
aws configure set region us-east-1
|
||||
chmod 600 /root/.aws/credentials
|
||||
|
||||
# Test — note: s3:ListAllMyBuckets is NOT supported by Wasabi IAM
|
||||
aws s3 ls s3://hermes-vps-backups/ --endpoint-url https://s3.us-east-1.wasabisys.com
|
||||
```
|
||||
|
||||
### Hermes
|
||||
|
||||
```bash
|
||||
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
|
||||
```
|
||||
|
||||
## Standard Netcup SCP
|
||||
|
||||
- URL: `https://www.servercontrolpanel.de/SCP/`
|
||||
- Use for: password resets, firewall policy management, OS reinstall, boot/rescue mode
|
||||
- Netcup pre-installs a firewall policy that blocks SMTP. Remove "netcup Mail Block" policy in SCP → Firewall if email delivery is needed.
|
||||
|
||||
## Standard Admin User
|
||||
|
||||
All servers use `ippadmin` (sudo, no password) with the `wisp_rsa` Ed25519 SSH key. Root SSH login should be disabled after setup:
|
||||
|
||||
```bash
|
||||
sed -i 's/^PermitRootLogin.*/PermitRootLogin prohibit-password/' /etc/ssh/sshd_config
|
||||
sed -i 's/^#PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
|
||||
systemctl restart sshd
|
||||
```
|
||||
|
||||
## Firewall (UFW)
|
||||
|
||||
```bash
|
||||
ufw default deny incoming
|
||||
ufw default allow outgoing
|
||||
ufw allow ssh
|
||||
ufw allow http
|
||||
ufw allow https
|
||||
ufw --force enable
|
||||
```
|
||||
|
||||
## Root password safety rule
|
||||
|
||||
When setting up a new remote server:
|
||||
1. Connect with the provided password
|
||||
2. **Immediately deploy your SSH public key** first
|
||||
3. Then create users, install packages, change passwords
|
||||
4. Record new passwords in password manager
|
||||
5. Use SSH key for all future access
|
||||
|
||||
**Never change root password mid-script without capturing the output.** If the script fails before `echo "password: ${PASS}"` executes, you're locked out.
|
||||
Reference in New Issue
Block a user