mrash / fwknop

Single Packet Authorization > Port Knocking
http://www.cipherdyne.org/fwknop/
GNU General Public License v2.0
1.06k stars 229 forks source link

Linux NFTables Support in fwknop #107

Open theckman opened 10 years ago

theckman commented 10 years ago

NFTables, which is a new packet filter subsystem for the Linux kernel, has been pulled in to the git tree for the Linux 3.13 build. NFTables is on-track to replace the tried-and-true iptables system.

This issue is to request that, when NFTables is pushed in to mainline, support be added to fwknop.

I'm not sure what systems/kernels you have access to for development purposes, but if needed I should be able to provide a system with nftables / Linux 3.13

mrash commented 10 years ago

Thanks for the suggestion. This will definitely be added to fwknop and the other cipherdyne.org projects as well.

mrash commented 8 years ago

With the new command open/close cycle stuff, I think integrating with NFTables will be easy.

fabianfrz commented 7 years ago

are there any news on this issue?

LuciferSam86 commented 6 years ago

any news?

andrewgdunn commented 5 years ago

I'll poke at this as well, it's blocking our deployment.

mauricev commented 4 years ago

Perhaps it's not as easy as originally expected. 😐

mpsOxygen commented 2 years ago

Wow, it's been 8 years and nothing?

q2dg commented 2 years ago

9 years already

Stephen-Seo commented 2 years ago

I think it may be possible to use a custom script that takes the iptables ... command and uses iptables-translate ... to convert the iptables ... command to an nft ... equivalent (see the "command translation" section on this page on nftables). Might have to convert the filter name if the current nftables ruleset uses a differently named filter name.

I think this is possible because this option --with-iptables=/path/to/iptables exists. Maybe just have it point to your custom script, and have the script convert the iptables ... command and apply it to the current nftables rules.

It's kind of a "hack" to get it working this way, as one would probably have to write up their own script and have some checks in place so that the rule would work correctly with the current nftables ruleset.

EDIT: Oh wait, the --with-iptables=... is a compiler (configure) option, not a command option..

EDIT2: So I 'm guessing fwknop uses the first valid iptables command in $PATH. Maybe one could create a script, name it as iptables, and place it in some other directory and prepend that directory into $PATH. One would have to make sure the server would use that custom $PATH though. Seems a bit too much trouble to get it working this way, unless you really want it to use nftables rules.

EDIT3: So it looks like one can set the FIREWALL_EXE in the fwknopd.conf, so doing some $PATH hackery is probably not needed. I may investigate what a custom script should be to be able to handle nftables.

EDIT4: It appears that fwknopd expects to work with output from iptables ..., so I don't think the "custom script approach" will work here. fwknop will have to implement proper nftables support, unless I overlooked something.

geo99918 commented 1 year ago

10 years, is this going to be fixed or we look for alternatives to fwknop ?

bam80 commented 1 year ago

Yeah that's become critical.. Speaking of the alternatives, what do we actually have?

geo99918 commented 1 year ago

Yeah that's become critical.. Speaking of the alternatives, what do we actually have?

I heard wireguard has similar feature of not revealing itself unless the package with right key arrives. Maybe not the same functionality but we can live with it.

bam80 commented 1 year ago

Speaking of wireguard for openwrt low powered devices particularly, some time ago I had success with this project: https://github.com/adyanth/openwrt-tailscale-enabler It's a overkill of course but I see no other real alternatives right now..

davidandreoletti commented 1 year ago

@mrash Some additional context for consideration regarding prioritising #107 over #285.

  1. OpenWRT switched from fw3 (iptables) to fw4 (netfilter/nftables) in at least 22.03.x releases.
  2. OpenWRT has a fwknop package. The OpenWRT fwknop package does not support fw4 yet since the upstream package mrash/fwknop binary does not.
  3. OpenWRT users with your (awesome) software installed can't get access to their freshly updated routers.

Have you had brief look at iptables to nftables migration instructions yet ? Helpful for scoping some of the change(s) needed.

mrash commented 1 year ago

I suspect that fwknop can support nft as it stands today with the "command cycle" feature. Here is an example of getting fwknop to work with ipset even though ipset is not "directly" supported in the same way as iptables/pf/ipfw: https://www.cipherdyne.org/fwknop/docs/fwknop-tutorial.html#spa-with-ipset Similarly, I'm guessing fwknop could support nft. It would be an interesting exercise to see if this could actually work. That said, I agree that fwknop should support nft in the same way as iptables since nft is clearly here to stay.

davidandreoletti commented 1 year ago

nft is clearly here to stay

Yes!

The following major Linux distributions continue to distribute iptables but have already moved to nfttables in some capacity for core firewalling functionality via firewalld:

