diff --git a/README.md b/README.md index 14cf89f..87e614a 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ A tool for keeping ProtonVPN, OPNsense, and qBittorrent ports in sync. ## Purpose This tool helps automate port forwarding from ProtonVPN to qBittorrent via OPNsense. The tool polls ProtonVPN for the given forwarded port, checks the port set in OPNsense and qBittorrent, and updates it if necessary. +Version v0.5 and later allows you to skip qBittorrent and just sync Proton's forwarded port to OPNsense. + ## Docker Install I recommend using the provided Docker container to simplify the set up of qbop. An example Docker Compose file is provided. @@ -28,9 +30,10 @@ I'd recommend using Docker Compose to configure and run your instance of qbop. T 4. `OPN_API_KEY:` Your OPNsense API key - https://docs.opnsense.org/development/how-tos/api.html 5. `OPN_API_SECRET:` Your OPNsense API secret 6. `OPN_PROTON_ALIAS_NAME:` The firewall alias that you use for ProtonVPN's forwarded port. For example, `proton_vpn_forwarded_port`. -7. `QBIT_ADDR:` The IP address of your qBittorrent app. For example, `http://10.1.1.100:8080`. -8. `QBIT_USER:` Your qBittorrent username -9. `QBIT_PASS:` Your qBittorrent password +7. `QBIT_SKIP:` [true/false] Skip qBittorrent. If true, subsequent qBit environment variables are not necessary. +8. `QBIT_ADDR:` The IP address of your qBittorrent app. For example, `http://10.1.1.100:8080`. +9. `QBIT_USER:` Your qBittorrent username +10. `QBIT_PASS:` Your qBittorrent password ## Native Install @@ -51,8 +54,9 @@ Clone the qbop repo to your machine. Remove the existing file `config.yml`. Copy 4. `opnsense_api_key:` Your OPNsense API key - https://docs.opnsense.org/development/how-tos/api.html 5. `opnsense_api_secret:` Your OPNsense API secret 6. `opnsense_alias_name:` The firewall alias that you use for ProtonVPN's forwarded port. For example, `proton_vpn_forwarded_port`. -7. `qbit_addr:` The IP address of your qBittorrent app. For example, `http://10.1.1.100:8080`. -8. `qbit_user:` Your qBittorrent username -9. `qbit_pass:` Your qBittorrent password +7. `qbit_skip:` [true/false] Skip qBittorrent. If true, subsequent qBit environment variables are not necessary. +8. `qbit_addr:` The IP address of your qBittorrent app. For example, `http://10.1.1.100:8080`. +9. `qbit_user:` Your qBittorrent username +10. `qbit_pass:` Your qBittorrent password Next, you must start the script. You can manually start it, if you wish, with `ruby qbop.rb`. I'd recommend setting it up to start on boot, though. I've included an example systemd service file for those on Linux. diff --git a/config.yml b/config.yml index 746ab7a..9831f1b 100644 --- a/config.yml +++ b/config.yml @@ -15,6 +15,7 @@ opnsense_api_secret: <%= ENV["OPN_API_SECRET"] %> opnsense_alias_name: <%= ENV["OPN_PROTON_ALIAS_NAME"] %> # qBit +qbit_skip: <%= ENV["QBIT_SKIP"] %> qbit_addr: <%= ENV["QBIT_ADDR"] %> qbit_user: <%= ENV["QBIT_USER"] %> qbit_pass: <%= ENV["QBIT_PASS"] %> diff --git a/config.yml.example b/config.yml.example index e25391f..3218ed9 100644 --- a/config.yml.example +++ b/config.yml.example @@ -12,6 +12,7 @@ opnsense_api_secret: opnsense_alias_name: proton_vpn_forwarded_port # qBit +qbit_skip: [true/false] qbit_addr: http:// qbit_user: qbit_pass: diff --git a/docker-compose.yml b/docker-compose.yml index e23b202..512410c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,9 +12,10 @@ services: - PROTON_GATEWAY= - OPN_INTERFACE_ADDR= - OPN_API_KEY= - - OPN_API_SECRET= + - OPN_API_SECRET= - OPN_PROTON_ALIAS_NAME= - - QBIT_ADDR= + - QBIT_SKIP= + - QBIT_ADDR= - QBIT_USER= - QBIT_PASS= diff --git a/qbop.rb b/qbop.rb index 6fa02d1..ccb0be0 100644 --- a/qbop.rb +++ b/qbop.rb @@ -147,57 +147,61 @@ def parse_config end # qBit section - begin - # create qBit object - qbit ||= Service::Qbit.new + unless config["qbit_skip"].nil? || config["qbit_skip"].to_s.downcase == "true" + begin + # create qBit object + qbit ||= Service::Qbit.new - # get sid from qBit - sid = qbit.qbt_auth_login(config) + # get sid from qBit + sid = qbit.qbt_auth_login(config) - # get port from qBit - qbt_port = qbit.qbt_app_preferences(config, sid) + # get port from qBit + qbt_port = qbit.qbt_app_preferences(config, sid) - if qbt_port != forwarded_port - @logger.info("qBit port #{qbt_port} does not match Proton forwarded port #{forwarded_port}. Attempt #{counter[:qbit_attempt]} of 3.") + if qbt_port != forwarded_port + @logger.info("qBit port #{qbt_port} does not match Proton forwarded port #{forwarded_port}. Attempt #{counter[:qbit_attempt]} of 3.") - # after 3 attempts, if the ports still don't match, set the qBit port to be updated - if counter[:port] == forwarded_port && counter[:qbit_attempt] > 2 - counter[:qbit_change] = true + # after 3 attempts, if the ports still don't match, set the qBit port to be updated + if counter[:port] == forwarded_port && counter[:qbit_attempt] > 2 + counter[:qbit_change] = true + end + else + # reset counter if ports match + counter[:qbit_attempt] = 1 if counter[:qbit_attempt] != 1 + @logger.info("qBit port #{qbt_port} matches Proton forwarded port #{forwarded_port}") end - else - # reset counter if ports match - counter[:qbit_attempt] = 1 if counter[:qbit_attempt] != 1 - @logger.info("qBit port #{qbt_port} matches Proton forwarded port #{forwarded_port}") - end - # keep track of how many times the qBit and Proton ports don't match - if qbt_port != forwarded_port - counter[:port] = forwarded_port - counter[:qbit_attempt] += 1 - end + # keep track of how many times the qBit and Proton ports don't match + if qbt_port != forwarded_port + counter[:port] = forwarded_port + counter[:qbit_attempt] += 1 + end - # set qBit port if counter is set to true - if counter[:qbit_change] == true - # set qBit port - response = qbit.qbt_app_set_preferences(config, forwarded_port, sid) + # set qBit port if counter is set to true + if counter[:qbit_change] == true + # set qBit port + response = qbit.qbt_app_set_preferences(config, forwarded_port, sid) - if response.code == "200" - @logger.info("qBit's port has been updated to #{forwarded_port}") + if response.code == "200" + @logger.info("qBit's port has been updated to #{forwarded_port}") - # reset counter - counter[:qbit_change] = false - counter[:qbit_attempt] = 1 - else - @logger.error("qBit's port was not updated") + # reset counter + counter[:qbit_change] = false + counter[:qbit_attempt] = 1 + else + @logger.error("qBit's port was not updated") + end end - end - rescue Exception => e - @logger.error("qBit has returned an error:") - @logger.error(e) + rescue Exception => e + @logger.error("qBit has returned an error:") + @logger.error(e) - @logger.info("sleeping for #{config['loop_freq'].to_i} seconds and trying again") - sleep config["loop_freq"].to_i - next + @logger.info("sleeping for #{config['loop_freq'].to_i} seconds and trying again") + sleep config["loop_freq"].to_i + next + end + else + @logger.info("qBit check skipped") end # sleep before looping again diff --git a/version.yml b/version.yml index 2dbaf68..0a8de35 100644 --- a/version.yml +++ b/version.yml @@ -1,2 +1,2 @@ --- -version: 0.4.1 +version: 0.5.1