Compare commits
7 Commits
6578e93a16
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f450aa809 | |||
| 6c992a8d90 | |||
| 5f4594f882 | |||
| 29e169cbd5 | |||
| 3ec52f2aea | |||
| 30f4ebbd6d | |||
| 17a0346aa8 |
@@ -6,7 +6,7 @@ on:
|
|||||||
- 'v*'
|
- 'v*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build-and-release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
@@ -65,68 +65,58 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
go build -ldflags "-X main.Version=${VERSION} -X main.BuildTime=${BUILD_TIME}" \
|
go build -ldflags "-X main.Version=${VERSION} -X main.BuildTime=${BUILD_TIME}" \
|
||||||
-o bin/${OUTPUT_NAME} ./cmd/safelineApi
|
-o bin/${OUTPUT_NAME} ./cmd/safelineApi
|
||||||
echo "BINARY_PATH=bin/${OUTPUT_NAME}" >> $GITHUB_ENV
|
|
||||||
echo "BINARY_NAME=${OUTPUT_NAME}" >> $GITHUB_ENV
|
echo "BINARY_NAME=${OUTPUT_NAME}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Create release assets directory
|
- name: Create Release (first run only)
|
||||||
run: |
|
run: |
|
||||||
mkdir -p release-assets
|
VERSION="${{ steps.version.outputs.VERSION }}"
|
||||||
cp ${{ env.BINARY_PATH }} release-assets/
|
REPO="${{ gitea.repository }}"
|
||||||
|
SERVER="${{ gitea.server_url }}"
|
||||||
|
TOKEN="${{ secrets.GITEA_TOKEN }}"
|
||||||
|
|
||||||
|
# Check if release exists
|
||||||
|
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" "${SERVER}/api/v1/repos/${REPO}/releases/tags/${VERSION}" \
|
||||||
|
-H "Authorization: token ${TOKEN}")
|
||||||
|
|
||||||
|
if [ "$RESPONSE" = "404" ]; then
|
||||||
|
# Create release if it doesn't exist
|
||||||
|
curl -X POST "${SERVER}/api/v1/repos/${REPO}/releases" \
|
||||||
|
-H "Authorization: token ${TOKEN}" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"tag_name": "'${VERSION}'",
|
||||||
|
"name": "Release '${VERSION}'",
|
||||||
|
"body": "# SafelineAPI '${VERSION}'\n\n## Available Downloads\n\n### Linux\n- **amd64**: safelineApi-linux-amd64\n- **ARM64**: safelineApi-linux-arm64\n- **ARMv7**: safelineApi-linux-armv7\n- **386**: safelineApi-linux-386\n- **PowerPC 64LE**: safelineApi-linux-ppc64le\n\n### Windows\n- **amd64**: safelineApi-windows-amd64.exe\n- **386**: safelineApi-windows-386.exe",
|
||||||
|
"draft": false,
|
||||||
|
"prerelease": false
|
||||||
|
}'
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Release checked/created"
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload Binary Asset
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: ${{ matrix.name }}
|
|
||||||
path: release-assets/${{ env.BINARY_NAME }}
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
release:
|
|
||||||
needs: build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Download all artifacts
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
path: release-artifacts
|
|
||||||
|
|
||||||
- name: Get version
|
|
||||||
id: version
|
|
||||||
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Flatten artifacts
|
|
||||||
run: |
|
run: |
|
||||||
mkdir -p final-release
|
VERSION="${{ steps.version.outputs.VERSION }}"
|
||||||
find release-artifacts -type f -exec mv {} final-release/ \;
|
REPO="${{ gitea.repository }}"
|
||||||
ls -la final-release/
|
SERVER="${{ gitea.server_url }}"
|
||||||
|
TOKEN="${{ secrets.GITEA_TOKEN }}"
|
||||||
- name: Create Release
|
BINARY="${{ env.BINARY_NAME }}"
|
||||||
uses: gitea-github-actions/actions/gitea-release@main
|
|
||||||
with:
|
# Get release data
|
||||||
files: final-release/*
|
RELEASE_DATA=$(curl -s "${SERVER}/api/v1/repos/${REPO}/releases/tags/${VERSION}" \
|
||||||
draft: false
|
-H "Authorization: token ${TOKEN}")
|
||||||
prerelease: false
|
|
||||||
title: Release ${{ steps.version.outputs.VERSION }}
|
RELEASE_ID=$(echo "$RELEASE_DATA" | grep -o '"id":[0-9]*' | head -1 | grep -o '[0-9]*')
|
||||||
body: |
|
|
||||||
# SafelineAPI ${{ steps.version.outputs.VERSION }}
|
if [ -z "$RELEASE_ID" ]; then
|
||||||
|
echo "Failed to get release ID"
|
||||||
## Available Downloads
|
echo "$RELEASE_DATA"
|
||||||
|
exit 1
|
||||||
### Linux
|
fi
|
||||||
- **amd64**: safelineApi-linux-amd64
|
|
||||||
- **ARM64**: safelineApi-linux-arm64
|
echo "Uploading $BINARY to release $RELEASE_ID"
|
||||||
- **ARMv7**: safelineApi-linux-armv7
|
|
||||||
- **386**: safelineApi-linux-386
|
# Upload the binary
|
||||||
- **PowerPC 64LE**: safelineApi-linux-ppc64le
|
curl -X POST "${SERVER}/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets" \
|
||||||
|
-H "Authorization: token ${TOKEN}" \
|
||||||
### Windows
|
-F "attachment=@bin/${BINARY}"
|
||||||
- **amd64**: safelineApi-windows-amd64.exe
|
|
||||||
- **386**: safelineApi-windows-386.exe
|
|
||||||
|
|
||||||
Built at: ${{ github.event.head_commit.timestamp }}
|
|
||||||
env:
|
|
||||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
|
||||||
GITEA_SERVER: ${{ gitea.server_url }}
|
|
||||||
|
|||||||
412
INSTALL.md
Normal file
412
INSTALL.md
Normal file
@@ -0,0 +1,412 @@
|
|||||||
|
# SafelineAPI - Installation & Setup Guide
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
1. [Requirements](#requirements)
|
||||||
|
2. [Option 1: Using Pre-Built Releases](#option-1-using-pre-built-releases)
|
||||||
|
3. [Option 2: Building from Source](#option-2-building-from-source)
|
||||||
|
4. [Configuration](#configuration)
|
||||||
|
5. [Running on Linux](#running-on-linux)
|
||||||
|
6. [Running on Windows](#running-on-windows)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
### For Using Pre-Built Releases
|
||||||
|
- **Linux**: glibc-based distributions (most common Linux distros)
|
||||||
|
- **Windows**: Windows 7 or later (64-bit or 32-bit)
|
||||||
|
- A SafeLine API token
|
||||||
|
- Credentials for your DNS provider (Cloudflare, Tencent Cloud, Aliyun, Huawei Cloud, or WestCN)
|
||||||
|
|
||||||
|
### For Building from Source
|
||||||
|
- **Go**: Version 1.23 or later ([download here](https://go.dev/dl/))
|
||||||
|
- **Git**: For cloning the repository
|
||||||
|
- A SafeLine API token
|
||||||
|
- DNS provider credentials
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Option 1: Using Pre-Built Releases
|
||||||
|
|
||||||
|
### Step 1: Download the Binary
|
||||||
|
|
||||||
|
Go to the [Releases page](../../releases) and download the appropriate binary for your system:
|
||||||
|
|
||||||
|
**Linux:**
|
||||||
|
- `safelineApi-linux-amd64` - Most common, Intel/AMD 64-bit
|
||||||
|
- `safelineApi-linux-arm64` - ARM 64-bit (Apple Silicon, newer ARM servers)
|
||||||
|
- `safelineApi-linux-armv7` - ARM 32-bit (Raspberry Pi, older ARM)
|
||||||
|
- `safelineApi-linux-386` - 32-bit Intel/AMD
|
||||||
|
- `safelineApi-linux-ppc64le` - PowerPC 64-bit
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
- `safelineApi-windows-amd64.exe` - 64-bit (most common)
|
||||||
|
- `safelineApi-windows-386.exe` - 32-bit
|
||||||
|
|
||||||
|
### Step 2: Make it Executable (Linux only)
|
||||||
|
```bash
|
||||||
|
chmod +x safelineApi-linux-amd64
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Prepare Configuration
|
||||||
|
See [Configuration](#configuration) section below.
|
||||||
|
|
||||||
|
### Step 4: Run or Install as Service
|
||||||
|
See [Running on Linux](#running-on-linux) or [Running on Windows](#running-on-windows) sections.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Option 2: Building from Source
|
||||||
|
|
||||||
|
### Step 1: Clone the Repository
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/yourusername/SafelineAPI.git
|
||||||
|
cd SafelineAPI
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 2: Install Dependencies
|
||||||
|
```bash
|
||||||
|
go mod download
|
||||||
|
go mod tidy
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Build the Binary
|
||||||
|
|
||||||
|
**For Linux:**
|
||||||
|
```bash
|
||||||
|
# Build for your current system
|
||||||
|
make build
|
||||||
|
|
||||||
|
# Build for all platforms
|
||||||
|
make build-all
|
||||||
|
```
|
||||||
|
|
||||||
|
**For Windows (PowerShell):**
|
||||||
|
```powershell
|
||||||
|
# Build for current system
|
||||||
|
go build -o safelineApi.exe ./cmd/safelineApi
|
||||||
|
|
||||||
|
# Build for all platforms
|
||||||
|
@"
|
||||||
|
`$goos = @('linux', 'windows')
|
||||||
|
`$goarch = @('amd64', '386', 'arm64')
|
||||||
|
foreach (`$os in `$goos) {
|
||||||
|
foreach (`$arch in `$goarch) {
|
||||||
|
`$env:GOOS = `$os
|
||||||
|
`$env:GOARCH = `$arch
|
||||||
|
`$ext = if (`$os -eq 'windows') { '.exe' } else { '' }
|
||||||
|
go build -o bin/safelineApi-`${os}-`${arch}`${ext} ./cmd/safelineApi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"@ | powershell -NoProfile -
|
||||||
|
```
|
||||||
|
|
||||||
|
**For macOS:**
|
||||||
|
```bash
|
||||||
|
go build -o safelineApi ./cmd/safelineApi
|
||||||
|
```
|
||||||
|
|
||||||
|
The binary will be created in the `bin/` directory or current directory.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Step 1: Create Configuration File
|
||||||
|
|
||||||
|
Copy the example configuration:
|
||||||
|
```bash
|
||||||
|
# Linux/macOS
|
||||||
|
cp config.example.json config.json
|
||||||
|
|
||||||
|
# Windows (PowerShell)
|
||||||
|
Copy-Item config.example.json config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 2: Edit Configuration
|
||||||
|
|
||||||
|
Open `config.json` and fill in your details:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"SafeLine": {
|
||||||
|
"Host": {
|
||||||
|
"HostName": "your-safeline-host.com",
|
||||||
|
"Port": "1443"
|
||||||
|
},
|
||||||
|
"ApiToken": "your-api-token-here"
|
||||||
|
},
|
||||||
|
"ApplyCert": {
|
||||||
|
"Days": 30,
|
||||||
|
"Email": "your-email@example.com",
|
||||||
|
"SavePath": "/tmp/ssl",
|
||||||
|
"DNSProviderConfig": {
|
||||||
|
"DNSProvider": "Cloudflare",
|
||||||
|
"Cloudflare": {
|
||||||
|
"APIToken": "your-cloudflare-scoped-token"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important:**
|
||||||
|
- `SafeLine.Host.HostName`: Your SafeLine instance hostname
|
||||||
|
- `SafeLine.ApiToken`: Your SafeLine API token
|
||||||
|
- `ApplyCert.Email`: Email for Let's Encrypt notifications
|
||||||
|
- `ApplyCert.SavePath`: Where to save certificates (Linux: `/opt/safelineapi/certs`, Windows: `C:\SafelineAPI\certs`)
|
||||||
|
- `DNSProvider`: Set to `Cloudflare` (additional providers coming in future versions)
|
||||||
|
- `Cloudflare.APIToken`: Your scoped Cloudflare API token with `Zone:DNS:Edit` permissions
|
||||||
|
|
||||||
|
See [CONFIGURATION.md](docs/CONFIGURATION.md) for detailed configuration options.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Running on Linux
|
||||||
|
|
||||||
|
### Option A: Manual Run
|
||||||
|
|
||||||
|
**1. Navigate to the binary location:**
|
||||||
|
```bash
|
||||||
|
cd /path/to/safelineapi
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. Run with configuration file:**
|
||||||
|
```bash
|
||||||
|
./safelineApi-linux-amd64 config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
**3. Check the output:**
|
||||||
|
```
|
||||||
|
[INFO] Starting SafelineAPI...
|
||||||
|
[INFO] Loaded configuration from config.json
|
||||||
|
[INFO] Connecting to SafeLine instance...
|
||||||
|
[INFO] Found X certificates to update
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option B: Install as Systemd Service (Recommended)
|
||||||
|
|
||||||
|
**1. Create service user (optional but recommended):**
|
||||||
|
```bash
|
||||||
|
sudo useradd -r -s /bin/false safeline
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. Set up directories:**
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /opt/safelineapi
|
||||||
|
sudo mkdir -p /opt/safelineapi/certs
|
||||||
|
sudo mkdir -p /var/log/safelineapi
|
||||||
|
```
|
||||||
|
|
||||||
|
**3. Copy files:**
|
||||||
|
```bash
|
||||||
|
# Copy binary
|
||||||
|
sudo cp safelineApi-linux-amd64 /opt/safelineapi/safelineApi
|
||||||
|
sudo chmod +x /opt/safelineapi/safelineApi
|
||||||
|
|
||||||
|
# Copy configuration
|
||||||
|
sudo cp config.json /opt/safelineapi/config.json
|
||||||
|
sudo chmod 600 /opt/safelineapi/config.json # Only readable by owner
|
||||||
|
|
||||||
|
# Set ownership
|
||||||
|
sudo chown -R safeline:safeline /opt/safelineapi
|
||||||
|
sudo chown -R safeline:safeline /var/log/safelineapi
|
||||||
|
```
|
||||||
|
|
||||||
|
**4. Create systemd service file:**
|
||||||
|
|
||||||
|
Create `/etc/systemd/system/safelineapi.service`:
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=SafelineAPI Service
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
WorkingDirectory=/opt/safelineapi
|
||||||
|
ExecStart=/opt/safelineapi/safelineApi config.json
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=5
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
User=safeline
|
||||||
|
Group=safeline
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
**5. Enable and start the service:**
|
||||||
|
```bash
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
sudo systemctl enable safelineapi
|
||||||
|
sudo systemctl start safelineapi
|
||||||
|
```
|
||||||
|
|
||||||
|
**6. Check status:**
|
||||||
|
```bash
|
||||||
|
sudo systemctl status safelineapi
|
||||||
|
sudo journalctl -u safelineapi -f # Follow logs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option C: Run with Cron (for periodic updates)
|
||||||
|
|
||||||
|
Add to crontab:
|
||||||
|
```bash
|
||||||
|
crontab -e
|
||||||
|
|
||||||
|
# Run every day at 2 AM
|
||||||
|
0 2 * * * /opt/safelineapi/safelineApi /opt/safelineapi/config.json >> /var/log/safelineapi/cron.log 2>&1
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Running on Windows
|
||||||
|
|
||||||
|
### Option A: Manual Run (Command Prompt or PowerShell)
|
||||||
|
|
||||||
|
**1. Open Command Prompt or PowerShell**
|
||||||
|
|
||||||
|
**2. Navigate to the folder with the binary:**
|
||||||
|
```powershell
|
||||||
|
cd "C:\Program Files\SafelineAPI"
|
||||||
|
```
|
||||||
|
|
||||||
|
**3. Run the application:**
|
||||||
|
```powershell
|
||||||
|
# With config file
|
||||||
|
.\safelineApi-windows-amd64.exe config.json
|
||||||
|
|
||||||
|
# Or use interactive mode
|
||||||
|
.\safelineApi-windows-amd64.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
**4. Expected output:**
|
||||||
|
```
|
||||||
|
[INFO] Starting SafelineAPI...
|
||||||
|
[INFO] Loaded configuration from config.json
|
||||||
|
[INFO] Connecting to SafeLine instance...
|
||||||
|
[INFO] Found X certificates to update
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option B: Install as Windows Service (Recommended)
|
||||||
|
|
||||||
|
**Using NSSM (Non-Sucking Service Manager):**
|
||||||
|
|
||||||
|
**1. Download NSSM:**
|
||||||
|
- Download from https://nssm.cc/download
|
||||||
|
- Extract to a folder in PATH or note the full path
|
||||||
|
|
||||||
|
**2. Open PowerShell as Administrator**
|
||||||
|
|
||||||
|
**3. Install the service:**
|
||||||
|
```powershell
|
||||||
|
# If nssm is in PATH
|
||||||
|
nssm install SafelineAPI "C:\Program Files\SafelineAPI\safelineApi-windows-amd64.exe" "C:\Program Files\SafelineAPI\config.json"
|
||||||
|
|
||||||
|
# Or with full path to nssm
|
||||||
|
"C:\Path\To\nssm.exe" install SafelineAPI "C:\Program Files\SafelineAPI\safelineApi-windows-amd64.exe" "C:\Program Files\SafelineAPI\config.json"
|
||||||
|
```
|
||||||
|
|
||||||
|
**4. Start the service:**
|
||||||
|
```powershell
|
||||||
|
nssm start SafelineAPI
|
||||||
|
```
|
||||||
|
|
||||||
|
**5. Check status:**
|
||||||
|
```powershell
|
||||||
|
nssm status SafelineAPI
|
||||||
|
```
|
||||||
|
|
||||||
|
**6. View logs:**
|
||||||
|
```powershell
|
||||||
|
# NSSM logs to Event Viewer by default
|
||||||
|
# Or check the log file NSSM creates (path shown in service properties)
|
||||||
|
```
|
||||||
|
|
||||||
|
**7. Stop the service:**
|
||||||
|
```powershell
|
||||||
|
nssm stop SafelineAPI
|
||||||
|
```
|
||||||
|
|
||||||
|
**8. Uninstall the service:**
|
||||||
|
```powershell
|
||||||
|
nssm remove SafelineAPI confirm
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option C: Windows Task Scheduler (Alternative)
|
||||||
|
|
||||||
|
**1. Open Task Scheduler** (Win+R → `taskschd.msc`)
|
||||||
|
|
||||||
|
**2. Create Basic Task:**
|
||||||
|
- Name: SafelineAPI
|
||||||
|
- Trigger: Daily at 2 AM
|
||||||
|
- Action: Start program
|
||||||
|
- Program: `C:\Program Files\SafelineAPI\safelineApi-windows-amd64.exe`
|
||||||
|
- Arguments: `C:\Program Files\SafelineAPI\config.json`
|
||||||
|
|
||||||
|
**3. Configure permissions:**
|
||||||
|
- General tab → "Run with highest privileges" (optional)
|
||||||
|
- Run whether user is logged in or not
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Application Won't Start
|
||||||
|
- **Check config.json syntax:** Use an online JSON validator
|
||||||
|
- **Check file permissions:** Ensure the application can read `config.json`
|
||||||
|
- **Check SafeLine API token:** Verify it's correct and hasn't expired
|
||||||
|
- **Check network:** Ensure you can reach your SafeLine instance
|
||||||
|
|
||||||
|
### Service Won't Start (Linux)
|
||||||
|
```bash
|
||||||
|
# Check logs
|
||||||
|
sudo journalctl -u safelineapi -n 50
|
||||||
|
|
||||||
|
# Check service status
|
||||||
|
sudo systemctl status safelineapi
|
||||||
|
|
||||||
|
# Manually run to see errors
|
||||||
|
sudo -u safeline /opt/safelineapi/safelineApi /opt/safelineapi/config.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Service Won't Start (Windows)
|
||||||
|
```powershell
|
||||||
|
# Check NSSM status
|
||||||
|
nssm status SafelineAPI
|
||||||
|
|
||||||
|
# Check event logs
|
||||||
|
Get-EventLog -LogName Application -Source SafelineAPI -Newest 10
|
||||||
|
```
|
||||||
|
|
||||||
|
### DNS Provider Issues
|
||||||
|
See [CONFIGURATION.md](docs/CONFIGURATION.md) for DNS provider-specific setup.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Best Practices
|
||||||
|
|
||||||
|
1. **Protect config.json:**
|
||||||
|
- Linux: `sudo chmod 600 /opt/safelineapi/config.json`
|
||||||
|
- Windows: Set ACL to allow only service user
|
||||||
|
|
||||||
|
2. **Use environment variables (optional):**
|
||||||
|
```bash
|
||||||
|
export SAFELINE_API_TOKEN="your-token"
|
||||||
|
export SAFELINE_HOST="your-host"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Use scoped API tokens** where possible (e.g., Cloudflare scoped tokens)
|
||||||
|
|
||||||
|
4. **Keep certificates secure:**
|
||||||
|
- Ensure `SavePath` directory is not world-readable
|
||||||
|
- Regularly back up certificates
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Getting Help
|
||||||
|
|
||||||
|
- Check [CONFIGURATION.md](docs/CONFIGURATION.md) for configuration details
|
||||||
|
- Check [cloudflare.md](docs/cloudflare.md) for Cloudflare-specific setup
|
||||||
|
- Create an issue on GitHub/Gitea for bugs
|
||||||
150
README.md
150
README.md
@@ -1,78 +1,108 @@
|
|||||||
SafelineAPI
|
# SafelineAPI
|
||||||
=================
|
|
||||||
|
|
||||||
Small CLI to request and upsert TLS certificates (DNS-01) with multiple DNS provider backends. This repo now includes Cloudflare DNS provider support via the lego provider.
|
A lightweight CLI tool that automatically manages TLS/SSL certificates for SafeLine instances using DNS-01 validation. It supports multiple DNS providers, making it easy to automate certificate renewal and updates across your infrastructure.
|
||||||
|
|
||||||
## Prerequisites
|
## What It Does
|
||||||
- Go toolchain (only required to build from source)
|
|
||||||
- A SafeLine API token (set in `config.json`)
|
|
||||||
- Cloudflare API token (scoped) or Global API key + account email
|
|
||||||
|
|
||||||
## Quick start
|
SafelineAPI simplifies TLS certificate management by:
|
||||||
|
- **Automatically requesting new certificates** from Let's Encrypt using DNS-01 validation
|
||||||
|
- **Updating existing certificates** in your SafeLine WAF instance
|
||||||
|
- **Supporting multiple DNS providers** (Cloudflare)
|
||||||
|
- **Running as a scheduled service** on Linux (systemd) or Windows
|
||||||
|
- **Checking certificate expiration** and renewing before they expire
|
||||||
|
|
||||||
1. Copy `config.example.json` to `config.json` and fill in your values.
|
Perfect for users who want hands-off certificate management integrated with SafeLine!
|
||||||
|
|
||||||
2. Build (optional):
|
## Quick Start
|
||||||
```powershell
|
|
||||||
cd C:\Users\samge\coding\SafelineAPI-1
|
|
||||||
go build -o safelineApi.exe ./cmd/safelineApi
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Run:
|
### Download & Run (Easiest)
|
||||||
```powershell
|
|
||||||
# using built binary
|
|
||||||
.\safelineApi.exe
|
|
||||||
|
|
||||||
# or directly with go
|
1. **Download a pre-built binary** from [Releases](../../releases)
|
||||||
go run ./cmd/safelineApi -- -t "<SafeLineApiToken>" -D "Cloudflare" -e "you@example.com"
|
2. **Follow the setup guide** → see [INSTALL.md](INSTALL.md)
|
||||||
```
|
|
||||||
|
|
||||||
Configuration notes
|
### Or Build from Source
|
||||||
- The main configuration file is `config.json` in the project root.
|
|
||||||
- To use Cloudflare for DNS-01, set `ApplyCert.DNSProviderConfig.DNSProvider` to `Cloudflare` and set `ApplyCert.DNSProviderConfig.Cloudflare.APIToken` to a scoped API token with `Zone:DNS:Edit` permission.
|
|
||||||
- If you must use the global API key, set `Cloudflare.APIKey` and `Cloudflare.Email` instead (less secure).
|
|
||||||
|
|
||||||
Docs
|
|
||||||
- See `docs/CONFIGURATION.md` for detailed configuration and troubleshooting steps.
|
|
||||||
- See `docs/cloudflare.md` for a short Cloudflare-specific guide.
|
|
||||||
|
|
||||||
Security
|
|
||||||
- Prefer scoped API tokens over global keys.
|
|
||||||
- Keep `config.json` out of source control; use environment variables or secret management in production.
|
|
||||||
|
|
||||||
Need anything else?
|
|
||||||
- I can add a small PowerShell script to run the app with environment variable support or create a release artifact (Windows exe) if you'd like.
|
|
||||||
|
|
||||||
Linux usage (systemd)
|
|
||||||
|
|
||||||
Most users run this on a Linux host. Below are recommended steps to install and run SafelineAPI as a service.
|
|
||||||
|
|
||||||
1. Build on the target machine (or cross-compile):
|
|
||||||
```bash
|
```bash
|
||||||
cd /opt
|
git clone <your-repo-url>
|
||||||
git clone <your-repo-url> safelineapi
|
cd SafelineAPI
|
||||||
cd safelineapi
|
|
||||||
go build -o safelineApi ./cmd/safelineApi
|
go build -o safelineApi ./cmd/safelineApi
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Place your `config.json` in `/opt/safelineapi/config.json` (or edit accordingly). You can use `config.example.json` as a starting point.
|
## Installation & Setup
|
||||||
|
|
||||||
|
For detailed setup instructions, see **[INSTALL.md](INSTALL.md)** which covers:
|
||||||
|
- ✅ Using pre-built release binaries
|
||||||
|
- ✅ Building from source (Linux, Windows, macOS)
|
||||||
|
- ✅ Configuring the application
|
||||||
|
- ✅ Running as a service on Linux (systemd)
|
||||||
|
- ✅ Running as a service on Windows (NSSM, Task Scheduler)
|
||||||
|
- ✅ Troubleshooting
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
1. Copy `config.example.json` to `config.json`
|
||||||
|
2. Fill in your SafeLine API token and DNS provider credentials
|
||||||
|
3. Run with: `./safelineApi config.json`
|
||||||
|
|
||||||
|
For detailed configuration options, see [docs/CONFIGURATION.md](docs/CONFIGURATION.md)
|
||||||
|
|
||||||
|
## DNS Provider
|
||||||
|
|
||||||
|
Currently supports:
|
||||||
|
- **Cloudflare** - Primary DNS provider
|
||||||
|
|
||||||
|
Additional providers can be added in the future. See [docs/cloudflare.md](docs/cloudflare.md) for Cloudflare setup instructions.
|
||||||
|
|
||||||
|
## Security Best Practices
|
||||||
|
|
||||||
|
- ✅ Use **scoped API tokens** instead of global keys (especially for Cloudflare)
|
||||||
|
- ✅ Keep `config.json` **out of source control**
|
||||||
|
- ✅ Restrict file permissions on `config.json` (600 on Linux)
|
||||||
|
- ✅ Run the service as an **unprivileged user**
|
||||||
|
- ✅ Use environment variables or secret management in production
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- [INSTALL.md](INSTALL.md) - Complete installation and setup guide
|
||||||
|
- [CONFIGURATION.md](docs/CONFIGURATION.md) - Detailed configuration reference
|
||||||
|
- [cloudflare.md](docs/cloudflare.md) - Cloudflare-specific setup guide
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Prerequisites (for building from source)
|
||||||
|
- Go 1.23 or later
|
||||||
|
- Git
|
||||||
|
|
||||||
|
### Build Commands
|
||||||
|
|
||||||
3. Install systemd unit (example unit available at `contrib/safelineapi.service`):
|
|
||||||
```bash
|
```bash
|
||||||
sudo cp contrib/safelineapi.service /etc/systemd/system/
|
# Build for current platform
|
||||||
sudo useradd --system --no-create-home safeline || true
|
make build
|
||||||
sudo chown -R safeline:safeline /opt/safelineapi
|
|
||||||
sudo systemctl daemon-reload
|
# Build for all platforms (Linux & Windows)
|
||||||
sudo systemctl enable --now safelineapi.service
|
make build-all
|
||||||
sudo journalctl -u safelineapi.service -f
|
|
||||||
|
# Run tests
|
||||||
|
make test
|
||||||
|
|
||||||
|
# Format code
|
||||||
|
make fmt
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Alternatively run with the provided helper script (uses environment variables or builds if missing):
|
## Automated Releases
|
||||||
```bash
|
|
||||||
chmod +x scripts/run.sh
|
|
||||||
SAFELINE_API_TOKEN="..." DNS_PROVIDER=Cloudflare CONTACT_EMAIL="you@example.com" ./scripts/run.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
Notes
|
This project uses **Gitea Actions** to automatically build and release binaries for:
|
||||||
- The `contrib/safelineapi.service` unit assumes files live in `/opt/safelineapi` and the binary is `/opt/safelineapi/safelineApi`. Adjust paths to fit your setup.
|
- Linux: amd64, ARM64, ARMv7, 386, PowerPC 64LE
|
||||||
- For production, run the service as a dedicated unprivileged user and keep `config.json` permissions restricted.
|
- Windows: amd64, 386
|
||||||
|
|
||||||
|
Releases are triggered by git tags (e.g., `v1.0.0`, `v1.0.1`)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
See LICENSE file for details.
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
- Found a bug? Create an issue
|
||||||
|
- Have a question? Check the docs first, then create a discussion
|
||||||
|
- Want to contribute? Pull requests welcome!
|
||||||
|
|||||||
26
config.json
26
config.json
@@ -12,36 +12,10 @@
|
|||||||
"SavePath": "/tmp/ssl",
|
"SavePath": "/tmp/ssl",
|
||||||
"DNSProviderConfig": {
|
"DNSProviderConfig": {
|
||||||
"DNSProvider": "xxx",
|
"DNSProvider": "xxx",
|
||||||
"TencentCloud": {
|
|
||||||
"SecretId": "xxx",
|
|
||||||
"SecretKey": "xxx"
|
|
||||||
},
|
|
||||||
"AliCloud": {
|
|
||||||
"AccessKeyId": "xxx",
|
|
||||||
"AccessKeySecret": "xxx",
|
|
||||||
"RAMRole": "xxx (optional)",
|
|
||||||
"STSToken": "xxx (optional)"
|
|
||||||
},
|
|
||||||
"HuaweiCloud": {
|
|
||||||
"AccessKeyId": "xxx",
|
|
||||||
"Region": "xxx",
|
|
||||||
"SecretAccessKey": "xxx"
|
|
||||||
},
|
|
||||||
"WestCN": {
|
|
||||||
"Username": "xxx",
|
|
||||||
"Password": "xxx"
|
|
||||||
},
|
|
||||||
"RainYun": {
|
|
||||||
"ApiKey": "xxx"
|
|
||||||
},
|
|
||||||
"Cloudflare": {
|
"Cloudflare": {
|
||||||
"APIToken": "xxx",
|
"APIToken": "xxx",
|
||||||
"APIKey": "xxx (optional)",
|
"APIKey": "xxx (optional)",
|
||||||
"Email": "your-email@example.com (optional)"
|
"Email": "your-email@example.com (optional)"
|
||||||
},
|
|
||||||
"Dode": {
|
|
||||||
"Token": "xxx"
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user