NHAS / wag

Simple Wireguard 2FA
BSD 3-Clause "New" or "Revised" License
499 stars 27 forks source link

ACL Rule Mfa always has precedence over Allow? #43

Closed cheegui closed 1 year ago

cheegui commented 1 year ago

Hi All

In OpenVPN, our clients are able to access each other using the VPN tunnel IP address. We are unable to do this with WAG.

10.125.0.0/16 is the VPN tunnel network. 10.125.0.1 is the VPN tunnel IP address of the WG interface of our WG "server".

The config below does not work because the Mfa takes precedence over the Allow. So 10.125.0.1 also requires MFA and therefore we cannot reach http://10.125.0.1:8080 to enter the MFA code.

            "group:users": {
                "Allow": [
                    "10.125.0.1/32 8080/any"
                ],
                "Mfa": [
                    "10.125.0.0/16",
                    "192.168.5.0/24",
                    "192.168.6.0/24"
                ]
            },

To make it work, we have to remove the "10.125.0.0/16" from the Mfa. The config below works:

            "group:users": {
                "Allow": [
                    "10.125.0.1/32 8080/any"
                ],
                "Mfa": [
                    "192.168.5.0/24",
                    "192.168.6.0/24"
                ]
            },

But we want to be able to reach all the other peers in the VPN tunnel network 10.125.0.0/16 like we can do with OpenVPN. We tried doing "Mfa": [ "10.125.0.0/16 1-8079/any 8081-10000/any"] but it didn't work.
"Mfa": ["10.125.0.1 1-8079/any 8081-10000/any"] also did not work.

Looks like there's no way to do this?

Except specifying all the peers IP addresses in 10.125.0.0/16 one by one except 10.125.0.1 (since "10.125.0.1 1-8079/any 8081-10000/any" does not work) ?

Thank you very much in anticipation.

NHAS commented 1 year ago

Hi there!

This is totally an edge case I didnt consider when designing and building Wag. My only issue here is that the Mfa rules must always take precedence over Allow rules so people dont accidentally create overly permissive rules.

However, the use case you're describing should still be viable.

Im going to have a little think about how to solve this, as there really isnt an immediately obvious tidy way to do this.

cheegui commented 1 year ago

Thank you NHAS. Yes, this is an edge case. WAG is great. Hope the Wireguard author can work with you to make it more integrated with the GUI client software.

NHAS commented 1 year ago

Okay, so what I am planning on doing to resolve this edge case it to move from using MFA precedence to most specific route match precedence.

e.g if you have an MFA selector for 0.0.0.0/0 but have an allow for 192.168.1.1/32 the /32 will be matched and thus allow you through despite the MFA for all selector.

Little bit worried about how intuitive that is and if it provides enough protection against foot guns.

It may also weaken existing deployments people have. However I dont see any other way of accomplishing this goal, and its something that should exist.

NHAS commented 1 year ago

Thank you NHAS. Yes, this is an edge case. WAG is great. Hope the Wireguard author can work with you to make it more integrated with the GUI client software.

On a side note, this cant be integrated with the GUI client as its effectively all server side.

cheegui commented 1 year ago

Okay, so what I am planning on doing to resolve this edge case it to move from using MFA precedence to most specific route match precedence.

e.g if you have an MFA selector for 0.0.0.0/0 but have an allow for 192.168.1.1/32 the /32 will be matched and thus allow you through despite the MFA for all selector.

Little bit worried about how intuitive that is and if it provides enough protection against foot guns.

It may also weaken existing deployments people have. However I dont see any other way of accomplishing this goal, and its something that should exist.

Thank you NHAS! That's a good idea. To have the more specific rule take precedence. Another method could be the order of the rule definitions? For example, if Allow defined before Mfa, Allow will take precedence. Just a thought. Not an expert here. Yes, existing deployments will have to re-define their rules if necessary when they upgrade their WAG to the version with this fix.

cheegui commented 1 year ago

Thank you NHAS. Yes, this is an edge case. WAG is great. Hope the Wireguard author can work with you to make it more integrated with the GUI client software.

On a side note, this cant be integrated with the GUI client as its effectively all server side.

Thank you for the reply. What I meant is to have the MFA code web page integrated to the Wireguard Windows/macOS/IOS/Andriod GUI client. The GUI client will open up the http://wg_server_tunnel_IP:8080 webpage in the default browser for the user to enter the MFA code after he clicks Activate. The client conf file will contain info on whether MFA is needed and the URL of the MFA website.

Thank you for coming out with this wonderful software. The lack of MFA in Wireguard was a showstopper for using it in enterprises. WAG could change this and WG with WAG could overtake OpenVPN because Wireguard is much faster than OpenVPN.

NHAS commented 1 year ago

Okay, so what I am planning on doing to resolve this edge case it to move from using MFA precedence to most specific route match precedence.

e.g if you have an MFA selector for 0.0.0.0/0 but have an allow for 192.168.1.1/32 the /32 will be matched and thus allow you through despite the MFA for all selector.

