Fix flood setup

This commit is contained in:
Manuel Thalmann 2025-04-18 04:29:01 +02:00
parent 1a300eaf54
commit b9542c2e20
6 changed files with 146 additions and 187 deletions

View file

@ -94,6 +94,7 @@ services:
rtorrent:
build:
dockerfile: ./rtorrent.Dockerfile
target: rtorrent
context: .
restart: unless-stopped
hostname: rtorrent
@ -101,7 +102,10 @@ services:
PUID: 1337
PGID: 1337
PHOME: /config
PVPN_CMD_ARGS: --p2p --random
MAX_UPTIME: 43200
sysctls:
net.ipv4.conf.all.rp_filter: 2
command: -o ratio.enable=
-o ratio.min.set=200
-o ratio.max.set=10000

View file

@ -20,7 +20,9 @@ begin
sudo cp "$dir/docker-compose.base.yml" "$root"
sudo cp "$dir/.dockerignore" "$root"
sudo cp "$dir/pvpn-cli.py" "$root"
sudo cp "$dir/proton-entrypoint.sh" "$root"
sudo cp "$dir/rtorrent.Dockerfile" "$root"
sudo cp "$dir/rtorrent-entrypoint.sh" "$root"
sudo cp "$source" "$overrides"
installDockerService $argv

View file

@ -0,0 +1,14 @@
#!/usr/bin/env bash
if [ -z "$PVPN_USERNAME" ]
then
echo "Please set the \`\$PVPN_USERNAME\` variable to your ProtonVPN username." >&2
exit 1
fi
export DBUS_SESSION_BUS_ADDRESS=`dbus-daemon --fork --config-file=/usr/share/dbus-1/session.conf --print-address`
mkdir -p ~/.config
ln -s /proton ~/.config/protonvpn
pvpn-cli || true
ip link show protonwire0 >/dev/null 2>&1 || exit
exec "$@"

View file

