Skip to content

Commit ad100d8

Browse files
authored
Merge pull request #19 from t-anc/18-self-signed-sertificate
Handle qBittorrent self signed certificates
2 parents cb8abaa + efa82b1 commit ad100d8

File tree

2 files changed

+81
-25
lines changed
  • root/etc/s6-overlay/s6-rc.d/svc-mod-gluetun-sync-port

2 files changed

+81
-25
lines changed

README.md

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -87,20 +87,21 @@ The only difference should be this small message in the logs during init checks
8787
The following env variables can be used to configure the mod (Only `GSP_GTN_API_KEY` is required) :
8888
| Variable | Default value | Comment |
8989
|:----------------------:|:-----------------------:|----------------------------------------------------------------------------------------------------------|
90-
| `GSP_GTN_API_KEY` | | Gluetun's API key. See the [install section](#gluetun). |
90+
| `GSP_GTN_API_KEY` | | Gluetun's API key. See the [install section](#gluetun). |
9191
| `GSP_GTN_API_KEY_FILE` | | Gluetun's API key file (for [docker secret](https://docs.docker.com/compose/use-secrets/) use). This supplants `GSP_GTN_API_KEY`. |
92-
| `GSP_GTN_ADDR` | `http://localhost:8000` | Gluetun API host address. |
93-
| `GSP_QBT_ADDR` | `http://localhost:8080` | Qbittorrent API host address. If the env variable `WEBUI_PORT` is set, it will be used as default. |
94-
| `GSP_SLEEP` | `60` | Time between checks in seconds. |
95-
| `GSP_RETRY_DELAY` | `10` | Time between retries in case of error (in s). |
96-
| `GSP_GTN_PORT_INDEX` | `1` | Index of port to use from gluetun. Set to `2` to use the second one, etc. Only if you have multiple ports forwarded. |
92+
| `GSP_GTN_ADDR` | `http://localhost:8000` | Gluetun API host address. |
93+
| `GSP_QBT_ADDR` | `http://localhost:8080` | Qbittorrent API host address. If the env variable `WEBUI_PORT` is set, it will be used as default. |
94+
| `GSP_SLEEP` | `60` | Time between checks in seconds. |
95+
| `GSP_RETRY_DELAY` | `10` | Time between retries in case of error (in s). |
96+
| `GSP_GTN_PORT_INDEX` | `1` | Index of port to use from gluetun. Set to `2` to use the second one, etc. Only if you have multiple ports forwarded. |
9797
| `GSP_QBT_USERNAME` | | Qbittorrent username. |
9898
| `GSP_QBT_PASSWORD` | | Qbittorrent password. |
9999
| `GSP_QBT_PASSWORD_FILE`| | Qbittorrent password file (for [docker secret](https://docs.docker.com/compose/use-secrets/) use). This supplants `GSP_QBT_PASSWORD`. |
100100
| `GSP_SKIP_INIT_CHECKS` | `false` | Set to `true` to disable qbt config checks ("Bypass authentication on localhost", etc). Set to `warning`to see check results but continue anyway.|
101+
| `GSP_CERT_CHECK` | `true` | Set to `false` to disable certificate check. (curl's insecure flag) |
101102
| `GSP_MINIMAL_LOGS` | `true` | Set to `false` to enable "Ports did not change." logs. |
102103
| `GSP_INIT_RETRY_WAIT` | `10` (=60s) | Number of retries to connect to qbittorrent's webUI at startup. Each retry takes 6 seconds. Increase to allow a longer wait at startup. |
103-
| `GSP_DEBUG` | `false` | Set to `true` to enable mod's `set -x`.<br>:warning: **FOR DEBUG ONLY.**<br>This will show your API key in the logs. |
104+
| `GSP_DEBUG` | `false` | Set to `true` to enable mod's `set -x`.<br>:warning: **FOR DEBUG ONLY.**<br>This will show your credentials in the logs. |
104105

105106
I was planning on implementing the option to use Gluetun's port forwarding file but since it will be [deprecated in v4](https://github.com/qdm12/gluetun-wiki/blob/main/setup/advanced/vpn-port-forwarding.md#native-integrations), I won't.
106107

@@ -152,17 +153,22 @@ Here's some tips for troubleshooting :
152153
153154
<details>
154155
155-
<summary>Check the logs</summary>
156+
<summary>Check the logs.</summary>
156157
157158
The mod's logs are visible in the container's log :
158159
```bash
159160
docker logs -f qbittorrent
160161
```
161162

163+
It's also possible to look at Gluetun's log :
162164

163-
<details>
165+
```bash
166+
docker logs -f gluetun
167+
```
164168

165-
<summary>Qbittorrent docker logs</summary>
169+
<details>
170+
171+
<summary>Qbittorrent docker logs.</summary>
166172

167173
```log
168174
[mod-init] Running Docker Modification Logic
@@ -223,15 +229,35 @@ Connection to localhost (::1) 8080 port [tcp/http-alt] succeeded!
223229
04/10/24 01:05:55 [GSP] - Ports did not change.
224230
```
225231

226-
</details>
232+
</details>
227233

228234
To (*drastically*) increase the log level, you can set the `GSP_DEBUG` var to `true`.
229235

236+
<details>
237+
238+
<summary>Gluetun docker logs.</summary>
239+
240+
```log
241+
2024-12-29T14:22:53+01:00 INFO [port forwarding] starting
242+
2024-12-29T14:22:53+01:00 INFO [port forwarding] gateway external IPv4 address is 156.71.163.18
243+
2024-12-29T14:22:53+01:00 INFO [port forwarding] port forwarded is 18008
244+
2024-12-29T14:22:53+01:00 INFO [firewall] setting allowed input port 18008 through interface tun0...
245+
2024-12-29T14:22:53+01:00 INFO [port forwarding] writing port file /tmp/gluetun/forwarded_port
246+
2024-12-29T14:22:58+01:00 INFO [http server] 200 GET /portforwarded wrote 15B to [::1]:55008 in 79.707µs
247+
2024-12-29T14:23:58+01:00 INFO [http server] 200 GET /portforwarded wrote 15B to [::1]:43420 in 112.741µs
248+
2024-12-29T14:24:58+01:00 INFO [http server] 200 GET /portforwarded wrote 15B to [::1]:45958 in 88.972µs
249+
```
250+
251+
Explanation :
252+
- The lines taggued `[port forwarding]` are internal actions related to ... port forwarding. Those are useful to understand what gluetun is doing.
253+
- The lines taggued `[http server]` are related to gluetun's API. In the example above, you can see that something (here, the mod) is requesting the `/portforwarded` endpoint, every 60 seconds. This DOES NOT indicate a change of forwarded port, only an external request to `GET` the current one.
254+
255+
</details>
230256
</details>
231257

232258
<details>
233259

234-
<summary>Check Gluetun's control server and forwarded port</summary>
260+
<summary>Check Gluetun's control server and forwarded port.</summary>
235261

236262
If the log indicates `Error retrieving port from Gluetun API.` then try to get the port mannually (replace the container's name and `localhost:8000` if needed) :
237263

@@ -275,3 +301,17 @@ If you get `0` or an error, then the issue is from your gluetun's configuration,
275301
This is thanks to [Gluetun's healthcheck](https://github.com/qdm12/gluetun-wiki/blob/main/faq/healthcheck.md) being healthy only when the connexion is set.
276302
277303
</details>
304+
305+
<details>
306+
307+
<summary>Issues with HTTPS.</summary>
308+
309+
There are 2 main issues with HTTPS :
310+
- Your certificate is not trusted by the container (ex : self signed).
311+
312+
To remediate this, you can use the `GSP_CERT_CHECK` variable and set it to `false`. This will use the `insecure` flag for every `curl` request.
313+
- Your certificate is trusted, but does not contain `localhost` (obviously) and so the connection is refused.
314+
315+
For this one, you can check [Unspec7's guide](#14) (Thanks to him).
316+
317+
</details>

root/etc/s6-overlay/s6-rc.d/svc-mod-gluetun-sync-port/run

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,25 @@
66
MAX_SLEEP_TIME="${GSP_SLEEP:-60}"
77
RETRY_DELAY="${GSP_RETRY_DELAY:-10}"
88
INIT_RETRY_WAIT="${GSP_INIT_RETRY_WAIT:-10}"
9+
CERT_CHECK="${GSP_CERT_CHECK:-true}"
10+
[ "${CERT_CHECK,,}" = 'false' ] && CURL_OPT='--insecure'
11+
DEBUG="${GSP_DEBUG:-false}"
12+
913
GTN_PORT_INDEX="$(( ${GSP_GTN_PORT_INDEX:-1} - 1))"
1014
[ "${MAX_SLEEP_TIME}" -eq "${RETRY_DELAY}" ] && (( RETRY_DELAY = RETRY_DELAY - 1 )) # To avoid errors later
1115
GLUETUN="${GSP_GTN_ADDR:-http://localhost:8000}"
1216
[ -n "${GSP_GTN_API_KEY_FILE}" ] && GSP_GTN_API_KEY="$(cat "${GSP_GTN_API_KEY_FILE}")"
1317
GTN_API_KEY="${GSP_GTN_API_KEY}"
18+
GTN_AUTH=("-H" "X-API-Key:${GTN_API_KEY}")
19+
1420
QBITTORRENT="${GSP_QBT_ADDR:-http://localhost:${WEBUI_PORT:-8080}}"
1521
[ -n "${GSP_QBT_PASSWORD_FILE}" ] && GSP_QBT_PASSWORD="$(cat "${GSP_QBT_PASSWORD_FILE}")"
1622
QBT_USERNAME="${GSP_QBT_USERNAME}"
1723
QBT_PASSWORD="${GSP_QBT_PASSWORD}"
1824
QBT_COOKIES="--cookie-jar /tmp/cookies.txt --cookie /tmp/cookies.txt"
19-
20-
GTN_AUTH=("-H" "X-API-Key:${GTN_API_KEY}")
21-
22-
DEBUG="${GSP_DEBUG:-false}"
23-
2425
CONF_FILE='/config/qBittorrent/qBittorrent.conf'
2526

27+
2628
spaces=' '
2729
QBT_display="${QBITTORRENT}${spaces}"
2830
GTN_display="${GLUETUN}${spaces}"
@@ -66,7 +68,8 @@ $(env | grep 'GSP')
6668
| QBT_USERNAME = ${QBT_USERNAME}
6769
| QBT_PASSWORD (to be anonymised) = ${QBT_PASSWORD}
6870
| GTN_API_KEY (to be anonymised) = ${GTN_API_KEY}
69-
| STANDALONE_MODE = $([ -f ${CONF_FILE} ] && echo 'False' || echo 'True')
71+
| CERT_CHECK = ${CERT_CHECK}
72+
| STANDALONE_MODE = $([ -f ${CONF_FILE} ] && echo 'false' || echo 'true')
7073
+---------------------------------------------------------+
7174
"
7275
set -x
@@ -75,6 +78,7 @@ fi
7578

7679
qbt_login(){
7780
curl --fail --silent \
81+
${CURL_OPT} \
7882
${QBT_COOKIES} \
7983
--url "${QBITTORRENT}/api/v2/auth/login" \
8084
--data "username=${QBT_USERNAME}" \
@@ -94,6 +98,17 @@ init_checks(){
9498
fi
9599

96100
# Check 1 :
101+
# In case of HTTPS, check if qBittorrent is using a trusted certificate.
102+
103+
if echo "${QBITTORRENT}" | grep -iq 'https://' ;then
104+
curl ${CURL_OPT} --silent --output /dev/null "${QBITTORRENT}"
105+
if [ "$?" -eq '60' ]; then
106+
err='true'
107+
log "${MSG_prefix} Your qBittorrent certificate is untrusted. See HTTPS section in https://github.com/t-anc/GSP-Qbittorent-Gluetun-sync-port-mod#troubleshooting."
108+
fi
109+
fi
110+
111+
# Check 2 :
97112
# Check for the auth bypass in qbittorrent's config file,
98113
# or check for bad credentials.
99114

@@ -109,19 +124,19 @@ init_checks(){
109124
fi
110125
fi
111126

112-
# Check 2 :
127+
# Check 3 :
113128
# Check for "Host header validation".
114-
if [ "$(curl --write-out '%{http_code}' --silent --output /dev/null "${QBITTORRENT}")" -eq 401 ]; then
129+
if [ "$(curl ${CURL_OPT} --write-out '%{http_code}' --silent --output /dev/null "${QBITTORRENT}")" -eq 401 ]; then
115130
err='true'
116131
log "${MSG_prefix} Qbittorrent returned 401. Is the \"Enable Host header validation\" setting set ? Is $(basename "${QBITTORRENT%:*}") whitelisted ?"
117132
fi
118133

119-
# Check 3 :
134+
# Check 4 :
120135
# Check Gluetun's authentication
121136
if [ -z "${GTN_API_KEY}" ];then
122137
log "[WARNING] It seems you don't have any 'GSP_GTN_API_KEY' set. You should set one, follow the doc here : https://github.com/t-anc/GSP-Qbittorent-Gluetun-sync-port-mod#gluetun"
123138
else
124-
if [ "$(curl --write-out '%{http_code}' --silent --output /dev/null "${GTN_AUTH[@]}" "${GLUETUN}/v1/openvpn/portforwarded")" -eq '401' ]; then
139+
if [ "$(curl ${CURL_OPT} --write-out '%{http_code}' --silent --output /dev/null "${GTN_AUTH[@]}" "${GLUETUN}/v1/openvpn/portforwarded")" -eq '401' ]; then
125140
err='true'
126141
log "${MSG_prefix} Gluetun returned 401. Is Gluetun's authentication correctly configured ? See https://github.com/t-anc/GSP-Qbittorent-Gluetun-sync-port-mod#gluetun"
127142
fi
@@ -158,9 +173,9 @@ get_ports(){
158173
GTN='true'
159174
;;
160175
esac
161-
[ "${QBT}" ] && QBT_PORT=$(curl --silent --fail --show-error ${QBT_COOKIES} "${QBITTORRENT}/api/v2/app/preferences" | jq ".listen_port" 2>/dev/null)
176+
[ "${QBT}" ] && QBT_PORT=$(curl --silent --fail --show-error ${CURL_OPT} ${QBT_COOKIES} "${QBITTORRENT}/api/v2/app/preferences" | jq ".listen_port" 2>/dev/null)
162177
[ "${GTN}" ] && {
163-
GTN_PORTS=$(curl --silent --fail --show-error "${GTN_AUTH[@]}" "${GLUETUN}/v1/openvpn/portforwarded")
178+
GTN_PORTS=$(curl --silent --fail --show-error ${CURL_OPT} "${GTN_AUTH[@]}" "${GLUETUN}/v1/openvpn/portforwarded")
164179
if echo "${GTN_PORTS}" | jq --exit-status 'has("ports")' > /dev/null; then # Handle the case of multiple ports - ex : [10550,20550,30550]
165180
GTN_PORT=$(echo "${GTN_PORTS}" | jq ".ports[${GTN_PORT_INDEX}]" 2>/dev/null)
166181
[ "${GTN_PORT}" = "null" ] && log "[ERROR] GSP_GTN_PORT_INDEX (${GSP_GTN_PORT_INDEX:-1}) > Nb of ports ($(echo "${GTN_PORTS}" | jq '.ports | length'))."\
@@ -175,7 +190,7 @@ get_ports(){
175190

176191

177192
log "Waiting for Qbittorrent WebUI ..."
178-
curl --retry "${INIT_RETRY_WAIT}" --retry-all-errors --retry-delay 6 -s -o /dev/null "${QBITTORRENT}" || \
193+
curl --insecure --retry "${INIT_RETRY_WAIT}" --retry-all-errors --retry-delay 6 -s -o /dev/null "${QBITTORRENT}" || \
179194
log "Couldn't connect to webUI. Check the address, or maybe your instance is taking to long to start. You can adjust the GSP_INIT_RETRY_WAIT variable to wait longer."
180195

181196

@@ -208,6 +223,7 @@ while :; do
208223
log "Updating qbittorrent port via API ..."
209224
curl \
210225
--silent \
226+
${CURL_OPT} \
211227
--request POST \
212228
${QBT_COOKIES} \
213229
--url "${QBITTORRENT}/api/v2/app/setPreferences" \

0 commit comments

Comments
 (0)