Little bit worried about how intuitive that is and if it provides enough protection against foot guns.

It may also weaken existing deployments people have. However I dont see any other way of accomplishing this goal, and its something that should exist.

Thank you NHAS! That's a good idea. To have the more specific rule take precedence. Another method could be the order of the rule definitions? For example, if Allow defined before Mfa, Allow will take precedence. Just a thought. Not an expert here. Yes, existing deployments will have to re-define their rules if necessary when they upgrade their WAG to the version with this fix.

Funny enough the way the longest prefix matching trie structure works there isn't a particularly elegant way of representing this in the code.

As that's the only structure the kernel provides to ebpf programs that can do subnet matching we have to stick to it as well.

NHAS commented 1 year ago

This is now on unstable, after I've knock off some other issues I'll be doing a v6.x.x release to bring this to wag. Thanks for your feedback!

NHAS commented 1 year ago

https://github.com/NHAS/wag/releases/tag/v6.0.1-pre-release

cheegui commented 1 year ago

Thank you NHAS! Will give it a try. Wishing you great success with this project.

cheegui commented 1 year ago

Tested 6.0.1 pre-release. It doesn't seem to work. Tried three config.json's. Doesn't seem to work with Groups if the routes are same across the groups. But when I removed all the groups and left only with *, it also didn't work - although this time, the error wasn't shown in systemctl status but in the syslog. See below.

Thank you very much.

_____-

    "Policies": {
        "*": {
            "Allow": [
                "10.125.0.1/32 8080/any"
           ]
        },
        "group:users": {
            "Allow": [
                "10.125.0.1/32 8080/any"
            ],
            "Mfa": [
                "10.125.0.0/16",
                "192.168.5.0/24",
                "192.168.6.0/24"
            ]
        },
      "group:administrators": {
            "Allow": [
                "10.125.0.0/16",
                "192.168.5.0/24",
                "192.168.6.0/24"
            ]
        }
      }
root@pawg02:/opt/wag# systemctl status wag
? wag.service - Wireguard Manager
     Loaded: loaded (/etc/systemd/system/wag.service; enabled; vendor preset: enabled)
     Active: inactive (dead) since Mon 2023-05-01 11:59:34 UTC; 10s ago
    Process: 3266 ExecStart=/opt/wag/wag start (code=exited, status=0/SUCCESS)
    Process: 3272 ExecStopPost=/opt/wag/wag cleanup (code=exited, status=0/SUCCESS)
   Main PID: 3266 (code=exited, status=0/SUCCESS)
        CPU: 91ms
May 01 11:59:34 pawg02 wag[3266]:   -config string
May 01 11:59:34 pawg02 wag[3266]:             Configuration file location (default "./config.json")
May 01 11:59:34 pawg02 wag[3266]:   -noiptables
May 01 11:59:34 pawg02 wag[3266]:             Do not add iptables rules
May 01 11:59:34 pawg02 wag[3272]: Error:  policies rules were invalid: route 10.125.0.1/32 already defined
May 01 11:59:34 pawg02 wag[3272]: Usage of cleanup:
May 01 11:59:34 pawg02 wag[3272]:   Attempt to clear all iptables rules that wag creates, and bring down wireguard interface
May 01 11:59:34 pawg02 wag[3272]:   -config string
May 01 11:59:34 pawg02 wag[3272]:             Configuration file location (default "./config.json")
May 01 11:59:34 pawg02 systemd[1]: wag.service: Deactivated successfully.
root@pawg02:/opt/wag#

====== __-

    "Policies": {
        "*": {
            "Allow": [
                "10.125.0.1/32 8080/any"
           ]
        },
        "group:users": {
            "Mfa": [
                "10.125.0.0/16",
                "192.168.5.0/24",
                "192.168.6.0/24"
            ],
            "Allow": [
                "10.125.0.254/32 8080/any"
            ]
        },
      "group:administrators": {
            "Allow": [
                "10.125.0.0/16",
                "192.168.5.0/24",
                "192.168.6.0/24"
            ]
        }
      }
root@pawg02:/opt/wag# systemctl status wag
? wag.service - Wireguard Manager
     Loaded: loaded (/etc/systemd/system/wag.service; enabled; vendor preset: enabled)
     Active: inactive (dead) since Mon 2023-05-01 12:03:04 UTC; 8s ago
    Process: 3291 ExecStart=/opt/wag/wag start (code=exited, status=0/SUCCESS)
    Process: 3297 ExecStopPost=/opt/wag/wag cleanup (code=exited, status=0/SUCCESS)
   Main PID: 3291 (code=exited, status=0/SUCCESS)
        CPU: 100ms
