How to modify port forwarding rules via API

Started by TnZzZHlp, June 22, 2024, 04:07:33 AM

Previous topic - Next topic
Hi, I am looking for an API to modify port forwarding, but after reviewing https://docs.opnsense.org/development/api/core/firewall.html, I couldn't find a relevant API. I would be very grateful if you could provide a solution.  :)

What are you trying to modify, specifically? If you're trying to update the forwarded port (which seems the likely case), set an alias and update that.

Here's some Ruby code I wrote a while back to get the job done. This class can grab the UUID of the alias, find the value, set it to whatever you like, and then apply it.

Good luck!


module Service
  class Opnsense
    def get_alias_uuid(config)
      uri = URI("#{config['opnsense_interface_addr']}/api/firewall/alias/getAliasUUID/#{config['opnsense_alias_name']}")

      # Create client
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE

      # Create Request
      req =  Net::HTTP::Get.new(uri)
      req.basic_auth config["opnsense_api_key"], config["opnsense_api_secret"]

      # Fetch Request
      res = http.request(req)
      JSON.parse(res.body)["uuid"]
    rescue StandardError => e
      @logger.error("get_alias_uuid - HTTP Request failed - (#{e.message})")
    end

    def get_alias_value(config, uuid)
      uri = URI("#{config['opnsense_interface_addr']}/api/firewall/alias/get")

      # Create client
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE

      # Create Request
      req =  Net::HTTP::Get.new(uri)
      req.basic_auth config["opnsense_api_key"], config["opnsense_api_secret"]

      # Fetch Request
      res = http.request(req)

      alias_content = JSON.parse(res.body).dig("alias", "aliases", "alias", uuid, "content")
      alias_content.values[0]["value"].to_i
    rescue StandardError => e
      @logger.error("get_alias_value - HTTP Request failed - (#{e.message})")
    end

    def set_alias_value(config, forwarded_port, uuid)
      uri = URI("#{config['opnsense_interface_addr']}/api/firewall/alias/setItem/#{uuid}")

      # Create client
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE
      body = {"alias": {"content": forwarded_port}}.to_json

      # Create Request
      req =  Net::HTTP::Post.new(uri)
      # Add headers
      req.basic_auth config["opnsense_api_key"], config["opnsense_api_secret"]
      # Add headers
      req.add_field "Content-Type", "application/json; charset=utf-8"
      # Set body
      req.body = body

      # Fetch Request
      http.request(req)
    rescue StandardError => e
      @logger.error("set_alias_value - HTTP Request failed - (#{e.message})")
    end

    def apply_changes(config)
      uri = URI("#{config['opnsense_interface_addr']}/api/firewall/alias/reconfigure")

      # Create client
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE

      # Create Request
      req =  Net::HTTP::Post.new(uri)
      # Add headers
      req.basic_auth config["opnsense_api_key"], config["opnsense_api_secret"]

      # Fetch Request
      http.request(req)
    rescue StandardError => e
      @logger.error("apply_changes - HTTP Request failed - (#{e.message})")
    end
  end
end

June 22, 2024, 06:36:29 AM #2 Last Edit: June 22, 2024, 07:24:51 AM by TnZzZHlp
Quote from: BondiBlueBalls on June 22, 2024, 06:00:42 AM
What are you trying to modify, specifically? If you're trying to update the forwarded port (which seems the likely case), set an alias and update that.

Here's some Ruby code I wrote a while back to get the job done. This class can grab the UUID of the alias, find the value, set it to whatever you like, and then apply it.

Good luck!


module Service
  class Opnsense
    def get_alias_uuid(config)
      uri = URI("#{config['opnsense_interface_addr']}/api/firewall/alias/getAliasUUID/#{config['opnsense_alias_name']}")

      # Create client
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE

      # Create Request
      req =  Net::HTTP::Get.new(uri)
      req.basic_auth config["opnsense_api_key"], config["opnsense_api_secret"]

      # Fetch Request
      res = http.request(req)
      JSON.parse(res.body)["uuid"]
    rescue StandardError => e
      @logger.error("get_alias_uuid - HTTP Request failed - (#{e.message})")
    end

    def get_alias_value(config, uuid)
      uri = URI("#{config['opnsense_interface_addr']}/api/firewall/alias/get")

      # Create client
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE

      # Create Request
      req =  Net::HTTP::Get.new(uri)
      req.basic_auth config["opnsense_api_key"], config["opnsense_api_secret"]

      # Fetch Request
      res = http.request(req)

      alias_content = JSON.parse(res.body).dig("alias", "aliases", "alias", uuid, "content")
      alias_content.values[0]["value"].to_i
    rescue StandardError => e
      @logger.error("get_alias_value - HTTP Request failed - (#{e.message})")
    end

    def set_alias_value(config, forwarded_port, uuid)
      uri = URI("#{config['opnsense_interface_addr']}/api/firewall/alias/setItem/#{uuid}")

      # Create client
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE
      body = {"alias": {"content": forwarded_port}}.to_json

      # Create Request
      req =  Net::HTTP::Post.new(uri)
      # Add headers
      req.basic_auth config["opnsense_api_key"], config["opnsense_api_secret"]
      # Add headers
      req.add_field "Content-Type", "application/json; charset=utf-8"
      # Set body
      req.body = body

      # Fetch Request
      http.request(req)
    rescue StandardError => e
      @logger.error("set_alias_value - HTTP Request failed - (#{e.message})")
    end

    def apply_changes(config)
      uri = URI("#{config['opnsense_interface_addr']}/api/firewall/alias/reconfigure")

      # Create client
      http = Net::HTTP.new(uri.host, uri.port)
      http.use_ssl = true
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE

      # Create Request
      req =  Net::HTTP::Post.new(uri)
      # Add headers
      req.basic_auth config["opnsense_api_key"], config["opnsense_api_secret"]

      # Fetch Request
      http.request(req)
    rescue StandardError => e
      @logger.error("apply_changes - HTTP Request failed - (#{e.message})")
    end
  end
end


Thank you, I am a Opnsense noob and I tried it. But I can't find rule's uuid in "api/firewall/alias/get"
This is respond https://paste.debian.net/1321134/
I set a port forward rule like this

Interface   Proto   Address   Ports      Address           Ports   IP                   Ports           Description      
WAN           TCP           *           *      WAN address   80   192.168.1.12   80 (HTTP)   Test