commit
0bda3100f8
36
Dockerfile
36
Dockerfile
|
@ -2,27 +2,47 @@
|
|||
|
||||
FROM ubuntu:jammy AS docker-cli
|
||||
|
||||
RUN apt update && \
|
||||
apt install --no-install-suggests --no-install-recommends -y ca-certificates curl gnupg lsb-release
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-suggests --no-install-recommends --yes --quiet \
|
||||
ca-certificates \
|
||||
curl \
|
||||
gnupg \
|
||||
lsb-release
|
||||
RUN mkdir -m 0755 -p /etc/apt/keyrings && \
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && \
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
RUN apt update && \
|
||||
apt install --no-install-suggests --no-install-recommends -y docker-ce-cli
|
||||
RUN apt-get update && \
|
||||
apt-get install --no-install-suggests --no-install-recommends --yes --quiet docker-ce-cli
|
||||
|
||||
FROM ubuntu:jammy
|
||||
|
||||
LABEL org.opencontainers.image.source="https://github.com/soxfor/qbittorrent-natmap"
|
||||
LABEL org.opencontainers.image.base.name="ubuntu:jammy"
|
||||
LABEL description="Map port via NAT-PMP and update qBittorrent configuration"
|
||||
LABEL version="1.0.6"
|
||||
LABEL version="1.0.7"
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt update
|
||||
RUN apt install --no-install-suggests --no-install-recommends -y natpmpc curl bc netcat-openbsd
|
||||
RUN apt-get update
|
||||
RUN apt-get install --no-install-suggests --no-install-recommends --yes --quiet \
|
||||
natpmpc \
|
||||
curl \
|
||||
bc \
|
||||
netcat-openbsd \
|
||||
tzdata \
|
||||
locales
|
||||
RUN rm -rf /var/lib/apt/lists/* /var/cache/apt/*
|
||||
RUN apt clean
|
||||
RUN apt-get clean
|
||||
|
||||
ENV TZ=Etc/UTC
|
||||
ENV LANG=en_US.UTF-8
|
||||
ENV LANGUAGE=en_US:en
|
||||
ENV LC_ALL=en_US.UTF-8
|
||||
|
||||
RUN sed -i "/${LANG}/s/^# //g" /etc/locale.gen && \
|
||||
locale-gen && \
|
||||
ln -fs "/usr/share/zoneinfo/${TZ}" /etc/localtime && \
|
||||
dpkg-reconfigure tzdata
|
||||
|
||||
ENV QBITTORRENT_SERVER=
|
||||
ENV QBITTORRENT_PORT=8080
|
||||
|
|
|
@ -5,29 +5,33 @@ timestamp() {
|
|||
}
|
||||
|
||||
getpublicip() {
|
||||
# shellcheck disable=SC2086
|
||||
natpmpc -g ${VPN_GATEWAY} | grep -oP '(?<=Public.IP.address.:.).*'
|
||||
}
|
||||
|
||||
findconfiguredport() {
|
||||
curl -s -i --header "Referer: http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}" --cookie "$1" http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}/api/v2/app/preferences | grep -oP '(?<=\"listen_port\"\:)(\d{1,5})'
|
||||
curl -s -i --header "Referer: http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}" --cookie "$1" "http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}/api/v2/app/preferences" | grep -oP '(?<=\"listen_port\"\:)(\d{1,5})'
|
||||
}
|
||||
|
||||
findactiveport() {
|
||||
# shellcheck disable=SC2086
|
||||
natpmpc -g ${VPN_GATEWAY} -a 0 0 udp ${NAT_LEASE_LIFETIME} >/dev/null 2>&1
|
||||
# shellcheck disable=SC2086
|
||||
natpmpc -g ${VPN_GATEWAY} -a 0 0 tcp ${NAT_LEASE_LIFETIME} | grep -oP '(?<=Mapped public port.).*(?=.protocol.*)'
|
||||
}
|
||||
|
||||
qbt_login() {
|
||||
curl -s -i --header "Referer: http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}" --data "username=${QBITTORRENT_USER}&password=${QBITTORRENT_PASS}" http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}/api/v2/auth/login | grep -oP '(?!set-cookie:.)SID=.*(?=\;.HttpOnly\;)'
|
||||
qbt_sid=$(curl -s -i --header "Referer: http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}" --data "username=${QBITTORRENT_USER}" --data-urlencode "password=${QBITTORRENT_PASS}" "http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}/api/v2/auth/login" | grep -oP '(?!set-cookie:.)SID=.*(?=\;.HttpOnly\;)')
|
||||
return $?
|
||||
}
|
||||
|
||||
qbt_changeport(){
|
||||
curl -s -i --header "Referer: http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}" --cookie "$1" --data-urlencode "json={\"listen_port\":$2,\"random_port\":false,\"upnp\":false}" http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}/api/v2/app/setPreferences 2>&1 >/dev/null
|
||||
curl -s -i --header "Referer: http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}" --cookie "$1" --data-urlencode "json={\"listen_port\":$2,\"random_port\":false,\"upnp\":false}" "http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}/api/v2/app/setPreferences" >/dev/null 2>&1
|
||||
return $?
|
||||
}
|
||||
|
||||
qbt_checksid(){
|
||||
if echo $(curl -s --header "Referer: http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}" --cookie "${qbt_sid}" http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}/api/v2/app/version) | grep -qi forbidden; then
|
||||
if curl -s --header "Referer: http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}" --cookie "${qbt_sid}" "http://${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}/api/v2/app/version" | grep -qi forbidden; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
@ -35,20 +39,25 @@ qbt_checksid(){
|
|||
}
|
||||
|
||||
qbt_isreachable(){
|
||||
nc -4 -vw 5 ${QBITTORRENT_SERVER} ${QBITTORRENT_PORT} 2>&1 &>/dev/null
|
||||
# shellcheck disable=SC2086
|
||||
nc -4 -vw 5 ${QBITTORRENT_SERVER} ${QBITTORRENT_PORT} &>/dev/null 2>&1
|
||||
}
|
||||
|
||||
fw_delrule(){
|
||||
if (docker exec ${VPN_CT_NAME} /sbin/iptables -L INPUT -n | grep -qP "^ACCEPT.*${configured_port}.*"); then
|
||||
docker exec ${VPN_CT_NAME} /sbin/iptables -D INPUT -i ${VPN_IF_NAME} -p tcp --dport ${configured_port} -j ACCEPT
|
||||
docker exec ${VPN_CT_NAME} /sbin/iptables -D INPUT -i ${VPN_IF_NAME} -p udp --dport ${configured_port} -j ACCEPT
|
||||
if (docker exec "${VPN_CT_NAME}" /sbin/iptables -L INPUT -n | grep -qP "^ACCEPT.*${configured_port}.*"); then
|
||||
# shellcheck disable=SC2086
|
||||
docker exec "${VPN_CT_NAME}" /sbin/iptables -D INPUT -i "${VPN_IF_NAME}" -p tcp --dport ${configured_port} -j ACCEPT
|
||||
# shellcheck disable=SC2086
|
||||
docker exec "${VPN_CT_NAME}" /sbin/iptables -D INPUT -i "${VPN_IF_NAME}" -p udp --dport ${configured_port} -j ACCEPT
|
||||
fi
|
||||
}
|
||||
|
||||
fw_addrule(){
|
||||
if ! (docker exec ${VPN_CT_NAME} /sbin/iptables -L INPUT -n | grep -qP "^ACCEPT.*${active_port}.*"); then
|
||||
docker exec ${VPN_CT_NAME} /sbin/iptables -A INPUT -i ${VPN_IF_NAME} -p tcp --dport ${active_port} -j ACCEPT
|
||||
docker exec ${VPN_CT_NAME} /sbin/iptables -A INPUT -i ${VPN_IF_NAME} -p udp --dport ${active_port} -j ACCEPT
|
||||
if ! (docker exec "${VPN_CT_NAME}" /sbin/iptables -L INPUT -n | grep -qP "^ACCEPT.*${active_port}.*"); then
|
||||
# shellcheck disable=SC2086
|
||||
docker exec "${VPN_CT_NAME}" /sbin/iptables -A INPUT -i "${VPN_IF_NAME}" -p tcp --dport ${active_port} -j ACCEPT
|
||||
# shellcheck disable=SC2086
|
||||
docker exec "${VPN_CT_NAME}" /sbin/iptables -A INPUT -i "${VPN_IF_NAME}" -p udp --dport ${active_port} -j ACCEPT
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
@ -61,8 +70,7 @@ get_portmap() {
|
|||
|
||||
if ! qbt_checksid; then
|
||||
echo "$(timestamp) | qBittorrent Cookie invalid, getting new SessionID"
|
||||
qbt_sid=$(qbt_login)
|
||||
if [ -z "${qbt_sid}" ]; then
|
||||
if ! qbt_login; then
|
||||
echo "$(timestamp) | Failed getting new SessionID from qBittorrent"
|
||||
return 1
|
||||
fi
|
||||
|
@ -70,15 +78,16 @@ get_portmap() {
|
|||
echo "$(timestamp) | qBittorrent SessionID Ok!"
|
||||
fi
|
||||
|
||||
configured_port=$(findconfiguredport ${qbt_sid})
|
||||
configured_port=$(findconfiguredport "${qbt_sid}")
|
||||
active_port=$(findactiveport)
|
||||
|
||||
echo "$(timestamp) | Public IP: ${public_ip}"
|
||||
echo "$(timestamp) | Configured Port: ${configured_port}"
|
||||
echo "$(timestamp) | Active Port: ${active_port}"
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
if [ ${configured_port} != ${active_port} ]; then
|
||||
if qbt_changeport ${qbt_sid} ${active_port}; then
|
||||
if qbt_changeport "${qbt_sid}" ${active_port}; then
|
||||
if fw_delrule; then
|
||||
echo "$(timestamp) | IPTables rule deleted for port ${configured_port} on ${VPN_CT_NAME} container"
|
||||
fi
|
||||
|
@ -99,7 +108,7 @@ get_portmap() {
|
|||
}
|
||||
|
||||
pre_reqs() {
|
||||
while read var; do
|
||||
while read -r var; do
|
||||
[ -z "${!var}" ] && { echo "$(timestamp) | ${var} is empty or not set."; exit 1; }
|
||||
done << EOF
|
||||
QBITTORRENT_SERVER
|
||||
|
@ -121,8 +130,12 @@ return 0
|
|||
load_vals(){
|
||||
public_ip=$(getpublicip)
|
||||
if qbt_isreachable; then
|
||||
qbt_sid=$(qbt_login)
|
||||
configured_port=$(findconfiguredport ${qbt_sid})
|
||||
if qbt_login; then
|
||||
configured_port=$(findconfiguredport "${qbt_sid}")
|
||||
else
|
||||
echo "$(timestamp) | Unable to login to qBittorrent at ${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}"
|
||||
exit 7
|
||||
fi
|
||||
else
|
||||
echo "$(timestamp) | Unable to reach qBittorrent at ${QBITTORRENT_SERVER}:${QBITTORRENT_PORT}"
|
||||
exit 6
|
||||
|
@ -130,11 +143,18 @@ load_vals(){
|
|||
active_port=''
|
||||
}
|
||||
|
||||
public_ip=
|
||||
configured_port=
|
||||
active_port=
|
||||
qbt_sid=
|
||||
|
||||
if pre_reqs; then load_vals; fi
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
[ -z ${public_ip} ] && { echo "$(timestamp) | Unable to grab VPN Public IP. Please check configuration"; exit 3; }
|
||||
# shellcheck disable=SC2086
|
||||
[ -z ${configured_port} ] && { echo "$(timestamp) | qBittorrent configured port value is empty(?). Please check configuration"; exit 4; }
|
||||
[ -z ${qbt_sid} ] && { echo "$(timestamp) | Unable to grab qBittorrent SessionID. Please check configuration"; exit 5; }
|
||||
[ -z "${qbt_sid}" ] && { echo "$(timestamp) | Unable to grab qBittorrent SessionID. Please check configuration"; exit 5; }
|
||||
|
||||
while true;
|
||||
do
|
||||
|
@ -143,7 +163,9 @@ do
|
|||
else
|
||||
echo "$(timestamp) | NAT-PMP/UPnP Failed"
|
||||
fi
|
||||
# shellcheck disable=SC2086
|
||||
echo "$(timestamp) | Sleeping for $(echo ${CHECK_INTERVAL}/60 | bc) minutes"
|
||||
# shellcheck disable=SC2086
|
||||
sleep ${CHECK_INTERVAL}
|
||||
done
|
||||
|
||||
|
|
Loading…
Reference in New Issue