May 01 12:03:04 pawg02 wag[3291]:   -config string
May 01 12:03:04 pawg02 wag[3291]:             Configuration file location (default "./config.json")
May 01 12:03:04 pawg02 wag[3291]:   -noiptables
May 01 12:03:04 pawg02 wag[3291]:             Do not add iptables rules
May 01 12:03:04 pawg02 wag[3297]: Error:  policies rules were invalid: route 10.125.0.0/16 already defined
May 01 12:03:04 pawg02 wag[3297]: Usage of cleanup:
May 01 12:03:04 pawg02 wag[3297]:   Attempt to clear all iptables rules that wag creates, and bring down wireguard interface
May 01 12:03:04 pawg02 wag[3297]:   -config string
May 01 12:03:04 pawg02 wag[3297]:             Configuration file location (default "./config.json")
May 01 12:03:04 pawg02 systemd[1]: wag.service: Deactivated successfully.
root@pawg02:/opt/wag#

======================


    "Policies": {
        "*": {
            "Mfa": [
                "10.125.0.0/16",
                "192.168.5.0/24",
                "192.168.6.0/24"
            ],
            "Allow": [
                "10.125.0.1/32"
           ]
        }
       }
     }
root@pawg02:/opt/wag# systemctl start wag
root@pawg02:/opt/wag# systemctl status wag
? wag.service - Wireguard Manager
     Loaded: loaded (/etc/systemd/system/wag.service; enabled; vendor preset: enabled)
     Active: activating (auto-restart) (Result: exit-code) since Mon 2023-05-01 12:04:51 UTC; 2s ago
    Process: 3365 ExecStart=/opt/wag/wag start (code=exited, status=1/FAILURE)
    Process: 3397 ExecStopPost=/opt/wag/wag cleanup (code=exited, status=1/FAILURE)
   Main PID: 3365 (code=exited, status=1/FAILURE)
        CPU: 255ms
root@pawg02:/opt/wag#

root@pawg02:/opt/wag# tail -n 40 /var/log/syslog
May  1 12:05:23 pawg02 systemd[1]: Started Wireguard Manager.
May  1 12:05:23 pawg02 systemd-networkd[840]: wgpa01: Link UP
May  1 12:05:23 pawg02 systemd-networkd[840]: wgpa01: Gained carrier
May  1 12:05:23 pawg02 networkd-dispatcher[873]: WARNING:Unknown index 47 seen, reloading interface list
May  1 12:05:23 pawg02 systemd-udevd[3531]: Using default interface naming scheme 'v249'.
May  1 12:05:23 pawg02 wag[3523]: 2023/05/01 12:05:23 Removing Firewall rules...
May  1 12:05:23 pawg02 systemd-networkd[840]: wgpa01: Link DOWN
May  1 12:05:23 pawg02 systemd-networkd[840]: wgpa01: Lost carrier
May  1 12:05:24 pawg02 wag[3523]: 2023/05/01 12:05:24 unable to start router: xdp setup add user: route 10.125.0.1/32 already defined
May  1 12:05:24 pawg02 systemd[1]: wag.service: Main process exited, code=exited, status=1/FAILURE
May  1 12:05:24 pawg02 wag[3556]: 2023/05/01 12:05:24 Cleaning up
May  1 12:05:24 pawg02 wag[3556]: 2023/05/01 12:05:24 Removing Firewall rules...
May  1 12:05:24 pawg02 wag[3556]: 2023/05/01 12:05:24 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t filter -D FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT --wait]: exit status 1: iptables: Bad rule (does a matching rule exist in that chain?).
May  1 12:05:24 pawg02 wag[3556]: 2023/05/01 12:05:24 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t filter -D FORWARD -i wgpa01 -j ACCEPT --wait]: exit status 1: iptables: Bad rule (does a matching rule exist in that chain?).
May  1 12:05:24 pawg02 wag[3556]: 2023/05/01 12:05:24 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t filter -D FORWARD -o wgpa01 -j ACCEPT --wait]: exit status 1: iptables: Bad rule (does a matching rule exist in that chain?).
May  1 12:05:24 pawg02 wag[3556]: 2023/05/01 12:05:24 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t nat -D POSTROUTING -s 10.125.0.0/16 -j MASQUERADE --wait]: exit status 1: iptables: Bad rule (does a matching rule exist in that chain?).
May  1 12:05:24 pawg02 wag[3556]: 2023/05/01 12:05:24 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t filter -D INPUT -m tcp -p tcp -i wgpa01 --dport 8080 -j ACCEPT --wait]: exit status 1: iptables: Bad rule (does a matching rule exist in that chain?).
May  1 12:05:24 pawg02 wag[3556]: 2023/05/01 12:05:24 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t filter -D INPUT -p icmp --icmp-type 8 -i wgpa01 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT --wait]: exit status 1: iptables: Bad rule (does a matching rule exist in that chain?).
May  1 12:05:24 pawg02 wag[3556]: 2023/05/01 12:05:24 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t filter -D INPUT -i wgpa01 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT --wait]: exit status 1: iptables: Bad rule (does a matching rule exist in that chain?).
May  1 12:05:24 pawg02 wag[3556]: 2023/05/01 12:05:24 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t filter -D INPUT -i wgpa01 -j DROP --wait]: exit status 1: iptables: Bad rule (does a matching rule exist in that chain?).
May  1 12:05:24 pawg02 wag[3556]: 2023/05/01 12:05:24 Unable to remove wireguard device, delete failed:  failed to execute message: netlink receive: no such device
May  1 12:05:24 pawg02 wag[3556]: 2023/05/01 12:05:24 remove /tmp/wag.sock: no such file or directory
May  1 12:05:24 pawg02 wag[3556]: 2023/05/01 12:05:24 exit status 1
May  1 12:05:24 pawg02 systemd[1]: wag.service: Control process exited, code=exited, status=1/FAILURE
May  1 12:05:24 pawg02 systemd[1]: wag.service: Failed with result 'exit-code'.
root@pawg02:/opt/wag#


