Skip to content

Commit 78c45b7

Browse files
committed
Merge branch 'release/1.0.0'
2 parents eebe7d0 + d9092ad commit 78c45b7

10 files changed

+268
-165
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
deploy_config
2+
acme.sh
3+
http.header

README.md

+27-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
1-
# deploy-freenas
1+
# deploy-freenas.sh
22

3-
deploy-freenas.py is a Python script to deploy TLS certificates to a FreeNAS server using the FreeNAS API. This should ensure that the certificate data is properly stored in the configuration database, and that all appropriate services use this certificate. It's intended to be called from a Let's Encrypt client like [acme.sh](https://github.com/Neilpang/acme.sh) after the certificate is issued, so that the entire process of issuance (or renewal) and deployment can be automated.
3+
deploy-freenas.sh is a shell script to deploy TLS certificates to a FreeNAS server using the FreeNAS API. This should ensure that the certificate data is properly stored in the configuration database, and that all appropriate services use this certificate. It's intended to be called from a Let's Encrypt client like [acme.sh](https://github.com/Neilpang/acme.sh) after the certificate is issued, so that the entire process of issuance (or renewal) and deployment can be automated.
4+
5+
This project was remade from project deploy-freenas.py by danb35 due to the impossibility of using Python in the closed structure of the OPNsense system.
46

57
# Installation
6-
This script can run on any machine running Python 3 that has network access to your FreeNAS server, but in most cases it's best to run it directly on the FreeNAS box. Change to a convenient directory and run `git clone https://github.com/danb35/deploy-freenas`.
8+
This script can run on any machine running Bourne shell (all *nix systems, macOS; for Windows you need to install additional package, like [CygWin](https://www.cygwin.com/)) that has network access to your FreeNAS server, but in most cases it's best to run it directly on the FreeNAS box. Change to a convenient directory and run `git clone https://github.com/Limych/deploy-freenas`
9+
10+
<p align="center">* * *</p>
11+
I put a lot of work into making this repo available and updated to inspire and help others! I will be glad to receive thanks from you — it will give me new strength and add enthusiasm:
12+
<p align="center"><a href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=UAGFL5L6M8RN2&item_name=[deploy-freenas]+Donation+for+a+big+barrel+of+coffee+:)&currency_code=EUR&source=url"><img alt="Buy Me a Coffe" src="https://raw.githubusercontent.com/Limych/HomeAssistantConfiguration/master/docs/images/donate-with-paypal.png"></a></p>
713

814
# Usage
915

16+
There are now two ways to usage of this script:
17+
18+
## Usage as independent script
19+
1020
The relevant configuration takes place in the `deploy_config` file. You can create this file either by copying `depoy_config.example` from this repository, or directly using your preferred text editor. Its format is as follows:
1121

1222
```
@@ -23,10 +33,21 @@ port = 443
2333

2434
Everything but the password is optional, and the defaults are documented in `depoy_config.example`.
2535

26-
Once you've prepared `deploy_config`, you can run `deploy_freenas.py`. The intended use is that it would be called by your ACME client after issuing a certificate. With acme.sh, for example, you'd add `--deploy-hook "/path/to/deploy_freenas.py"` to your command.
36+
Once you've prepared `deploy_config`, you can run `deploy_freenas.sh`. The intended use is that it would be called by your ACME client after issuing a certificate. With acme.sh, for example, you'd add `--deploy-hook "/path/to/deploy_freenas.sh"` to your command.
2737

28-
There is an optional paramter, `-c` or `--config`, that lets you specify the path to your configuration file. By default the script will try to use `deploy_config` in the script working directoy:
38+
There is an optional parameter, `-c` or `--config`, that lets you specify the path to your configuration file. By default the script will try to use `deploy_config` in the script working directoy:
2939

3040
```
31-
/path/to/deploy_freenas.py --config /somewhere/else/deploy_config
41+
/path/to/deploy_freenas.sh --config /somewhere/else/deploy_config
42+
```
43+
44+
## Usage as part of acme.sh
45+
46+
Install deployer to existing acme.sh installation by `install2acme.sh` script.
47+
48+
Then you can deploy certificates like with other [deploy hooks](https://github.com/Neilpang/acme.sh/wiki/deployhooks):
49+
```bash
50+
export FREENAS_PASSWORD="xxxxxxx" # Required
51+
export FREENAS_HOST="https://example.com:443" # Optional. Default: "http://localhost:80"
52+
acme.sh --deploy -d example.com --deploy-hook freenas
3253
```

deploy/freenas.sh

+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/usr/bin/env sh
2+
3+
# Script to deploy certificate to a FreeNAS server
4+
5+
# The following variables exported from environment will be used.
6+
# If not set then values previously saved in domain.conf file are used.
7+
8+
# Required variables:
9+
# export FREENAS_PASSWORD="xxxxxxx"
10+
#
11+
# Optional variables (default values described):
12+
# export FREENAS_HOST="http://localhost:80"
13+
# export FREENAS_VERIFY=false
14+
15+
#domain keyfile certfile cafile fullchain
16+
freenas_deploy() {
17+
_cdomain="$1"
18+
_ckey="$2"
19+
_ccert="$3"
20+
_cca="$4"
21+
_cfullchain="$5"
22+
23+
_debug _cdomain "$_cdomain"
24+
_debug _ckey "$_ckey"
25+
_debug _ccert "$_ccert"
26+
_debug _cca "$_cca"
27+
_debug _cfullchain "$_cfullchain"
28+
29+
_fullchain=$(tr '\n\r' '@#' <"$_cfullchain" | sed 's/@/\\n/g;s/#/\\r/g')
30+
_key=$(tr '\n\r' '@#' <"$_ckey" | sed 's/@/\\n/g;s/#/\\r/g')
31+
32+
_debug _fullchain "$_fullchain"
33+
_debug _key "$_key"
34+
35+
if [ -z "$FREENAS_PASSWORD" ]; then
36+
if [ -z "$Le_Deploy_FreeNAS_password" ]; then
37+
_err "FREENAS_PASSWORD not defined."
38+
return 1
39+
fi
40+
else
41+
Le_Deploy_FreeNAS_password="$FREENAS_PASSWORD"
42+
_savedomainconf Le_Deploy_FreeNAS_password "$Le_Deploy_FreeNAS_password"
43+
fi
44+
45+
if [ -z "$FREENAS_HOST" ]; then
46+
if [ -z "$Le_Deploy_FreeNAS_host" ]; then
47+
Le_Deploy_FreeNAS_host="http://localhost:80"
48+
_savedomainconf Le_Deploy_freenas_host "$Le_Deploy_FreeNAS_host"
49+
fi
50+
else
51+
Le_Deploy_FreeNAS_host="$FREENAS_HOST"
52+
_savedomainconf Le_Deploy_freenas_host "$Le_Deploy_FreeNAS_host"
53+
fi
54+
55+
if [ -z "$FREENAS_VERIFY" ]; then
56+
if [ -z "$Le_Deploy_FreeNAS_verify" ]; then
57+
Le_Deploy_FreeNAS_verify=false
58+
_savedomainconf Le_Deploy_FreeNAS_verify "$Le_Deploy_FreeNAS_verify"
59+
fi
60+
else
61+
Le_Deploy_FreeNAS_verify="$FREENAS_VERIFY"
62+
_savedomainconf Le_Deploy_FreeNAS_verify "$Le_Deploy_FreeNAS_verify"
63+
fi
64+
65+
_api_base="${Le_Deploy_FreeNAS_host}/api/v1.0"
66+
# _cert=$(date +letsencrypt-%Y-%m-%d-%H%M%S)
67+
_cert=$(date +letsencrypt-%Y-%m-%d)
68+
_realm=$(printf "%s:%s" "root" "$Le_Deploy_FreeNAS_password" | _base64)
69+
70+
_debug _api_base "$_api_base"
71+
_debug _cert "$_cert"
72+
_debug _realm "$_realm"
73+
74+
_info "Update or create SSL certificate"
75+
export _H1="Authorization: Basic $_realm"
76+
export _H2="Content-Type: application/json"
77+
_request="{\"cert_name\":\"$_cert\",\"cert_certificate\":\"$_fullchain\",\"cert_privatekey\":\"$_key\"}"
78+
_debug _request "$_request"
79+
_response="$(_post "$_request" "$_api_base/system/certificate/import/")"
80+
_debug _response "$_response"
81+
82+
if echo "$_response" | grep -q "certificate with this name already exists"; then
83+
_err "SSL certificate with name '$_cert' are already exists. Stop deploying"
84+
return 0
85+
elif [ "$_response" != "Certificate imported." ]; then
86+
_err "Error SSL certificate import"
87+
return 1
88+
fi
89+
90+
_info "Download certificate list and parse it to find the ID that matches our cert name"
91+
_response=$(_get "$_api_base/system/certificate/?limit=0")
92+
_debug _response "$_response"
93+
_regex="^.*\"cert_name\": *\"$_cert\".*$"
94+
_debug _regex "$_regex"
95+
_resource=$(echo "$_response" | sed 's/},{/},\n{/g' | _egrep_o "$_regex")
96+
_debug _resource "$_resource"
97+
_regex="^.*\"cert_name\": \"$_cert\".*$"
98+
_debug _regex "$_regex"
99+
_resource=$(echo "$_response" | sed 's/},{/},\n{/g' | _egrep_o "$_regex")
100+
_debug _resource "$_resource"
101+
_regex=".*\"id\": *\([0-9]*\).*$"
102+
_debug _regex "$_regex"
103+
_cert_id=$(echo "$_resource" | sed -n "s/$_regex/\1/p")
104+
_debug _resourceId "$_cert_id"
105+
106+
_info "Set our cert as active"
107+
_request="{\"stg_guicertificate\":\"$_cert_id\"}"
108+
_response=$(_post "$_request" "$_api_base/system/settings/" '' "PUT")
109+
_debug _response "$_response"
110+
111+
_info "Reload nginx with new cert"
112+
_response="$(_post "" "$_api_base/system/settings/restart-httpd-all/")"
113+
_debug _response "$_response"
114+
115+
# Make time for httpd for reloading
116+
sleep 3
117+
118+
_info "Set our cert as active for FTP plugin"
119+
_request="{\"ftp_ssltls_certfile\":\"$_cert\"}"
120+
_response=$(_post "$_request" "$_api_base/services/ftp/" '' "PUT")
121+
_debug _response "$_response"
122+
123+
_info "Certificate successfully deployed"
124+
return 0
125+
}

deploy_config.example

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ password = YourSuperSecurePassword#@#$*
1717
# verify sets whether the script will attempt to verify the server's certificate with a HTTPS
1818
# connection. Set to true if you're using a HTTPS connection to a remote host. If connect_host
1919
# is set to localhost (or is unset), set to false. Default is false.
20-
# verify = false
20+
# verify = true
2121

2222
# privkey_path is the path to the certificate private key on your system. Default
2323
# assumes you're using acme.sh:

deploy_freenas.py

-151
This file was deleted.

0 commit comments

Comments
 (0)