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