NHAS commented 1 year ago

Hm. I see the issue, I've added a check to make sure people can't add duplicate routes (as they get overwritten so effectively only the last route is ever used for a specific route)

However I've implemented it poorly and it doesn't take into account some basic side cases.

That last configuration file should be working. Could you give me the output of journalctl -ex -u wag instead of syslog.

NHAS commented 1 year ago

Actually that last config could be because the server automatically adds an allow route for itself.

NHAS commented 1 year ago

I've updated the release to remove duplicate route detection. I'll add it back in later when I have half a mind to design it right.

https://github.com/NHAS/wag/releases/tag/v6.1.1-pre-release

cheegui commented 1 year ago

Hm. I see the issue, I've added a check to make sure people can't add duplicate routes (as they get overwritten so effectively only the last route is ever used for a specific route)

However I've implemented it poorly and it doesn't take into account some basic side cases.

That last configuration file should be working. Could you give me the output of journalctl -ex -u wag instead of syslog.

root@pawg02:/opt/wag# systemctl start wag
root@pawg02:/opt/wag# systemctl status wag
● wag.service - Wireguard Manager
     Loaded: loaded (/etc/systemd/system/wag.service; enabled; vendor preset: enabled)
     Active: activating (auto-restart) (Result: exit-code) since Tue 2023-05-02 02:07:27 UTC; 5s ago
    Process: 5164 ExecStart=/opt/wag/wag start (code=exited, status=1/FAILURE)
    Process: 5199 ExecStopPost=/opt/wag/wag cleanup (code=exited, status=1/FAILURE)
   Main PID: 5164 (code=exited, status=1/FAILURE)
        CPU: 261ms
root@pawg02:/opt/wag# journalctl -ex -u wag
░░ Defined-By: systemd
░░ Support: http://www.ubuntu.com/support
░░
░░ An ExecStart= process belonging to unit wag.service has exited.
░░
░░ The process' exit code is 'exited' and its exit status is 1.
May 02 02:08:00 pawg02 wag[5355]: 2023/05/02 02:08:00 Cleaning up
May 02 02:08:00 pawg02 wag[5355]: 2023/05/02 02:08:00 Removing Firewall rules...
May 02 02:08:00 pawg02 wag[5355]: 2023/05/02 02:08:00 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t filter -D FO>
May 02 02:08:00 pawg02 wag[5355]: 2023/05/02 02:08:00 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t filter -D FO>
May 02 02:08:00 pawg02 wag[5355]: 2023/05/02 02:08:00 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t filter -D FO>
May 02 02:08:00 pawg02 wag[5355]: 2023/05/02 02:08:00 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t nat -D POSTR>
May 02 02:08:00 pawg02 wag[5355]: 2023/05/02 02:08:00 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t filter -D IN>
May 02 02:08:00 pawg02 wag[5355]: 2023/05/02 02:08:00 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t filter -D IN>
May 02 02:08:00 pawg02 wag[5355]: 2023/05/02 02:08:00 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t filter -D IN>
May 02 02:08:00 pawg02 wag[5355]: 2023/05/02 02:08:00 Unable to clean up firewall rules:  running [/usr/sbin/iptables -t filter -D IN>
May 02 02:08:00 pawg02 wag[5355]: 2023/05/02 02:08:00 Unable to remove wireguard device, delete failed:  failed to execute message: n>
May 02 02:08:00 pawg02 wag[5355]: 2023/05/02 02:08:00 remove /tmp/wag.sock: no such file or directory
May 02 02:08:00 pawg02 wag[5355]: 2023/05/02 02:08:00 exit status 1
May 02 02:08:00 pawg02 systemd[1]: wag.service: Control process exited, code=exited, status=1/FAILURE
░░ Subject: Unit process exited
░░ Defined-By: systemd
░░ Support: http://www.ubuntu.com/support
░░
░░ An ExecStopPost= process belonging to unit wag.service has exited.
░░
░░ The process' exit code is 'exited' and its exit status is 1.
May 02 02:08:00 pawg02 systemd[1]: wag.service: Failed with result 'exit-code'.
░░ Subject: Unit failed
░░ Defined-By: systemd
░░ Support: http://www.ubuntu.com/support
░░
░░ The unit wag.service has entered the 'failed' state with result 'exit-code'.
lines 2763-2795/2795 (END)
cheegui commented 1 year ago

Actually that last config could be because the server automatically adds an allow route for itself.

Yes, tested 6.0.1 and it works when the ""Allow": ["10.125.0.1/32"]" is removed. So the server IP is automatically allowed and on all ports? What if we only want to allow 8080/any? Thank you very much.

NHAS commented 1 year ago

For the moment. Just ignore 6.0.1, try the new release, I've removed the restriction.

cheegui commented 1 year ago

I've updated the release to remove duplicate route detection. I'll add it back in later when I have half a mind to design it right.

https://github.com/NHAS/wag/releases/tag/v6.1.1-pre-release

6.1.1 does not work. Not able to access the MFA 10.125.0.0/16 network like before. 6.0.1 is able to access the MFA 10.125.0.0/16 network when the 10.125.0.1 (server) route is removed. 6.1.1 started successfully with duplicate routes between groups.

Tested config below with 6.1.1. Cannot access 10.125.0.0/16. Thank you.

        "Policies": {
            "*": {
                "Allow": [
                    "10.125.0.1/32 8080/any"
               ]
            },
            "group:users": {
                "Allow": [
                    "10.125.0.1/32 8080/any"
                ],
                "Mfa": [
                    "10.125.0.0/16",
                    "192.168.5.0/24",
                    "192.168.6.0/24"
                ]
            },
          "group:administrators": {
                "Allow": [
                    "10.125.0.0/16",
                    "192.168.5.0/24",
                    "192.168.6.0/24"
                ]
            }
          }
        }
