committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 509 additions and 12 deletions
-
46README.md
-
105acme.sh
-
116httpapi/README.md
-
119httpapi/http_local.sh
-
135httpapi/http_scp.sh
@ -0,0 +1,116 @@ |
|||||
|
# HTTP API Validation Plugin |
||||
|
|
||||
|
This directory contains plugins for acme.sh's HTTP API validation system. These plugins allow you to deploy ACME HTTP-01 challenge files to remote servers using various methods without requiring direct filesystem access. |
||||
|
|
||||
|
## Usage |
||||
|
|
||||
|
To use an HTTP API validation plugin, there are two ways to specify it: |
||||
|
|
||||
|
### Method 1: Using the `--webroot` parameter with the plugin name prefix: |
||||
|
|
||||
|
```bash |
||||
|
acme.sh --issue -d example.com --webroot http_scp |
||||
|
``` |
||||
|
|
||||
|
### Method 2: Using the dedicated `--http-api` parameter: |
||||
|
|
||||
|
```bash |
||||
|
acme.sh --issue -d example.com --http-api http_scp |
||||
|
``` |
||||
|
|
||||
|
The second method is preferred as it's more explicit about the validation method being used. |
||||
|
|
||||
|
## Available Plugins |
||||
|
|
||||
|
- `http_scp`: Deploy challenge files via SCP to a remote web server |
||||
|
- `http_local`: Deploy challenge files to a local directory (for testing) |
||||
|
|
||||
|
## Using HTTP API Plugins |
||||
|
|
||||
|
Before using an HTTP API plugin, you need to set the required environment variables: |
||||
|
|
||||
|
```bash |
||||
|
# For SCP plugin |
||||
|
export HTTP_SCP_USER="username" |
||||
|
export HTTP_SCP_HOST="example.com" |
||||
|
export HTTP_SCP_PATH="/var/www/html" |
||||
|
# Optional |
||||
|
export HTTP_SCP_PORT="22" |
||||
|
export HTTP_SCP_KEY="/path/to/ssh/key" |
||||
|
|
||||
|
# For Local plugin |
||||
|
export HTTP_LOCAL_DIR="/var/www/html" |
||||
|
export HTTP_LOCAL_MKDIR="true" # Create directory if it doesn't exist |
||||
|
export HTTP_LOCAL_VERIFY="true" # Simple curl verification |
||||
|
|
||||
|
# Then issue your certificate |
||||
|
acme.sh --issue -d example.com --http-api http_scp |
||||
|
``` |
||||
|
|
||||
|
These environment variables will be saved to your account configuration for future use. |
||||
|
|
||||
|
## Creating Your Own Plugin |
||||
|
|
||||
|
Plugins are shell scripts with at least two functions: |
||||
|
|
||||
|
1. `<plugin-name>_deploy`: Deploy the challenge file |
||||
|
2. `<plugin-name>_rm`: Remove the challenge file |
||||
|
|
||||
|
Here's a minimal example: |
||||
|
|
||||
|
```bash |
||||
|
#!/usr/bin/env sh |
||||
|
|
||||
|
# Deploy the challenge file |
||||
|
http_myplugin_deploy() { |
||||
|
local domain="$1" |
||||
|
local token="$2" |
||||
|
local keyauthorization="$3" |
||||
|
|
||||
|
# Deploy the challenge file to your web server |
||||
|
# ... |
||||
|
|
||||
|
return 0 # Return 0 for success, non-zero for failure |
||||
|
} |
||||
|
|
||||
|
# Remove the challenge file |
||||
|
http_myplugin_rm() { |
||||
|
local domain="$1" |
||||
|
local token="$2" |
||||
|
|
||||
|
# Remove the challenge file |
||||
|
# ... |
||||
|
|
||||
|
return 0 # Return 0 for success, non-zero for failure |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
## Plugin Configuration |
||||
|
|
||||
|
Typically, plugins will need configuration settings like server addresses, credentials, etc. These should be provided as environment variables: |
||||
|
|
||||
|
```bash |
||||
|
export HTTP_MYPLUGIN_HOST="example.com" |
||||
|
export HTTP_MYPLUGIN_USER="username" |
||||
|
export HTTP_MYPLUGIN_PASSWORD="password" |
||||
|
# etc... |
||||
|
|
||||
|
acme.sh --issue -d example.com --http-api http_myplugin |
||||
|
``` |
||||
|
|
||||
|
Alternatively, you can save these values in your acme.sh account configuration file for future use. |
||||
|
|
||||
|
## Example: Using the SCP Plugin |
||||
|
|
||||
|
```bash |
||||
|
# Set required environment variables |
||||
|
export HTTP_SCP_USER="username" |
||||
|
export HTTP_SCP_HOST="remote.server.com" |
||||
|
export HTTP_SCP_PATH="/var/www/html" |
||||
|
# Optional: |
||||
|
export HTTP_SCP_PORT="22" |
||||
|
export HTTP_SCP_KEY="/path/to/ssh/key" |
||||
|
|
||||
|
# Issue certificate using SCP validation |
||||
|
acme.sh --issue -d example.com --http-api http_scp |
||||
|
``` |
@ -0,0 +1,119 @@ |
|||||
|
#!/usr/bin/env sh |
||||
|
|
||||
|
http_local_info='Local filesystem HTTP-01 validation plugin |
||||
|
Site: Local filesystem |
||||
|
Docs: github.com/acmesh-official/acme.sh/wiki/HTTP-API |
||||
|
Options: |
||||
|
HTTP_LOCAL_DIR Directory to copy challenge to |
||||
|
HTTP_LOCAL_MKDIR Create directory if it doesnt exist (true/false) |
||||
|
HTTP_LOCAL_VERIFY Verify challenge file is accessible via HTTPS (true/false, default: false) |
||||
|
' |
||||
|
|
||||
|
#Here we implement local filesystem-based http validation |
||||
|
|
||||
|
#Returns 0 means success, otherwise error. |
||||
|
|
||||
|
######## Public functions ##################### |
||||
|
|
||||
|
#Usage: http_local_deploy domain token keyauthorization |
||||
|
http_local_deploy() { |
||||
|
_cdomain="$1" |
||||
|
_ctoken="$2" |
||||
|
_ckey="$3" |
||||
|
|
||||
|
_debug _cdomain "$_cdomain" |
||||
|
_debug _ctoken "$_ctoken" |
||||
|
|
||||
|
_getconfig |
||||
|
if [ "$?" != "0" ]; then |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
_info "Deploying challenge file to local directory" |
||||
|
_wellknown_path="$HTTP_LOCAL_DIR/.well-known/acme-challenge" |
||||
|
|
||||
|
# Create directory if needed |
||||
|
if [ "$HTTP_LOCAL_MKDIR" = "true" ]; then |
||||
|
_debug "Creating directory $_wellknown_path" |
||||
|
mkdir -p "$_wellknown_path" |
||||
|
fi |
||||
|
|
||||
|
# Create temporary file with token content |
||||
|
_tempcontent="$(_mktemp)" |
||||
|
if [ "$?" != "0" ]; then |
||||
|
_err "Failed to create temporary file" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
echo "$_ckey" > "$_tempcontent" |
||||
|
|
||||
|
# Copy challenge file |
||||
|
_info "Copying challenge file" |
||||
|
if ! cp "$_tempcontent" "$_wellknown_path/$_ctoken"; then |
||||
|
_err "Failed to copy challenge file" |
||||
|
rm -f "$_tempcontent" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
rm -f "$_tempcontent" |
||||
|
|
||||
|
# Verify the file is accessible via HTTPS if enabled |
||||
|
if [ "$HTTP_LOCAL_VERIFY" != "false" ]; then |
||||
|
_info "Verifying challenge file is accessible via HTTPS" |
||||
|
_verify_url="https://$_cdomain/.well-known/acme-challenge/$_ctoken" |
||||
|
_debug "Verifying URL: $_verify_url" |
||||
|
|
||||
|
# Try to access the file with curl, ignoring SSL certificate verification |
||||
|
if ! curl -k -s -o /dev/null -w "%{http_code}" "$_verify_url" | grep -q "200"; then |
||||
|
_err "Challenge file is not accessible via HTTPS at $_verify_url" |
||||
|
return 1 |
||||
|
fi |
||||
|
else |
||||
|
_debug "Skipping HTTPS verification as HTTP_LOCAL_VERIFY is set to false" |
||||
|
fi |
||||
|
|
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
#Usage: http_local_rm domain token |
||||
|
http_local_rm() { |
||||
|
_cdomain="$1" |
||||
|
_ctoken="$2" |
||||
|
|
||||
|
_debug _cdomain "$_cdomain" |
||||
|
_debug _ctoken "$_ctoken" |
||||
|
|
||||
|
_getconfig |
||||
|
if [ "$?" != "0" ]; then |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
_info "Removing challenge file from local directory" |
||||
|
_wellknown_path="$HTTP_LOCAL_DIR/.well-known/acme-challenge" |
||||
|
|
||||
|
# Remove challenge file |
||||
|
_info "Removing challenge file" |
||||
|
if ! rm -f "$_wellknown_path/$_ctoken"; then |
||||
|
_err "Failed to remove challenge file" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
_getconfig() { |
||||
|
if [ -z "$HTTP_LOCAL_DIR" ]; then |
||||
|
_err "HTTP_LOCAL_DIR is not defined" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
if [ -z "$HTTP_LOCAL_MKDIR" ]; then |
||||
|
HTTP_LOCAL_MKDIR="false" |
||||
|
fi |
||||
|
|
||||
|
if [ -z "$HTTP_LOCAL_VERIFY" ]; then |
||||
|
HTTP_LOCAL_VERIFY="false" |
||||
|
fi |
||||
|
|
||||
|
return 0 |
||||
|
} |
@ -0,0 +1,135 @@ |
|||||
|
#!/usr/bin/env sh |
||||
|
|
||||
|
http_scp_info='SCP HTTP-01 validation plugin |
||||
|
Site: github.com/acmesh-official/acme.sh/wiki/HTTP-API |
||||
|
Docs: github.com/acmesh-official/acme.sh/wiki/HTTP-API#http_scp |
||||
|
Options: |
||||
|
HTTP_SCP_USER Username for SSH/SCP |
||||
|
HTTP_SCP_HOST Remote host |
||||
|
HTTP_SCP_PATH Remote webroot path |
||||
|
HTTP_SCP_PORT SSH port (optional) |
||||
|
HTTP_SCP_KEY SSH private key path (optional) |
||||
|
' |
||||
|
|
||||
|
#Here we implement scp-based http validation |
||||
|
|
||||
|
#Returns 0 means success, otherwise error. |
||||
|
|
||||
|
######## Public functions ##################### |
||||
|
|
||||
|
#Usage: http_scp_deploy domain token keyauthorization |
||||
|
http_scp_deploy() { |
||||
|
_cdomain="$1" |
||||
|
_ctoken="$2" |
||||
|
_ckey="$3" |
||||
|
|
||||
|
_debug _cdomain "$_cdomain" |
||||
|
_debug _ctoken "$_ctoken" |
||||
|
|
||||
|
_getconfig |
||||
|
if [ "$?" != "0" ]; then |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
_info "Deploying challenge file to remote server using SCP" |
||||
|
_wellknown_path="$HTTP_SCP_PATH/.well-known/acme-challenge" |
||||
|
|
||||
|
# Create temporary file with token content |
||||
|
_tempcontent="$(_mktemp)" |
||||
|
if [ "$?" != "0" ]; then |
||||
|
_err "Failed to create temporary file" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
echo "$_ckey" > "$_tempcontent" |
||||
|
|
||||
|
# Prepare SSH options |
||||
|
_scp_options="" |
||||
|
if [ -n "$HTTP_SCP_KEY" ]; then |
||||
|
_scp_options="$_scp_options -i $HTTP_SCP_KEY" |
||||
|
fi |
||||
|
|
||||
|
if [ -n "$HTTP_SCP_PORT" ]; then |
||||
|
_scp_options="$_scp_options -P $HTTP_SCP_PORT" |
||||
|
fi |
||||
|
_scp_options="$_scp_options -o StrictHostKeyChecking=no" |
||||
|
|
||||
|
# Create challenge directory if it doesn't exist |
||||
|
_info "Creating challenge directory on remote server" |
||||
|
# shellcheck disable=SC2029 # We intentionally want client-side expansion of _wellknown_path |
||||
|
if ! ssh $HTTP_SCP_USER@$HTTP_SCP_HOST $_scp_options "mkdir -p ${_wellknown_path}"; then |
||||
|
_err "Failed to create challenge directory on remote server" |
||||
|
rm -f "$_tempcontent" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
# Upload challenge file |
||||
|
_info "Uploading challenge file" |
||||
|
if ! scp $_scp_options "$_tempcontent" $HTTP_SCP_USER@$HTTP_SCP_HOST:"${_wellknown_path}/${_ctoken}"; then |
||||
|
_err "Failed to upload challenge file" |
||||
|
rm -f "$_tempcontent" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
rm -f "$_tempcontent" |
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
#Usage: http_scp_rm domain token |
||||
|
http_scp_rm() { |
||||
|
_cdomain="$1" |
||||
|
_ctoken="$2" |
||||
|
|
||||
|
_debug _cdomain "$_cdomain" |
||||
|
_debug _ctoken "$_ctoken" |
||||
|
|
||||
|
_getconfig |
||||
|
if [ "$?" != "0" ]; then |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
_info "Removing challenge file from remote server" |
||||
|
_wellknown_path="$HTTP_SCP_PATH/.well-known/acme-challenge" |
||||
|
|
||||
|
# Prepare SSH options |
||||
|
_scp_options="" |
||||
|
if [ -n "$HTTP_SCP_KEY" ]; then |
||||
|
_scp_options="$_scp_options -i $HTTP_SCP_KEY" |
||||
|
fi |
||||
|
|
||||
|
if [ -n "$HTTP_SCP_PORT" ]; then |
||||
|
_scp_options="$_scp_options -p $HTTP_SCP_PORT" |
||||
|
else |
||||
|
_scp_options="$_scp_options -p 22" |
||||
|
fi |
||||
|
_scp_options="$_scp_options -o StrictHostKeyChecking=no" |
||||
|
|
||||
|
# Remove challenge file |
||||
|
_info "Removing challenge file from remote server" |
||||
|
# shellcheck disable=SC2029 # We intentionally want client-side expansion of _wellknown_path and _ctoken |
||||
|
if ! ssh $HTTP_SCP_USER@$HTTP_SCP_HOST $_scp_options "rm -f ${_wellknown_path}/${_ctoken}"; then |
||||
|
_err "Failed to remove challenge file from remote server" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
_getconfig() { |
||||
|
if [ -z "$HTTP_SCP_USER" ]; then |
||||
|
_err "HTTP_SCP_USER is not defined" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
if [ -z "$HTTP_SCP_HOST" ]; then |
||||
|
_err "HTTP_SCP_HOST is not defined" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
if [ -z "$HTTP_SCP_PATH" ]; then |
||||
|
_err "HTTP_SCP_PATH is not defined" |
||||
|
return 1 |
||||
|
fi |
||||
|
|
||||
|
return 0 |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue