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

os-wireguard: add script to enable cron renewal of DNS for stale connections #2956

Merged
merged 5 commits into from May 12, 2022

Conversation

meyergru
Copy link
Contributor

Wireguard does DNS resolution of endpoints only on startup. Even when a keepalive is in place, a stale connection does not lead to a renewal of DNS entries in case the other side's IP has changed.

This adds a script that can be called from cron every now and then and then triggers a DNS renewal for all stale connections.

Update version number
Add new version
Script for DNS renewal of all Wireguard interfaces in case of stale connections
Add "renew" action for cron
@mimugmail
Copy link
Member

Hi,

Did you successfully tested it on your machine?

@meyergru
Copy link
Contributor Author

meyergru commented Apr 25, 2022

Sort of: I ran the script with "set -x" and it read the configs fine and I can use it from cron after "service configd restart" and a restart of the web ui. I cannot force a connection to go stale, though, so I cannot check if it is effective.

The script basis is from the original Wireguard author (it was called reresolve.sh in the contrib directory of the wireguard tools), so it should do what is expected. It uses wg to check the timestamp of the last handshake and if it is older than ~2 minutes, it just restarts the connection. I could see everything but the restart on my script run.

The only thing I added was a loop over all wireguard interface files, which are under /usr/locat/etc/wireguard on OpnSense. Also, bash is in another location, so the shebang had to be altered,

@Greelan
Copy link
Contributor

Greelan commented May 3, 2022

As an initial observations, afaik bash is not included in OPNsense by default. Is it installed with the WG plugin?

@meyergru
Copy link
Contributor Author

meyergru commented May 3, 2022

There is a dependency from os-wireguard to wireguard-tools, which in turn requires bash. wg-quick makes use of bash as well. You can check via 'pkg info -r bash' and 'pkg info -r wireguard-tools'. All of these packages are in the opnsense repo.

So yes, it is installed with os-wireguard.

Copy link
Member

@mimugmail mimugmail left a comment

Choose a reason for hiding this comment

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

OK for me, thx :)

@fichtner fichtner self-assigned this May 12, 2022
Comment on lines +1 to +2
#!/usr/local/bin/bash
# SPDX-License-Identifier: GPL-2.0
Copy link
Member

Choose a reason for hiding this comment

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

Could this be any more Linux-y :D

@fichtner
Copy link
Member

.sh might break validation of shell scripting but I'll deal with this post-merge. Thanks!

@fichtner fichtner merged commit f31a35b into opnsense:master May 12, 2022
@budimanjojo
Copy link
Contributor

Sorry for barging in, but I want to use this now. Will this be in the next OPNSense release? Can I just put these files in my OPNSense system with the same name (/usr/local/opnsense/service/conf/actions.d/actions_wireguard.conf and /usr/local/opnsense/scripts/OPNsense/Wireguard/resolve-dns.sh). Or I should put mine in different location?

@Greelan
Copy link
Contributor

Greelan commented May 13, 2022

I suspect opnsense-patch f31a35b -c plugins will do it, tho not sure whether it is ready for prime time given @fichtner'a comment about post-merge changes

@fichtner
Copy link
Member

There's an issue with the script since it doesn't have executable permission, but otherwise it should work as a single patch

@fichtner
Copy link
Member

(

And to get the cron command to show up this is needed:

# service configd restart

)

@budimanjojo
Copy link
Contributor

I suspect opnsense-patch f31a35b -c plugins will do it, tho not sure whether it is ready for prime time given @fichtner'a comment about post-merge changes

Wow I didn't know there's such thing in opnsense. This is gold, thank you!

There's an issue with the script since it doesn't have executable permission, but otherwise it should work as a single patch

I also just found out that you renamed the files .sh to .bash. Can I run opnsense-patch command with your latest changes and then change the permission and call it a day?

@budimanjojo
Copy link
Contributor

I managed to do this using:
opnsense-patch -c plugins f31a35b (-c plugins needs to be before the commit id actually)
then I do another opnsense-patch -c plugins 10aee29. After that I do service configd restart and everything is now good. Thank you!

@fichtner
Copy link
Member

yes, I think opnsense-patch can fixup the permission given the patch :)

@budimanjojo
Copy link
Contributor

budimanjojo commented May 13, 2022

Looks like something is wrong here.