The following Linux distributions hint at an eventual ipset deprecation:

fwknop can support nft as it stands today with the command cycle feature

@mrash No doubt fwknop will have to have full programmatic nfttables support eventually to remain well supported for Linux end users.

In the meantime, would you consider the following as a suitable short term course of action for a growing list of fwknop users coming to knock at this GitHub repo for better nftables support ?

  1. @mrash lists most fwknop generated iptables rules. I do not know if theexample iptables rules needs to covers additional cases beyond:
    • port open rule
    • port close rule
    • keep connection state tracked after port closed rule
  2. @bam80 / @geo99918 / @Stephen-Seo and others (@davidandreoletti included) convert the rules into nftables rules via iptables-translate + test them on OpenWRT routers using fwknop's access.conf CMD_CYCLE_OPEN/CMD_CYCLE_CLOSE settings
  3. Provide @mrash with nfttables rules example to update the doc with for future users, if that's something you are interested in.
bam80 commented 1 year ago

@davidandreoletti you took it off my tongue, I was thinking about this approach too.
For 1) I would need help. For other steps, I will upgrade my router soon and would be able to help myself.

bam80 commented 1 year ago

In the meantime, would you consider the following as a suitable short term course of action for a growing list of fwknop users coming to knock at this GitHub repo for better nftables support ?

@davidandreoletti maybe you could create a separate issue for that where we could share the info?

davidandreoletti commented 1 year ago

The current issue is the right spot for it as:

davidandreoletti commented 1 year ago

nft is clearly here to stay

Yes!

The following major Linux distributions continue to distribute iptables but have already moved to nfttables in some capacity for core firewalling functionality via firewalld:

The following Linux distributions hint at an eventual ipset deprecation:

fwknop can support nft as it stands today with the command cycle feature

@mrash No doubt fwknop will have to have full programmatic nfttables support eventually to remain well supported for Linux end users.

In the meantime, would you consider the following as a suitable short term course of action for a growing list of fwknop users coming to knock at this GitHub repo for better nftables support ?

  1. @mrash lists most fwknop generated iptables rules. I do not know if theexample iptables rules needs to covers additional cases beyond:
  • port open rule
  • port close rule
  • keep connection state tracked after port closed rule
  1. @bam80 / @geo99918 / @Stephen-Seo and others (@davidandreoletti included) convert the rules into nftables rules via iptables-translate + test them on OpenWRT routers using fwknop's access.conf CMD_CYCLE_OPEN/CMD_CYCLE_CLOSE settings
  2. Provide @mrash with nfttables rules example to update the doc with for future users, if that's something you are interested in.

@mrash (ping)

bam80 commented 1 year ago

@mrash if you have no more time/interest to support the project, better let us know earlier than later

akerl commented 1 year ago

I'm not sure why y'all would need the author to list the iptables commands in the code, or update the docs. The code's right there for you to look at and submit a PR.

bam80 commented 1 year ago

@akerl every project should have a maintainer(s). If there is no maintainer any more, it should be declared publicly. For now it was said several times by author there gonna be a maintenance release and such, but things didn't seem to progressed since then. So it's better just describe the situation precisely than feed us on false hopes.

wxwx commented 2 weeks ago

I hacked together my own solution for using nftables instead of iptables.

Maybe it is of help to someone.

I dont take any responsibility if this may do something it was not intended to do.

That being said, I am sorry for my poor scripting skills. Almost certainly someone can do it better or improve

WARNING: Before you do all of this on a live system, take care that you can log into your system without using ssh with port 22, because that is switched of here.

This works for me on debian12 as root user.

protocol      ssh
server:       10.0.0.10
external if:  enp0s3
apt-get install nftables fwknop-server

tee /etc/nftables.conf >/dev/null <<XXXXX
#!/usr/sbin/nft -f

flush ruleset 

table inet filter { 
    chain input {
        type filter hook input priority 0; policy drop; 

        # allow from loopback 
        iifname 10 accept; 

        # established/ related connections 
        ct state established, related accept; 

        # invalid connections 
        ct state invalid drop;

        # no ping floods 
        ip6 nexthdr  icmpv6 icmpv6 type echo-request limit rate 2/second accept; 
        ip  protocol icmp   icmp   type echo-request limit rate 2/second accept; 

        # drop all ssh connection
        tcp dport 22   reject with tcp reset; 

        udp dport 53                                      reject with icmp port-unreachable;
    }
    chain forward {
        type filter hook input priority 0; policy accept;
    }
    chain output {
        type filter hook input priority 0; policy accept;
    }
}
XXXXX

cp /etc/fwknop/access.conf  /etc/fwknop/access.conf.ORIG
cp /etc/fwknop/fwknopd.conf /etc/fwknop/fwknopd.conf.ORIG

