OPNsense Forum

Archive => 21.7 Legacy Series => Topic started by: sardaukar on December 04, 2021, 04:42:12 pm

Title: Help with Firewall plugin
Post by: sardaukar on December 04, 2021, 04:42:12 pm
I want to quickly toggle rules between hosts, and the Firewall API plugin seems perfect for it (even though I think this should be part of the normal API, but alas).

This is made more complicated by the fact that the plugin's rules have to be separate from the actual port forwarding rules I'm using. So, I've tried to replicate my SSH redirect to a certain host rule, but I always get a syntax error on the rule.

Here's the original port forward rule:

https://imgur.com/a/CJAZfmi

And here's the one in the Firewall -> Automation -> Source NAT section that I'm trying to get to do the same thing:

https://imgur.com/a/FngGR1V

Right off the bat, the "Destination" filter in the Automation rule doesn't allow me to use "WAN Address" like the proper port-forwarding rule. And when I disable the port-forward rule and activate this Automation one, I get syntax errors:

Code: [Select]
12-04-21 15:31:16 [ There were error(s) loading the rules: /tmp/rules.debug:64: syntax error - The line in question reads [64]: nat on igb1 inet proto TCP from any port any to any port 22 -> 192.168.1.12 port 22 # qoob_ssh ]

What am I doing wrong? Thanks in advance!
Title: Re: Help with Firewall plugin
Post by: franco on December 06, 2021, 09:33:11 am
Hi,

For port forward you want "Destination NAT".


Cheers,
Franco
Title: Re: Help with Firewall plugin
Post by: sardaukar on December 06, 2021, 09:37:19 am
Yeah, the Automation plugin doesn't have that - it's either Source NAT or Filter.

Anyway, I fixed it by changing the IP associated with an alias instead. Now all rules are the same, the only difference is what is the content of my `server` alias.

Here's the Ruby script I ended up using:

Code: [Select]
#!/usr/bin/env ruby

require 'rest-client'
require 'json'
require 'base64'

raise "must provide IP!" unless ARGV.size == 1

ip = ARGV[0]

KEY = "your API key"
SECRET = "your API secret"

ALIAS_UUID = "your alias UUID"
BASE_URL = "https://192.168.1.1:8443/api/firewall"

def empty_alias
  puts "emptying alias..."

  response = RestClient::Request.new(
    method: :post,
    url: "#{BASE_URL}/alias/setItem/#{ALIAS_UUID}",
    verify_ssl: OpenSSL::SSL::VERIFY_NONE,
    headers: {
      "Authorization" => "Basic " + Base64.strict_encode64("#{KEY}:#{SECRET}"),
      content_type: :json
    },
    payload: {
      alias: {
        name: "server",
        content: ""
      }
    }.to_json
  ).execute

  raise "error" unless response.code == 200
end

def set_alias_to(ip)
  puts "setting alias to #{ip} ..."
  response = RestClient::Request.new(
    method: :post,
    url: "#{BASE_URL}/alias_util/add/server",
    verify_ssl: OpenSSL::SSL::VERIFY_NONE,
    headers: {
      "Authorization" => "Basic " + Base64.strict_encode64("#{KEY}:#{SECRET}"),
      content_type: :json
    },
    payload: {
      address: ip
    }.to_json
  ).execute

  raise "error" unless response.code == 200
end

def apply
  puts "reconfiguring..."
  response = RestClient::Request.new(
    method: :post,
    url: "#{BASE_URL}/alias/reconfigure",
    verify_ssl: OpenSSL::SSL::VERIFY_NONE,
    headers: {
      "Authorization" => "Basic " + Base64.strict_encode64("#{KEY}:#{SECRET}"),
      content_type: :json
    },
    payload: {}.to_json
  ).execute

  raise "error" unless response.code == 200
end

empty_alias
set_alias_to(ip)
apply()

puts "done!"

Now I can just `set_server_alias 192.168.1.12` to change its content. Not super awesome, but OPNSense's API is a bit on the terrible side.
Title: Re: Help with Firewall plugin
Post by: franco on December 06, 2021, 09:49:01 am
I tried to reproduce "from any port any to any port 22" but could not.

You can use "wanip" in the target field and that should do it.


Cheers,
Franco
Title: Re: Help with Firewall plugin
Post by: sardaukar on December 06, 2021, 09:51:01 am
I find this solution a bit easier to understand than a plugin that introduces yet another layer of rules ::)
Title: Re: Help with Firewall plugin
Post by: franco on December 06, 2021, 09:53:47 am
I find the aversion a bit peculiar, but you don't see me rolling eyes over it just yet. ;)


Cheers,
Franco
Title: Re: Help with Firewall plugin
Post by: sardaukar on December 06, 2021, 09:57:17 am
I just think it's poorly structured. Why have core Firewall API functionality in another plugin? Why have it work on separate rules instead of the ones you want to toggle or change? It's needlessly confusing. 
Title: Re: Help with Firewall plugin
Post by: franco on December 06, 2021, 10:16:37 am
Because it's the closes we've come so far in having a firewall API sponsored. The original customer who helped shape this has moved on since which has you stuck on this I fear.

Remember the open source motto: my problem, someone else's money. ;)


Cheers,
Franco
Title: Re: Help with Firewall plugin
Post by: sardaukar on December 06, 2021, 10:26:38 am
True that! I'm just not used to this kind of API (I'm a web developer by day). But then again I'm on the Ruby/Elixir camp, which is a bit closer to the present than PHP ;D