root@OPNsense:/home/budiman # /usr/local/opnsense/scripts/OPNsense/Wireguard/resolve-dns.bash
/usr/local/opnsense/scripts/OPNsense/Wireguard/resolve-dns.bash: line 19: syntax error in conditional expression: unexpected token `('

Now I'm running into this issue and every configctl command failed T.T:

root@OPNsense:/home/budiman # configctl wireguard renew
configd socket missing (@/var/run/configd.socket)

@fichtner
Copy link
Member

configd not coming back up? try restarting again. as for bash script error... sorry I have to pass. Sort of the reason why we don't want to offer native bash support in core.

@mimugmail
Copy link
Member

@meyergru can you fix the line breaks please? It seems there were some c+p issues

@budimanjojo
Copy link
Contributor

Can I try to fix this?

@budimanjojo
Copy link
Contributor

budimanjojo commented May 13, 2022

I have tried this and it's working

#!/usr/local/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2015-2020 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.

set -e
shopt -s nocasematch
shopt -s extglob
export LC_ALL=C

for CONFIG_FILE in /usr/local/etc/wireguard/*.conf; do

[[ $CONFIG_FILE =~ /?([a-zA-Z0-9_=+.-]{1,15})\.conf$ ]]
INTERFACE="${BASH_REMATCH[1]}"

process_peer() {
        [[ $PEER_SECTION -ne 1 || -z $PUBLIC_KEY || -z $ENDPOINT ]] && return 0
        [[ $(wg show "$INTERFACE" latest-handshakes) =~ ${PUBLIC_KEY//+/\\+}\   ([0-9]+) ]] || return 0
        (( ($EPOCHSECONDS - ${BASH_REMATCH[1]}) > 135 )) || return 0
        wg set "$INTERFACE" peer "$PUBLIC_KEY" endpoint "$ENDPOINT"
        reset_peer_section
}

reset_peer_section() {
        PEER_SECTION=0
        PUBLIC_KEY=""
        ENDPOINT=""
}

reset_peer_section
while read -r line || [[ -n $line ]]; do
        stripped="${line%%\#*}"
        key="${stripped%%=*}"; key="${key##*([[:space:]])}"; key="${key%%*([[:space:]])}"
        value="${stripped#*=}"; value="${value##*([[:space:]])}"; value="${value%%*([[:space:]])}"
        [[ $key == "["* ]] && { process_peer; reset_peer_section; }
        [[ $key == "[Peer]" ]] && PEER_SECTION=1
        if [[ $PEER_SECTION -eq 1 ]]; then
                case "$key" in
                PublicKey) PUBLIC_KEY="$value"; continue ;;
                Endpoint) ENDPOINT="$value"; continue ;;
                esac
        fi
done < "$CONFIG_FILE"
process_peer
done

@budimanjojo
Copy link
Contributor

configd not coming back up?

No it didn't until I deleted the action, cron service was failing to start and everything became sluggish (configctl commands are not working)
I have fixed it in my end by fixing the script new lines, this is dangerous, especially if I didn't became the lab rat before this get into release :D

@meyergru
Copy link
Contributor Author

Sorry, I edited the files in Github web UI, where you cannot set execute bits and have no control over newlines.

@budimanjojo
Copy link
Contributor

Please also change Wireguard toWireGuard. Notice the capital G there 😁

@meyergru
Copy link
Contributor Author

I am currently on vacation and cannot do anything useful.

@Greelan
Copy link
Contributor

Greelan commented May 13, 2022

@budimanjojo why not create your own PR with the tidy-ups you're after? :)

@budimanjojo
Copy link
Contributor

Done, Please take a look

@Greelan
Copy link
Contributor

Greelan commented May 14, 2022

Looks OK to me

agh1467 pushed a commit to agh1467/plugins that referenced this pull request Jun 11, 2022
agh1467 pushed a commit to agh1467/plugins that referenced this pull request Jun 11, 2022
@TheHellSite
Copy link

I am currently using a monit service to restart a stale wg interface. Working well.

Just a quick question about the script. Is it meant to be run like every 5 minutes?

@digitalface
Copy link

digitalface commented Jun 29, 2022

Hi all,

I have WG 1.11 installed with a few enpoints set up and this DNS feature would be really useful for me. But how do I enable it? I cannot see a setting under WG.

Thanks in advance

[edit] Ignore, I can see it under settings/cron

@meyergru
Copy link
Contributor Author

You have to enable it as a cron job.

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

Successfully merging this pull request may close these issues.

None yet

7 participants