tee /etc/fwknop/fwknop.conf >/dev/null <<XXXXX
PCAP_INTF                   enp0s3;    # maybe change your ethernet interface
XXXXX

tee /etc/fwknop/access.conf >/dev/null <<'XXXXX'
SOURCE                    ANY
OPEN_PORTS                tcp/22
FW_ACCESS_TIMEOUT         30
REQUIRE_SOURCE_ADDRESS    Y
KEY_BASE64                __REPLACE_BY_YOUR_OWN_KEY_BASE_64__________=
HMAC_KEY_BASE64           __REPLACE_BY_YOUR_OWN_HMAC_KEY_BASE64_________________________________________________==
CMD_CYCLE_TIMER           30
CMD_CYCLE_OPEN            /root/bin/fwknop_ssh.sh open  $IP $PORT $PROTO $SRC $PKT_SRC $DST $TIMEOUT
CMD_CYCLE_CLOSE           /root/bin/fwknop_ssh.sh close $IP $PORT $PROTO $SRC $PKT_SRC $DST $TIMEOUT
XXXXX

mkdir -p /root/bin

tee /root/bin/fwknop_ssh.sh >/dev/null <<'XXXXX'
#!/usr/bin/bash

ACTION=$1
IP=$2
PORT=$3
PROTO=$4
SRC=$5
PKT_SRC=$6
DST=$7
TIMEOUT=$8

LOG=/root/nft.log

ACTION_TOKEN=""
if [ "$ACTION" = "open" ]; then
    ACTION_TOKEN="open"
elif [ "$ACTION" = "close" ]; then
    ACTION_TOKEN="close"
else
    ACTION_TOKEN="unknown"
    echo "$ACTION_TOKEN: ($DATE) "       >>$LOG
    echo "   ACTION:  $ACTION"  >>$LOG
    echo ""
fi

DATE=`/usr/bin/date +"%Y-%m-%d_%H:%M:%S %s"`
echo "$ACTION_TOKEN: ($DATE) "       >>$LOG
echo "   ACTION:  $ACTION"  >>$LOG
echo "   ip:      $IP"      >>$LOG
echo "   port:    $PORT"    >>$LOG
echo "   proto:   $PROTO"   >>$LOG
echo "   src:     $SRC"     >>$LOG
echo "   pkt_src: $PKT_SRC" >>$LOG
echo "   dst:     $DST"     >>$LOG
echo "   timeout: $TIMEOUT" >>$LOG
echo ""                     >>$LOG

RULE_ID=fwknop_$TIMEOUT

if [ "$ACTION_TOKEN" = "open" ]; then
    HANDLE=`nft -a list table inet filter | grep "tcp dport 22" | sed -e 's/^.* //'`
    echo "   HANDLE:  $HANDLE"  >>$LOG
    echo ""                     >>$LOG

    if [ "$HANDLE" = "" ]; then
        # insert at top of chain
        CMD="nft insert rule inet filter input ip saddr $IP tcp dport $PORT accept comment $RULE_ID"
    else
        # insert before the dport 22 rule
        CMD="nft insert rule inet filter input handle $HANDLE ip saddr $IP tcp dport $PORT accept comment $RULE_ID"
    fi
    echo "open  --- $CMD"       >>$LOG
    echo ""                     >>$LOG

    $CMD
fi

if [ "$ACTION_TOKEN" = "close" ]; then
    DELETE_HANDLE=`nft -a list table inet filter | grep "comment \"$RULE_ID\"" | sed -e 's/^.* //'`
    echo "Trying to delete rule with"        >>$LOG
    echo "   DELETE_HANDLE:  $DELETE_HANDLE" >>$LOG
    echo ""                                  >>$LOG

    if [ "$DELETE_HANDLE" = "" ]; then
        # no rule found that could be deleted
        CMD="# !!! FAILURE !!! ##############################################################################"
    else
        # delete rule
        CMD="nft delete rule inet filter input handle $DELETE_HANDLE"
    fi
    echo "close --- $CMD"       >>$LOG
    echo ""                     >>$LOG

    $CMD

fi
XXXXX

chmod 700 /root/bin/fwknop_ssh.sh

systemctl enable fwknop-server.service
systemctl start fwknop-server.service
/etc/nftables.conf

# on the client you need something like this in .fwknoprc
[default]
[10.0.0.10]
ACCESS                      tcp/22
SPA_SERVER                  10.0.0.10
KEY_BASE64                  __REPLACE_BY_YOUR_OWN_KEY_BASE_64__________=
HMAC_KEY_BASE64             __REPLACE_BY_YOUR_OWN_HMAC_KEY_BASE64_________________________________________________==
USE_HMAC                    Y