NHAS commented 1 year ago

Im going to need more information about your user groups. As if your user is just in users then you'd need to MFA before you could hit 10.125.0.0/16 which might be falsely confusing you.

NHAS commented 1 year ago

I can confirm the following works for me:

"Policies": {
            "*": {
                "Mfa": [
                    "142.250.67.14/32",
                    "1.1.0.0/16"
                ]
            },
            "group:toast": {
               "Allow": [
                  "1.1.1.1"
                ],
                "Mfa": [
                    "4.4.4.4 123/tcp",
                    "5.5.5.5"
                ]
            }
        }
cheegui commented 1 year ago
            "group:users": {
                "Allow": [
                    "10.125.0.1/32 8080/any"
                ],
                "Mfa": [
                    "10.125.0.0/16",
                    "192.168.5.0/24",
                    "192.168.6.0/24"
                ]
            },

Im going to need more information about your user groups. As if your user is just in users then you'd need to MFA before you could hit 10.125.0.0/16 which might be falsely confusing you.

6.0.1 works in that we can access the MFA 10.125.0.0/16 (the VPN tunnel network) after going to the server ip:8080 to enter the MFA code (provided we remove the allow server IP - since you mentioned it is automatically allowed in 6.0.1).

In 6.1.1, we were able to go to 10.125.0.1:8080 to enter the MFA code. But after that, we can only go to the MFA 192.168.5.0/24 and 192.168.6.0/24 but not the MFA VPN tunnel network 10.125.0.0/16. Note I only have one client and so I tested ping 10.125.0.1 and it didn't work in 6.1.1 (works in 6.0.1 - can also ssh 10.125.0.1 in 6.0.1). It can of course ping itself 10.125.0.3 (the client VPN tunnel interface IP).

            "group:users": {
                "Allow": [
                    "10.125.0.1/32 8080/any"
                ],
                "Mfa": [
                    "10.125.0.0/16",
                    "192.168.5.0/24",
                    "192.168.6.0/24"
                ]
            },
NHAS commented 1 year ago

Sure you may have one user, but I need to know what group that user is in. I know you've said that 6.0.1 works where 6.1.1 doesnt. But the only difference between those two versions is that I've removed the configuration restriction on having the same routes, its effectively the same otherwise.

Hence Im struggling to understand how this could be an issue.

cheegui commented 1 year ago

I can confirm the following works for me:

"Policies": {
            "*": {
                "Mfa": [
                    "142.250.67.14/32",
                    "1.1.0.0/16"
                ]
            },
            "group:toast": {
               "Allow": [
                  "1.1.1.1"
                ],
                "Mfa": [
                    "4.4.4.4 123/tcp",
                    "5.5.5.5"
                ]
            }
        }

The difference with between our configs is we don't have the "Mfa VPN tunnel network" in the "*" group like yours ( "Mfa": ["142.250.67.14/32","1.1.0.0/16"]). Our ""Mfa": [ "10.125.0.0/16"," is in the group.users.

cheegui commented 1 year ago

Sure you may have one user, but I need to know what group that user is in. I know you've said that 6.0.1 works where 6.1.1 doesnt. But the only difference between those two versions is that I've removed the configuration restriction on having the same routes, its effectively the same otherwise.

Hence Im struggling to understand how this could be an issue.

The user is in the "group:users" group. Thank you.

NHAS commented 1 year ago

