mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-03-21 21:41:48 +00:00
Add/Delete rule is working
This commit is contained in:
@@ -42,7 +42,7 @@ defmodule FzHttpWeb.RuleLive.RuleListComponent do
|
||||
end
|
||||
end
|
||||
|
||||
defp action(id) do
|
||||
def action(id) do
|
||||
case id do
|
||||
:allowlist ->
|
||||
:accept
|
||||
|
||||
@@ -17,68 +17,79 @@ defmodule FzWall.CLI.Live do
|
||||
"forward" is the Netfilter hook we want to tie into.
|
||||
"""
|
||||
def setup do
|
||||
exec!("#{nft()} add table ip #{@table_name}")
|
||||
# Start with a blank slate
|
||||
teardown()
|
||||
|
||||
exec!(
|
||||
"#{nft()} 'add chain ip #{@table_name} forward { type filter hook forward priority 0 ; }'"
|
||||
)
|
||||
for protocol <- ["ip", "ip6"] do
|
||||
exec!("#{nft()} add table #{protocol} #{@table_name}")
|
||||
|
||||
exec!("#{nft()} 'add rule ip #{@table_name} forward counter accept'")
|
||||
exec!(
|
||||
"#{nft()} 'add chain #{protocol} #{@table_name} forward { type filter hook forward priority 0 ; }'"
|
||||
)
|
||||
|
||||
exec!("#{nft()} 'add rule #{protocol} #{@table_name} forward counter accept'")
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Flushes and removes the FireZone nftables table and base chain.
|
||||
"""
|
||||
def teardown do
|
||||
exec!("#{nft()} delete table ip #{@table_name}")
|
||||
for protocol <- ["ip", "ip6"] do
|
||||
exec!("#{nft()} delete table #{protocol} #{@table_name}")
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Adds nftables rule.
|
||||
"""
|
||||
def add_rule({dest, action}) do
|
||||
exec!("#{nft()} 'add rule ip #{@table_name} forward ip daddr #{dest} #{action}'")
|
||||
def add_rule({proto, dest, action}) do
|
||||
exec!("""
|
||||
#{nft()} 'add rule #{proto} #{@table_name} forward\
|
||||
#{proto} daddr #{standardized_dest(dest)} #{action}'
|
||||
""")
|
||||
end
|
||||
|
||||
@doc """
|
||||
List currently loaded rules.
|
||||
"""
|
||||
def list_rules do
|
||||
exec!("#{nft()} -a list table ip firezone")
|
||||
exec!("#{nft()} -a list table ip6 firezone")
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes nftables rule.
|
||||
"""
|
||||
def delete_rule_spec({dest, action} = rule_spec) do
|
||||
case get_rule_handle("ip daddr #{dest} #{action}") do
|
||||
{:ok, handle_num} ->
|
||||
exec!("#{nft()} delete rule #{@table_name} forward handle #{handle_num}")
|
||||
def delete_rule({proto, dest, action}) do
|
||||
rule_str = "#{proto} daddr #{standardized_dest(dest)} #{action}"
|
||||
rules = exec!("#{nft()} -a list table #{proto} #{@table_name}")
|
||||
|
||||
{:error, cmd_output} ->
|
||||
case rule_handle_regex(~r/#{rule_str}.*# handle (?<num>\d+)/, rules) do
|
||||
nil ->
|
||||
raise("""
|
||||
######################################################
|
||||
Could not get handle to delete rule!
|
||||
Rule spec: #{rule_spec}
|
||||
Rule spec: #{rule_str}
|
||||
|
||||
Current chain:
|
||||
#{cmd_output}
|
||||
Current rules:
|
||||
#{rules}
|
||||
######################################################
|
||||
""")
|
||||
end
|
||||
end
|
||||
|
||||
def get_rule_handle(rule_str) do
|
||||
cmd_output = exec!("#{nft()} list table #{@table_name}")
|
||||
|
||||
case rule_handle_regex(~r/#{rule_str}.*# handle (?<num>\d+)/, cmd_output) do
|
||||
[handle] ->
|
||||
{:ok, handle}
|
||||
|
||||
[] ->
|
||||
{:error, cmd_output}
|
||||
exec!("#{nft()} delete rule #{proto} #{@table_name} forward handle #{handle}")
|
||||
end
|
||||
end
|
||||
|
||||
defp rule_handle_regex(regex, cmd_output) do
|
||||
Regex.run(regex, cmd_output, capture: :all_names)
|
||||
end
|
||||
|
||||
def restore(_rules) do
|
||||
# XXX: Implement me
|
||||
@doc """
|
||||
Restores rules.
|
||||
"""
|
||||
def restore(rules) do
|
||||
# XXX: Priority?
|
||||
for rule_spec <- rules do
|
||||
add_rule(rule_spec)
|
||||
end
|
||||
end
|
||||
|
||||
def egress_address do
|
||||
@@ -102,6 +113,25 @@ defmodule FzWall.CLI.Live do
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Standardized IP addresses and CIDR ranges so that we can
|
||||
parse them out of the nftables rulesets.
|
||||
"""
|
||||
def standardized_dest(dest) do
|
||||
if String.contains?(dest, "/") do
|
||||
dest
|
||||
|> InetCidr.parse()
|
||||
|> InetCidr.to_string()
|
||||
else
|
||||
{:ok, addr} = dest |> String.to_charlist() |> :inet.parse_address()
|
||||
:inet.ntoa(addr) |> List.to_string()
|
||||
end
|
||||
end
|
||||
|
||||
defp rule_handle_regex(regex, rules) do
|
||||
Regex.run(regex, rules, capture: :all_names)
|
||||
end
|
||||
|
||||
defp egress_interface do
|
||||
case :os.type() do
|
||||
{:unix, :linux} ->
|
||||
|
||||
@@ -35,6 +35,7 @@ defmodule FzWall.MixProject do
|
||||
defp deps do
|
||||
[
|
||||
{:fz_common, in_umbrella: true},
|
||||
{:inet_cidr, "~> 1.0.0"},
|
||||
{:credo, "~> 1.4", only: [:dev, :test], runtime: false},
|
||||
{:excoveralls, "~> 0.13", only: :test}
|
||||
]
|
||||
|
||||
1
mix.lock
1
mix.lock
@@ -26,6 +26,7 @@
|
||||
"hackney": {:hex, :hackney, "1.17.4", "99da4674592504d3fb0cfef0db84c3ba02b4508bae2dff8c0108baa0d6e0977c", [:rebar3], [{:certifi, "~>2.6.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "de16ff4996556c8548d512f4dbe22dd58a587bf3332e7fd362430a7ef3986b16"},
|
||||
"html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
|
||||
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
|
||||
"inet_cidr": {:hex, :inet_cidr, "1.0.4", "a05744ab7c221ca8e395c926c3919a821eb512e8f36547c062f62c4ca0cf3d6e", [:mix], [], "hexpm", "64a2d30189704ae41ca7dbdd587f5291db5d1dda1414e0774c29ffc81088c1bc"},
|
||||
"inflex": {:hex, :inflex, "2.1.0", "a365cf0821a9dacb65067abd95008ca1b0bb7dcdd85ae59965deef2aa062924c", [:mix], [], "hexpm", "14c17d05db4ee9b6d319b0bff1bdf22aa389a25398d1952c7a0b5f3d93162dd8"},
|
||||
"jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
|
||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
||||
|
||||
Reference in New Issue
Block a user