Skip to content

Commit

Permalink
Merge pull request #11 from clajiness/v0.9
Browse files Browse the repository at this point in the history
V0.9
  • Loading branch information
clajiness authored Jan 2, 2025
2 parents b0ece23 + 4612fd7 commit 994efd2
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 22 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ This tool helps automate port forwarding from ProtonVPN to qBittorrent via OPNse
You can ignore qBittorrent by using the `QBIT_SKIP` environment variable.

## Installation
I recommend using the provided Docker Compose file to simplify the set up of qbop.
I recommend using the provided Docker Compose file to simplify the set up of qbop. This container must be connected to ProtonVPN due to the required `natpmpc` command to work properly.

The Docker container is available here: https://github.com/clajiness/qbop/pkgs/container/qbop

### Requirements
* Docker Engine - https://docs.docker.com/engine/install/
* OPNsense - This is the tutorial I used to set up selective routing to ProtonVPN. https://docs.opnsense.org/manual/how-tos/wireguard-selective-routing.html
* OPNsense
* Selective routing: https://docs.opnsense.org/manual/how-tos/wireguard-selective-routing.html
* API: https://docs.opnsense.org/development/how-tos/api.html
* qBittorrent
* ProtonVPN subscription

Expand All @@ -26,7 +28,7 @@ The Docker container is available here: https://github.com/clajiness/qbop/pkgs/c
2. `REQUIRED_ATTEMPTS` The number of loops with a new forwarded port before updating OPNsense and qBit. The default is 3, min is 1, and max is 10.
3. `PROTON_GATEWAY:` Default is `10.2.0.1`. Do not use http(s):// or a trailing slash.
4. `OPN_INTERFACE_ADDR:` OPNsense Interface Address. Requires http(s):// and no trailing slash.
5. `OPN_API_KEY:` OPNsense API Key - https://docs.opnsense.org/development/how-tos/api.html
5. `OPN_API_KEY:` OPNsense API Key
6. `OPN_API_SECRET:` OPNsense API Secret
7. `OPN_PROTON_ALIAS_NAME:` The firewall alias that you use for ProtonVPN's forwarded port. For example, `proton_vpn_forwarded_port`.
8. `QBIT_SKIP:` [`true`/`false`] Skip qBittorrent. If `true`, subsequent qBit environment variables are not required.
Expand Down
8 changes: 4 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ services:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
environment:
# This value determines how often the script runs. The default value is 45 seconds.
# This value determines how often the script runs. The default is 45 seconds. This value is recommended by ProtonVPN.
- LOOP_FREQ=
# The number of loops with a new forwarded port before updating OPNsense and qBit. The default is 3, min is 1, and max is 10.
- REQUIRED_ATTEMPTS=
# Usually 10.2.0.1. Do not use http(s):// or a trailing slash.
# Default is `10.2.0.1`. Do not use http(s):// or a trailing slash.
- PROTON_GATEWAY=
# OPNsense Interface Address. Requires http(s):// and no trailing slash.
- OPN_INTERFACE_ADDR=
# OPNsense API Key
- OPN_API_KEY=
# OPNsense API Secret
- OPN_API_SECRET=
# The firewall alias that you use for ProtonVPN's forwarded port
# The firewall alias that you use for ProtonVPN's forwarded port. For example, `proton_vpn_forwarded_port`.
- OPN_PROTON_ALIAS_NAME=
# [true/false] Skip qBittorrent. If true, subsequent qBit environment variables are not required.
# [`true`/`false`] Skip qBittorrent. If `true`, subsequent qBit environment variables are not required.
- QBIT_SKIP=
# The IP address of your qBittorrent app. Requires http(s):// and no trailing slash.
- QBIT_ADDR=
Expand Down
7 changes: 4 additions & 3 deletions qbop.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Bundler.require(:default)
Dir['./service/*.rb'].sort.each { |file| require_relative file }

# create Helpers object
helpers = Service::Helpers.new

# collect env variables in a config variable
Expand Down Expand Up @@ -37,7 +38,7 @@
# make natpmpc call to proton
response = proton.proton_natpmpc(config[:proton_gateway])

# raise error if natmpc call returns an error
# raise error if natpmpc call returns an error
raise StandardError, response[:stderr].chomp unless response[:stderr].empty?

# get proton response from output
Expand Down Expand Up @@ -158,13 +159,13 @@
response = qbit.qbt_app_set_preferences(forwarded_port, sid)

if response.status == 200
@logger.info("qBit's port has been updated to #{forwarded_port}")
@logger.info("qBit port has been updated to #{forwarded_port}")

# reset counter
counter.reset_qbit_change
counter.reset_qbit_attempt
else
@logger.error("qBit's port was not updated - response code: #{response.status}")
@logger.error("qBit port was not updated - response code: #{response.status}")
end
end
rescue StandardError => e
Expand Down
20 changes: 13 additions & 7 deletions service/opnsense.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,7 @@ module Service
class Opnsense
def initialize(config)
@config = config
@conn = Faraday.new(
url: config[:opnsense_interface_addr],
ssl: { verify: false }
) do |faraday|
faraday.request :authorization, :basic, config[:opnsense_api_key], config[:opnsense_api_secret]
end
@conn = faraday_conn(config)
end

def get_alias_uuid
Expand All @@ -31,7 +26,7 @@ def get_alias_value(uuid)
def set_alias_value(forwarded_port, uuid)
@conn.post do |req|
req.url "/api/firewall/alias/setItem/#{uuid}"
req.headers = { 'Content-Type' => 'application/json' }
req.headers['Content-Type'] = 'application/json'
req.body = { 'alias': { 'content': forwarded_port } }.to_json
end
end
Expand All @@ -41,5 +36,16 @@ def apply_changes
req.url '/api/firewall/alias/reconfigure'
end
end

private

def faraday_conn(config)
Faraday.new(
url: config[:opnsense_interface_addr],
ssl: { verify: false }
) do |faraday|
faraday.request :authorization, :basic, config[:opnsense_api_key], config[:opnsense_api_secret]
end
end
end
end
14 changes: 10 additions & 4 deletions service/qbit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ module Service
class Qbit
def initialize(config)
@config = config
@conn = Faraday.new(
url: config[:qbit_addr],
ssl: { verify: false }
)
@conn = faraday_conn(config)
end

def qbt_auth_login # rubocop:disable Metrics/MethodLength
Expand Down Expand Up @@ -41,5 +38,14 @@ def qbt_app_set_preferences(forwarded_port, sid)
req.body = URI.encode_www_form({ 'json': "{\"listen_port\": #{forwarded_port.to_i}}" })
end
end

private

def faraday_conn(config)
Faraday.new(
url: config[:qbit_addr],
ssl: { verify: false }
)
end
end
end
2 changes: 1 addition & 1 deletion version.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
version: 0.9.3
version: 0.9.5

0 comments on commit 994efd2

Please sign in to comment.