we can only go to the MFA 192.168.5.0/24 and 192.168.6.0/24 but not the MFA VPN tunnel network 10.125.0.0/16.

Im not really sure what you mean by this. If you can hit the server address, then this is working, you said you only have one device in the VPN network so you're not going to be able to hit anything else? This may also be an iptables issue?

Can you give me the command you're using, what you're trying to ping, etc?

NHAS commented 1 year ago

Can you give me your whole configuration file (minus the private key) I'll just run this straight and see if I can replicate.

cheegui commented 1 year ago

This may also be an iptables issue?

Can you give me the com

It is not Iptables issue if we can hit the MFA 10.125.0.0/16 (VPN tunnel) network with 6.0.1. The problem only exists in 6.1.1.

NHAS commented 1 year ago

Have you reverted to 6.0.1 to try it?

cheegui commented 1 year ago

Can you give me your whole configuration file (minus the private key) I'll just run this straight and see if I can replicate.

{
    "Lockout": 5,
    "HelpMail": "it@example.com",
    "MaxSessionLifetimeMinutes": 7200,
    "SessionInactivityTimeoutMinutes": 1440,
    "ExternalAddress": "pawg.example.com",
    "DatabaseLocation": "devices.db",
    "Socket": "/tmp/wag.sock",
    "Webserver": {
        "Public": {
            "ListenAddress": "192.168.5.231:8081"
        },
        "Tunnel": {
            "Port": "8080"
        }
    },
    "ManagementUI": {
        "ListenAddress": "192.168.5.231:4433",
        "Enabled": true
    },
    "Authenticators": {
        "Issuer": "fx_wg_wag",
        "DefaultMethod": "totp",
        "Methods": [
            "totp"
        ]
    },
    "Wireguard": {
        "DevName": "wgpa01",
        "ListenPort": 51820,
        "PrivateKey": "Private_key_removed",
        "Address": "10.125.0.1/16",
        "MTU": 1420,
        "PersistentKeepAlive": 25,
        "DNS": [
            "192.168.5.1/32"
        ]
    },
    "Acls": {
        "Groups": {
            "group:users": [
                "user02",
                "user03",
                "user04",
                "user05"
            ],
            "group:administrators": [
                "user01",
                "user10"
            ]
        },
        "Policies": {
            "*": {
                "Allow": [
                    "10.125.0.1/32 8080/any"
               ]
            },
            "group:users": {
                "Allow": [
                    "10.125.0.1/32 8080/any"
                ],
                "Mfa": [
                    "10.125.0.0/16",
                    "192.168.5.0/24",
                    "192.168.6.0/24"
                ]
            },
          "group:administrators": {
                "Allow": [
                    "10.125.0.0/16",
                    "192.168.5.0/24",
                    "192.168.6.0/24"
                ]
            }
          }
        }
}
NHAS commented 1 year ago

Sweet thanks. Please give me what you're trying to hit in the VPN network as well (i.e ping x.x.x.x)

cheegui commented 1 year ago

Sweet thanks. Please give me what you're trying to hit in the VPN network as well (i.e ping x.x.x.x)

ping 10.125.0.1 (the wag server ip)

cheegui commented 1 year ago

Have you reverted to 6.0.1 to try it?

Reverted to 6.0.1 and it worked. We were able to go to 10.125.0.1:8080 to enter the MFA code and then we were able to ping and ssh 10.125.0.1. But the config we use for 6.0.1 is different. No policy for groups (maybe that's the problem?).

       "Policies": {
            "*": {
                "Mfa": [
                    "10.125.0.0/16",
                    "192.168.5.0/24",
                    "192.168.6.0/24"
                ],
                "Allow": [
                    "10.125.0.100/32"
               ]
            }
           }
         }
NHAS commented 1 year ago

Yeah cool I see what the issue is now.

You have defined this "10.125.0.1/32 8080/any" in your 6.1.1 config this says "only allow 8080/any to the VPN server", you are using ping, ping is ICMP which doesnt operate on port 8080, thus wag is blocking you.

The reason 6.0.1 worked is because it was forcing you not to have duplicate rules, so the default any/any rule was added for the server and you couldnt overwrite it.

If you change your rule to be "10.125.0.1/32 8080/any icmp" it should work

cheegui commented 1 year ago

Yeah cool I see what the issue is now.

You have defined this "10.125.0.1/32 8080/any" in your 6.1.1 config this says "only allow 8080/any to the VPN server", you are using ping, ping is ICMP which doesnt operate on port 8080, thus wag is blocking you.

The reason 6.0.1 worked is because it was forcing you not to have duplicate rules, so the default any/any rule was added for the server and you couldnt overwrite it.

If you change your rule to be "10.125.0.1/32 8080/any icmp" it should work

