Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

T4930: Allow WireGuard peers via DNS hostname #4200

Open
wants to merge 10 commits into
base: current
Choose a base branch
from

Conversation

sskaje
Copy link
Contributor

@sskaje sskaje commented Nov 20, 2024

Change Summary

T4930: Allow WireGuard peers via DNS hostname + new script resetting peer
T4930: Ensure peer is created even if dns not working
T4930: limit wg retry times by using environment variable
T4930: make wg dns retry configurable through interfaces wireguard wgX max-dns-retry

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes)
  • Migration from an old Vyatta component to vyos-1x, please link to related PR inside obsoleted component
  • Other (please describe):

Related Task(s)

https://vyos.dev/T4930

Related PR(s)

Component(s) name

wireguard

Proposed changes

  1. Support wireguard endpoint using domain as peer address, make sure wg retries for dns resolution no more than 5 times;
  2. Introduce an op mode command reset wireguard, if user want to use wg set to force wireguard redo dns resolution;
  3. Detail changes like splitting Wireguard peer creation into peer creation + endpoint setup, with exception (need help on correct exception/log handling, not found in docs.vyos.io)

How to test

config mode

vyos@vyos# set interfaces wireguard wg0 peer wg0-xxx address t2.vm.xxx.xxx
[edit]
vyos@vyos# commit
[edit]
vyos@vyos#

op mode

# reset all peers on wg0
vyos@vyos:~$ reset wireguard interface wg0
Resetting wg0 peer YYYY= endpoint to t1.vm.xxx.xxx:ppppp ... done
Resetting wg0 peer XXXX= endpoint to t2.vm.xxxx.xxx:ppppp ... done

# reset single peer on wg0
vyos@vyos:~$ reset wireguard interface wg0  peer wg0-xxx
Resetting wg0 peer XXXX= endpoint to t2.vm.xxxx.xxx:ppppp ... done

vyos without working dns

I've provided screenshots in task's comments.

configure max dns resolution retry times

vyos@vyos# set interfaces wireguard wg0
Possible completions:
+  address              IP address
   description          Description
   disable              Administratively disable interface
   domain-name          Endpoint Domain Name
   fwmark               A 32-bit fwmark value set on all outgoing packets (default: 0)
 > ip                   IPv4 routing parameters
 > ipv6                 IPv6 routing parameters
   max-dns-retry        Max retry when DNS resolves failed. (default: 3)
 > mirror               Mirror ingress/egress packets
   mtu                  Maximum Transmission Unit (MTU) (default: 1420)
+> peer                 peer alias
   per-client-thread    Process traffic from each client in a dedicated thread
   port                 Port number used by connection
   private-key          Base64 encoded private key
   redirect             Redirect incoming packet to destination
   vrf                  VRF instance name


[edit]
vyos@vyos# set interfaces wireguard wg0 max-dns-retry
Possible completions:
   <1-15>               Max retry times



[edit]
vyos@vyos# set interfaces wireguard wg0 max-dns-retry 3
[edit]
vyos@vyos#

Smoketest result

root@vyos:/home/vyos# python3 /usr/libexec/vyos/tests/smoke/cli/test_interfaces_wireguard.py
test_01_wireguard_peer (__main__.WireGuardInterfaceTest.test_01_wireguard_peer) ... ok
test_02_wireguard_add_remove_peer (__main__.WireGuardInterfaceTest.test_02_wireguard_add_remove_peer) ... ok
test_03_wireguard_same_public_key (__main__.WireGuardInterfaceTest.test_03_wireguard_same_public_key) ... ok
test_04_wireguard_threaded (__main__.WireGuardInterfaceTest.test_04_wireguard_threaded) ... ok
test_05_wireguard_peer_pubkey_change (__main__.WireGuardInterfaceTest.test_05_wireguard_peer_pubkey_change) ... ok

----------------------------------------------------------------------
Ran 5 tests in 52.648s

OK
root@vyos:/home/vyos#

Checklist:

  • I have read the CONTRIBUTING document
  • I have linked this PR to one or more Phabricator Task(s)
  • I have run the components SMOKETESTS if applicable
  • My commit headlines contain a valid Task id
  • My change requires a change to the documentation
  • I have updated the documentation accordingly

Copy link

github-actions bot commented Nov 20, 2024

👍
No issues in PR Title / Commit Title

@sever-sever
Copy link
Member

sever-sever commented Nov 20, 2024

Build package fails (based on CI)

PYTHONPATH=python/ python3 -m "nose" --with-xunit src --with-coverage --cover-erase --cover-xml --cover-package src/conf_mode,src/op_mode,src/completion,src/helpers,src/validators,src/tests --verbose
*** Error compiling './python/vyos/ifconfig/wireguard.py'...
  File "./python/vyos/ifconfig/wireguard.py", line 179
    f'Resetting {self.config['ifname']} peer {public_key} endpoint to {address}:{port} ... ',
                              ^^^^^^
SyntaxError: f-string: unmatched '['

make[2]: *** [Makefile:89: test] Error 1
make[2]: Leaving directory '/__w/vyos-1x/vyos-1x/packages/vyos-1x'
make[1]: *** [debian/rules:31: override_dh_auto_build] Error 2
make[1]: Leaving directory '/__w/vyos-1x/vyos-1x/packages/vyos-1x'
make: *** [debian/rules:21: build] Error 2
dpkg-buildpackage: error: debian/rules build subprocess returned exit status 2
Error: Process completed with exit code