@ -1,100 +1,72 @@
#!/usr/bin/env python3
from argparse import ArgumentParser
from os import chmod, environ
from os.path import dirname
from random import choice
from re import M
from os import environ
import shlex
import subprocess
import sys
from protonvpn_cli import connection
from protonvpn_cli.constants import PASSFILE
from protonvpn_cli.utils import check_init, get_fastest_server, get_servers, set_config_value, pull_server_data
from typing import List
from protonvpn_cli.cli_wrapper import CLIWrapper
from protonvpn_nm_lib.api import FeatureEnum
from protonvpn_nm_lib.core.servers.list import LogicalServer
cli = CLIWrapper()
def run_proton(args):
exit(
subprocess.run(
["proton"],
cwd="/app",
env=dict(
environ,
PVPN_CMD_ARGS=" ".join(args))).returncode)
if not cli.protonvpn.get_session().is_valid:
print("You are not logged in.", file=sys.stderr)
environ["PVPN_USERNAME"] = environ["PVPN_USERNAME"] + (environ["PVPN_TAGS"] or "")
if (sys.__stdin__ != None) and sys.__stdin__.isatty():
print("Please log in to ProtonVPN", file=sys.stderr)
print("Username: " + environ["PVPN_USERNAME"], file=sys.stderr)
result = subprocess.run(["protonvpn-cli", "login", environ["PVPN_USERNAME"]])
with open(PASSFILE, "w") as f:
f.write("{0}\n{1}".format(environ["PVPN_USERNAME"], environ["PVPN_PASSWORD"]))
chmod(PASSFILE, 0o600)
if result.returncode != 0:
exit(result.returncode)
else:
exit(0)
else:
print("Please run this container interactively in order to log in.", file=sys.stderr)
exit(1)
check_init()
set_config_value("USER", "username", environ["PVPN_USERNAME"])
set_config_value("USER", "tier", environ["PVPN_TIER"])
set_config_value("USER", "default_protocol", environ["PVPN_PROTOCOL"])
set_config_value("USER", "initialized", 1)
parser = ArgumentParser()
args = sys.argv[1:]
if not args:
args = shlex.split(environ.get("PVPN_CMD_ARGS") or "")
environ["PVPN_CMD_ARGS"] = ""
parser = ArgumentParser(exit_on_error=False)
subParsers = parser.add_subparsers(dest="command")
initParser = subParsers.add_parser("init", aliases=["i"])
connectParser = subParsers.add_parser("connect", aliases=["c"])
for aliases in [
["-f", "--fastest"],
["-r", "--random"],
for alias in [
["-s", "--streaming"],
["--sc"],
["--p2p"],
["--tor"]
]:
connectParser.add_argument(*aliases, action="store_true")
parser.add_argument(*alias, action="store_true")
connectParser.add_argument("--cc")
parsedArgs = None
group = parser.add_mutually_exclusive_group()
try:
parsedArgs = parser.parse_args(args)
except:
pass
for alias in [
["-f", "--fastest"],
["-r", "--random"]
]:
group.add_argument(*alias, action="store_true")
if parsedArgs is not None and (
len(
list(
filter(
lambda item: item[1] not in [False, None],
vars(parsedArgs).items()))) > 1):
parser.add_argument("--cc")
parsedArgs = parser.parse_args()
features: List[FeatureEnum] = list()
def match(server):
features = list()
if parsedArgs.streaming:
features.append(FeatureEnum.STREAMING)
if parsedArgs.sc:
features.append(FeatureEnum.SECURE_CORE)
if parsedArgs.p2p:
features.append(FeatureEnum.P2P)
if parsedArgs.tor:
features.append(FeatureEnum.TOR)
if parsedArgs.streaming:
pass
if parsedArgs.sc:
pass
if parsedArgs.p2p:
pass
if parsedArgs.tor:
pass
return (parsedArgs.cc is None or server.exit_country.lower() == parsedArgs.cc.lower()) and (
def match(server: LogicalServer):
return (parsedArgs.cc is None or server.exit_country.lower() == parsedArgs.cc.lower()) and (
all(feature in server.features for feature in features))
pull_server_data(force=True)
servers = list(filter(lambda server: match(server), get_servers()))
if len(servers) > 0:
if parsedArgs.fastest or not parsedArgs.random:
server = get_fastest_server(servers)
else:
server = choice(servers)
run_proton(["connect", server["Name"]])
else:
raise Exception(
f"Unable to find a server matching the specified criteria {args[1:]}!")
else:
run_proton(args)
matches = cli.protonvpn.get_session().servers.filter(match)
server = matches.get_fastest_server() if parsedArgs.fastest else matches.get_random_server()
subprocess.run(["protonwire", "connect", server.data["Domain"]])

View file

@ -0,0 +1,45 @@
#!/usr/bin/env bash
fallback="$(expr ${NATPMP_TIMEOUT} \* 3 / 4)"
export NATPMP_INTERVAL="${NATPMP_INTERVAL:-$fallback}"
groupadd --gid $PGID $USERNAME >/dev/null
useradd --create-home --home-dir $PHOME $USERNAME --uid $PUID -g $USERNAME 2>/dev/null
chown $USERNAME:$USERNAME $PHOME
chown $USERNAME:$USERNAME "/etc/rtorrent"
mkdir -p /config/.local/share
chown $USERNAME:$USERNAME /data
chown -R $USERNAME:$USERNAME /data/rtorrent
ln -s /data/rtorrent /config/.local/share/
chown -R $USERNAME:$USERNAME /config
echo "Opening a port using NAT-PMP for $NATPMP_TIMEOUT seconds…"
output="$(natpmpc -g 10.2.0.1 -a 0 0 tcp "$NATPMP_TIMEOUT")"
natpmpc -g 10.2.0.1 -a 0 0 udp "$NATPMP_TIMEOUT"
port="$(echo "$output" | grep -m 1 " public port [[:digit:]]\+ " | sed "s/.* public port \([[:digit:]]\+\).*/\\1/")"
echo "Port $port has been opened for P2P data transfer!"
echo "The NAT-PMP port forwarding will be updated every $NATPMP_INTERVAL seconds"
export PEERPORT="$port"
set -m
{
while true
do
echo "Refreshing NAT-PMP port forwarding…"
natpmpc -g 10.2.0.1 -a 0 0 udp "$NATPMP_TIMEOUT"
natpmpc -g 10.2.0.1 -a 0 0 tcp "$NATPMP_TIMEOUT"
echo "NAT-PMP port forwarding has been refreshed!"
sleep "$NATPMP_INTERVAL"
done
} &
cmd="rtorrent -o network.port_range.set=$PEERPORT-$PEERPORT,system.daemon.set=true $@"
if [ ${MAX_UPTIME:-0} -gt 0 ]
then
sudo -iu $USERNAME $cmd &
pid=$!
sleep "$MAX_UPTIME"
pkill -9 $pid
else
sudo -u $USERNAME $cmd
fi

View file

@ -1,122 +1,44 @@
FROM walt3rl/proton-privoxy AS proton
FROM jesec/rtorrent AS rtorrent
FROM debian
FROM ghcr.io/tprasadtp/protonwire AS protonwire
FROM debian AS vpn
ARG PVPN_CLI_VER=2.2.12
ARG USERNAME=proton
RUN export DEBIAN_FRONTEND=noninteractive \
&& apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y \
curl \
iproute2 \
jq \
natpmpc \
sudo \
wireguard \
&& apt-get install -y gnupg2 \
&& curl https://repo.protonvpn.com/debian/dists/stable/main/binary-all/protonvpn-stable-release_1.0.8_all.deb -o protonvpn.deb \
&& dpkg -i ./protonvpn.deb \
&& apt-get remove -y gnupg2 \
&& apt-get update \
&& apt-get install -y protonvpn-cli \
&& rm -rf /var/lib/apt/lists/*
COPY --from=protonwire /usr/bin/protonwire /usr/bin/
COPY --chmod=755 proton-entrypoint.sh /usr/local/bin/proton-entrypoint
COPY --chmod=755 pvpn-cli.py /usr/bin/pvpn-cli
ENV PVPN_USERNAME= \
PVPN_USERNAME_FILE= \
PVPN_PASSWORD= \
PVPN_PASSWORD_FILE= \
PVPN_TIER=2 \
PVPN_PROTOCOL=udp \
PVPN_TAGS="+pmp" \
PVPN_CMD_ARGS="connect --p2p --random" \
PVPN_DEBUG= \
HOST_NETWORK= \
DNS_SERVERS_OVERRIDE= \
PVPN_CMD_ARGS="--p2p --random" \
USERNAME=proton \
PUID=1000 \
PGID=1000 \
PHOME=/home/${USERNAME} \
NATPMP_TIMEOUT=60 \
PHOME=/home/${USERNAME}
ENTRYPOINT [ "proton-entrypoint" ]
FROM vpn AS rtorrent
ENV NATPMP_TIMEOUT=60 \
NATPMP_INTERVAL= \
MAX_UPTIME=
WORKDIR /root
COPY --from=rtorrent / /
RUN apt-get update -y \
&& apt-get upgrade -y \
&& apt-get install -y \
git \
iproute2 \
iptables \
natpmpc \
openvpn \
pipenv \
procps \
python3 \
python3-pip \
python3-setuptools \
sudo \
&& rm -rf /var/lib/apt/lists
RUN pip3 install --break-system-packages git+https://github.com/Rafficer/linux-cli-community.git@v$PVPN_CLI_VER#egg=protonvpn-cli
RUN mkdir /app
COPY --from=proton /app/proton-privoxy/run /app/proton
COPY --from=proton /root/.pvpn-cli/pvpn-cli.cfg.clean /root/.pvpn-cli/pvpn-cli.cfg
RUN \
sed -i \
-e "/^exec privoxy/d" \
-e "/^ln -s/d" \
/app/proton \
&& install -t /usr/local/bin /app/proton \
&& rm /app/proton
RUN printf "%s\n" \
"python3 /app/pvpn-cli.py \"\$@\"" > ./pvpn-cli \
&& install -Dm 755 ./pvpn-cli /usr/local/bin \
&& rm ./pvpn-cli
RUN printf "%s\n" \
"#!/bin/bash" \
"groupadd --gid \$PGID ${USERNAME} > /dev/null" \
"useradd --create-home --home-dir \$PHOME ${USERNAME} --uid \$PUID -g ${USERNAME} 2>/dev/null" \
"chown ${USERNAME} \$PHOME" \
'[ ! -z "$1" ] && [ "$1" = "init" ] && export PVPN_CMD_ARGS="$@"' \
'if [ -z "$PVPN_USERNAME" ] && [ -z "$PVPN_USERNAME_FILE" ]; then' \
" echo 'Error: Either env var \$PVPN_USERNAME or \$PVPN_USERNAME_FILE is required.'" \
"exit 1" \
"fi" \
"" \
'if [ -z "$PVPN_PASSWORD" ] && [ -z "$PVPN_PASSWORD_FILE" ]; then' \
"echo 'Error: Either env var \$PVPN_PASSWORD or \$PVPN_PASSWORD_FILE is required.'" \
"exit 1" \
"fi" \
"" \
'[ -f "$PVPN_USERNAME_FILE" ] && PVPN_USERNAME=$(cat "$PVPN_USERNAME_FILE")' \
'[ -f "$PVPN_PASSWORD_FILE" ] && PVPN_PASSWORD=$(cat "$PVPN_PASSWORD_FILE")' \
"pvpn-cli || exit" \
'ip link show proton0 > /dev/null 2>&1 || exit' \
'fallback="$(expr ${NATPMP_TIMEOUT} \* 3 / 4)"' \
'export NATPMP_INTERVAL="${NATPMP_INTERVAL:-$fallback}"' \
'echo "Opening a port using NAT-PMP for $NATPMP_TIMEOUT seconds…"' \
'output="$(natpmpc -a 0 0 tcp "$NATPMP_TIMEOUT")"' \
'natpmpc -a 0 0 udp "$NATPMP_TIMEOUT"' \
'port="$(echo "$output" | grep -m 1 " public port [[:digit:]]\+ " | sed "s/.* public port \([[:digit:]]\+\).*/\\1/")"' \
'echo "Port $port has been opened for P2P data transfer!"' \
'echo "The NAT-PMP port forwarding will be updated every $NATPMP_INTERVAL seconds"' \
'export PEERPORT="$port"' \
"{" \
" while true" \
" do" \
' echo "Refreshing NAT-PMP port forwarding…"' \
' natpmpc -a 0 0 udp "$NATPMP_TIMEOUT"' \
' natpmpc -a 0 0 tcp "$NATPMP_TIMEOUT"' \
' echo "NAT-PMP port forwarding has been refreshed!"' \
' sleep "$NATPMP_INTERVAL"' \
" done" \
"} &" \
"set -m" \
'[ ${MAX_UPTIME:-0} -gt 0 ] && {' \
' sudo -iu '"${USERNAME}"' rtorrent -o network.port_range.set=$port-$port,system.daemon.set=true $@ &' \
' pid=$!' \
' sleep "$MAX_UPTIME"' \
' pkill -9 $pid' \
'} || {' \
' sudo -u '"${USERNAME}"' rtorrent -o network.port_range.set=$port-$port,system.daemon.set=true $@' \
'}' > ./rtorrent-entrypoint \
&& install -Dm 755 ./rtorrent-entrypoint /usr/local/bin \
&& rm ./rtorrent-entrypoint
COPY pvpn-cli.py /app/pvpn-cli.py
#RUN apt-get update -y \
# && apt-get install -y sudo
# RUN echo "${USERNAME} ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers
VOLUME [ "/proton" ]
ENTRYPOINT [ "rtorrent-entrypoint" ]
RUN mkdir -p /data/rtorrent
COPY --chmod=777 --from=jesec/rtorrent / /
COPY --chmod=755 ./rtorrent-entrypoint.sh /usr/local/bin/rtorrent-entrypoint
ENTRYPOINT [ "proton-entrypoint", "rtorrent-entrypoint" ]