Still not working.

        "Policies": {
            "*": {
                "Allow": [
                    "10.125.0.1/32 8080/any icmp"
               ]
            },
            "group:users": {
                "Allow": [
                    "10.125.0.1/32 8080/any icmp"
                ],
                "Mfa": [
                    "10.125.0.0/16",
                    "192.168.5.0/24",
                    "192.168.6.0/24"
                ]
            },
          "group:administrators": {
                "Allow": [
                    "10.125.0.0/16",
                    "192.168.5.0/24",
                    "192.168.6.0/24"
                ]
            }
          }
NHAS commented 1 year ago

Sweet, give me the output of ./wag firewall -list and then try changing it to just 10.125.0.1

cheegui commented 1 year ago

Sweet, give me the output of ./wag firewall -list and then try changing it to just 10.125.0.1

Changed from 10.125.0.1/32 to 10.125.01 Still not working.

root@pawg02:/opt/wag# ./wag firewall -list
{"user01":{"MFA":null,"Public":["10.125.0.1/32 policy [public 8080/any public any/icmp]","10.125.0.0/16 policy [public any/any]","192.168.5.1/32 policy [public any/any]","192.168.5.0/24 policy [public any/any]","192.168.6.0/24 policy [public any/any]"],"Devices":[{"LastPacketTimestamp":0,"Expiry":0,"IP":"10.125.0.2","Authorized":false}],"AccountLocked":0},"user02":{"MFA":["10.125.0.1/32 policy [public 8080/any public any/icmp]","10.125.0.0/16 policy [mfa any/any]","192.168.5.1/32 policy [public any/any]","192.168.5.0/24 policy [mfa any/any]","192.168.6.0/24 policy [mfa any/any]"],"Public":null,"Devices":[{"LastPacketTimestamp":0,"Expiry":0,"IP":"10.125.0.3","Authorized":false}],"AccountLocked":0},"user03":{"MFA":["10.125.0.1/32 policy [public 8080/any public any/icmp]","10.125.0.0/16 policy [mfa any/any]","192.168.5.1/32 policy [public any/any]","192.168.5.0/24 policy [mfa any/any]","192.168.6.0/24 policy [mfa any/any]"],"Public":null,"Devices":[{"LastPacketTimestamp":58079082501874,"Expiry":490047542429407,"IP":"10.125.0.4","Authorized":true}],"AccountLocked":0}}
root@pawg02:/opt/wag#
NHAS commented 1 year ago

Sorry, when I mean changing it to 10.125.0.1 I mean remove all other restrictions and just leave it as "10.125.0.1"

Regardless, I can replicate. Effectively when the icmp directive is at the end like this 10.123.5.1 8081/any icmp it doesnt work, if it is at the start, it works perfectly fine.

Obviously, that little bit is a bug. Ironically not what you're getting hit by, but still a bug

cheegui commented 1 year ago

Sorry, when I mean changing it to 10.125.0.1 I mean remove all other restrictions and just leave it as "10.125.0.1"

Regardless, I can replicate. Effectively when the icmp directive is at the end like this 10.123.5.1 8081/any icmp it doesnt work, if it is at the start, it works perfectly fine.

Obviously, that little bit is a bug. Ironically not what you're getting hit by, but still a bug

Works now! Thank you very much.

NHAS commented 1 year ago

Honestly. Thank you. You've just helped me find a really corner case bug!!

Im going to do a little release in a second in order to make the 10.123.5.1 8081/any icmp rule declaration work properly.

NHAS commented 1 year ago

https://github.com/NHAS/wag/releases/tag/v6.1.2-pre-release

cheegui commented 1 year ago

https://github.com/NHAS/wag/releases/tag/v6.1.2-pre-release

Tested working.
However, the method of having the more specific rule take precedence may have its own issue. In 6.0.1 after removing the All WAG Server IP rule, we could ping and SSH 10.125.0.1 after entering the MFA code in http://10.125.0.01:8080. In 6.1.2, we could only ping but not SSH - since the " "Allow": ["10.125.0.1/32 8080/any icmp" ]" rule takes precedence over the " "Mfa": ["10.125.0.0/16"," rule. So Mfa 10.125.0.0/16 does not include 10.125.0.1 at all? At the moment, we don't have any other devices in the 10.125.0.0/16 network to test and so cannot test if SSH to another device in 10.125.0.0/16 (except 10.125.0.1) works. Guess there is no way to do "Allow": ["10.125.0.1/32 8080/any icmp" and then ""Mfa":[ "10.125.0.1/32 1-1024/any","10.125.0.0/16"," to allow access to other ports on 10.125.0.1 after MFA. The idea is to have the Allow of 10.125.0.1/32 8080/any allow going to the MFA code page, and then after entering the MFA, the user should have access to everything in 10.125.0.0/16 including 10.125.0.1 - like in OpenVPN. If this is not possible, not a big issue. Thank you very much for working on this.

Tested the config below but still cannot SSH 10.125.0.1. "Policies": { "*": { "Allow": [ "10.125.0.1/32 8080/any icmp" ] }, "group:users": { "Allow": [ "10.125.0.1/32 8080/any icmp" ], "Mfa": [ "10.125.0.1/32 22/tcp", "10.125.0.0/16", "192.168.5.0/24", "192.168.6.0/24" ] }, "group:administrators": { "Allow": [ "10.125.0.0/16", "192.168.5.0/24", "192.168.6.0/24" ] } }