@sskaje
Copy link
Contributor Author

sskaje commented Nov 20, 2024

Build package fails (based on CI)

PYTHONPATH=python/ python3 -m "nose" --with-xunit src --with-coverage --cover-erase --cover-xml --cover-package src/conf_mode,src/op_mode,src/completion,src/helpers,src/validators,src/tests --verbose
*** Error compiling './python/vyos/ifconfig/wireguard.py'...
  File "./python/vyos/ifconfig/wireguard.py", line 179
    f'Resetting {self.config['ifname']} peer {public_key} endpoint to {address}:{port} ... ',
                              ^^^^^^
SyntaxError: f-string: unmatched '['

make[2]: *** [Makefile:89: test] Error 1
make[2]: Leaving directory '/__w/vyos-1x/vyos-1x/packages/vyos-1x'
make[1]: *** [debian/rules:31: override_dh_auto_build] Error 2
make[1]: Leaving directory '/__w/vyos-1x/vyos-1x/packages/vyos-1x'
make: *** [debian/rules:21: build] Error 2
dpkg-buildpackage: error: debian/rules build subprocess returned exit status 2
Error: Process completed with exit code

Updated.

My IDE was set python3.12, that syntax is acceptable in 3.12 but not in 3.11 XD

Copy link
Member

@sarthurdev sarthurdev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the WG_ENDPOINT_RESOLUTION_RETRIES var block execution while waiting to resolve?

op-mode-definitions/reset-wireguard.xml.in Outdated Show resolved Hide resolved
op-mode-definitions/reset-wireguard.xml.in Outdated Show resolved Hide resolved
@sskaje
Copy link
Contributor Author

sskaje commented Nov 20, 2024

Does the WG_ENDPOINT_RESOLUTION_RETRIES var block execution while waiting to resolve?

Sorry, I don't understand your question.

WG_ENDPOINT_RESOLUTION_RETRIES is an environment variable use in wg command, source here:

wg reads env:
https://git.zx2c4.com/wireguard-tools/tree/src/config.c#n180

wg assigns as local variable:
https://git.zx2c4.com/wireguard-tools/tree/src/config.c#n199

wg loops and retries:
https://git.zx2c4.com/wireguard-tools/tree/src/config.c#n259

By default, wg retries 15 times, delay time increased to 1.2x of last delay time on each failure.
This make wg keeps wait for around 1 minutes until dns resolved or all attempts failed.

BTW, the reset-wireguard.xml.in is simplified by following your tips, please check if there is anything else I didn't make right.
That was AI generated code, because my earlier attempts on completions were failed.

@sarthurdev
Copy link
Member

By default, wg retries 15 times, delay time increased to 1.2x of last delay time on each failure.
This make wg keeps wait for around 1 minutes until dns resolved or all attempts failed.

That's what I was concerned by, we want to avoid long boot/commit time because of DNS resolution not being available.

@sskaje
Copy link
Contributor Author

sskaje commented Nov 20, 2024

By default, wg retries 15 times, delay time increased to 1.2x of last delay time on each failure.
This make wg keeps wait for around 1 minutes until dns resolved or all attempts failed.

That's what I was concerned by, we want to avoid long boot/commit time because of DNS resolution not being available.

Yes, that's why I set it to 5 and I still feel it costs too much time.

How about 3x? Or 3x by default and let user can customize it in somewhere like set interfaces wireguard wg0 max-dns-retry?

@sskaje
Copy link
Contributor Author

sskaje commented Nov 21, 2024

max-dns-retry added, limit 1-15.

vyos@vyos# set interfaces wireguard wg0
Possible completions:
+  address              IP address
   description          Description
   disable              Administratively disable interface
   domain-name          Endpoint Domain Name
   fwmark               A 32-bit fwmark value set on all outgoing packets (default: 0)
 > ip                   IPv4 routing parameters
 > ipv6                 IPv6 routing parameters
   max-dns-retry        Max retry when DNS resolves failed. (default: 3)
 > mirror               Mirror ingress/egress packets
   mtu                  Maximum Transmission Unit (MTU) (default: 1420)
+> peer                 peer alias
   per-client-thread    Process traffic from each client in a dedicated thread
   port                 Port number used by connection
   private-key          Base64 encoded private key
   redirect             Redirect incoming packet to destination
   vrf                  VRF instance name


[edit]
vyos@vyos# set interfaces wireguard wg0 max-dns-retry
Possible completions:
   <1-15>               Max retry times



[edit]
vyos@vyos# set interfaces wireguard wg0 max-dns-retry 3
[edit]
vyos@vyos#

@sskaje
Copy link
Contributor Author

sskaje commented Nov 29, 2024

Hi reviewers,

Still need help:

  1. Exception handling in WireGuardIf.update(). print() or any best practice in vyos?
  2. vyos-domain-resolver part in interfaces_wireguard, need help about the logic: as I read what's in nat & firewall, the service will keep running if ip_fqdn or ip6_fqdn not empty. That means I should check all working peers and build a similar object storing peers with domain, and check if this object not empty to create the /run/use-vyos-domain-resolver-*?

Copy link

CI integration ❌ failed!

Details

CI logs

  • CLI Smoketests (no interfaces) ❌ failed
  • CLI Smoketests (interfaces only) ❌ failed
  • Config tests ❌ failed
  • RAID1 tests ❌ failed
  • TPM tests ❌ failed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

3 participants