NHAS commented 1 year ago

Ahhh I totally get what you're saying here. You want users to be able to hit some ports on a host without Mfa and some other set of ports when they have mfa'd

That's a good point and not something I've designed wag to do. I'd have to have a think about it and whether it's feasible.

To cover all my bases, you can always add 22/tcp to your server rule to enable ssh. But obvious this would allow clients to hit ssh even when they hadn't authorised with Mfa.

Good shout! I'll have a think. But no promises for now.

As for the rest of the 10.125.0.0/16 network, it should be able to hit all services when mfa'd there.

cheegui commented 1 year ago

Thank you so much NHAS! As you correctly pointed out, this is really an edge case. But it is good to have it because it is how Openvpn works (peers can access each other via VPN tunnel IP). We are currently using Openvpn with MFA on PFSense firewall.

NHAS commented 1 year ago

I definitely agree that the option to do this should be here. I just want to have it be secure by default.

i.e you have to configure it specifically to allow clients to hit each others services

This just stops easy lateral spread in the event a single device gets compromised.

As for the allowed ports changing on Mfa I think that's a great idea but may not be feasible with the implementation as it is

Regardless I fixed a bug from this discussion so thanks for your contribution!

cheegui commented 1 year ago

I definitely agree that the option to do this should be here. I just want to have it be secure by default.

i.e you have to configure it specifically to allow clients to hit each others services

This just stops easy lateral spread in the event a single device gets compromised.

As for the allowed ports changing on Mfa I think that's a great idea but may not be feasible with the implementation as it is

Regardless I fixed a bug from this discussion so thanks for your contribution!

Actually as I don't have any other client, I don't know if the MFA 10.125.0.0/16 works. If it works for all devices in 10.125.0.0/16 except 10.125.0.1/32 (because the more specific Allow rule takes precedence), then the current 6.1.2 version may be good enough. After all, the purpose is to be able to access the other peers and not the server. Will try to set up another client and then test it out. Thank you.

NHAS commented 1 year ago

Sweet, I've added what you wanted port wise.

https://github.com/NHAS/wag/releases/tag/v6.2.0-pre-release

See the release notes here (more docs on the unstable branch)

This will mean that for the server address specifically that you cant remove the allow all any/any rule for the server. However as MFA polices take preference you can block out individual ports.

Effectively this means you can have MFA and Allow rules for the same route, and do fun stuff like:

 "*": {
            "Mfa": [
                  "10.0.0.0/16",
                  "10.0.1.1/32 22/tcp",
            ]
  },
 "group:users": {
            "Allow": [
                  "10.0.1.1/32 443/tcp",
            ]
 }

Where a user in the group:users will always be able to access 10.0.1.1/32 443/tcpand when they authorise they'll e able to see port 22/tcp as well.

If you want to be helpful I'd love for you to give this a really hard test and just try and abuse it as much as possible. Then I'll probably do a release.

cheegui commented 1 year ago

Thank you NHAS. I'm travelling now and won't be able to test this until maybe next month.

NHAS commented 1 year ago

Dang alright! Safe and happy travels

cheegui commented 1 year ago

Hi NHAS

Tested 6.2.0 and it works! Was able to ssh to the WG server at its VPN IP address after entering MFA code. Thank you so much!

An aside: I'm in a place where the Internet is severely censored and surveilled. Fearing that they may block 51820, I tried running Wireguard under port 443 (instead of 51820) but it didn't work. Checked that port 443 wasn't used on the WG server. Is there any reason why port 443 won't work for Wireguard?

    "Wireguard": {
        "DevName": "wireguard1",
        "ListenPort": 443,

Below is my config.json (tested a user in the users group) :

  "Policies": {
            "*": {
                "Allow": [
                    "10.125.0.1/32 8080/any icmp"
               ]
            },
            "group:users": {
                "Mfa": [
                    "10.125.0.1/32 22/tcp",
                    "10.125.0.0/16",
                    "192.168.5.0/24",
                    "192.168.6.0/24"
                ]
            },
          "group:administrators": {
                "Allow": [
                    "10.125.0.0/16",
                    "192.168.5.0/24",
                    "192.168.6.0/24"
                ]
            }
NHAS commented 1 year ago

Glad to hear that all works for you. Please test it a bunch and then I'll do a release.

In terms of this: "I'm in a place where the Internet is severely censored and surveilled"

Its probably best to warn you that wireguard as a protocol is very easy to pick up with packet inspection due to some very identifiable message characteristics (as example https://github.com/net4people/bbs/issues/88). So I would not recommend using wireguard alone if you are in a hostile nation, or other dangerous situation.

As for the issue you've described. There is no immediate reason that wireguard shouldnt be able to listen on port 443, can you give me more information?

What port is your webserver listening on? Are there any wag logs I can look at?