I found that my vyconfd.service kept crashing with the following error:
Fatal error: exception Failure("lexing: empty token")I tried to find which config entry in my config.boot caused it and narrowed it down by running:
vyos@vyos# OCAMLRUNPARAM=b /usr/libexec/vyos/vyconf/vyconfd --no-daemon --legacy-config-path
Fatal error: exception Failure("lexing: empty token")
Raised by primitive operation at Stdlib__Lexing.engine in file "lexing.ml", line 65, characters 15-37
Called from Vyos1x__Vyos1x_lexer.__ocaml_lex_read_double_quoted_string_rec in file "src/vyos1x_lexer.ml", line 240, characters 8-65
Called from Vyos1x__Vyos1x_lexer.token in file "src/vyos1x_lexer.ml" (inlined), line 171, characters 3-48
Called from Vyos1x__Parser.parse in file "src/parser.ml", line 9, characters 34-74
Called from Vyos1x__Config_file.load_config in file "src/config_file.ml", line 19, characters 21-41
Called from Vyconfd_config__Startup.load_config_failsafe in file "src/startup.ml", line 83, characters 14-49
Called from Dune__exe__Vyconfd in file "src/vyconfd.ml", line 385, characters 6-65I could then find it was in a double quoted string, and found the culprit. In one of my OpenVPN configs I have:
set interfaces openvpn vtun3 openvpn-option '--static-challenge Enter\ TOTP\ Code 1'
this resulted in the following config.boot entry:
openvpn vtun0 {
...
openvpn-option "--static-challenge Enter\ TOTP\ Code 1"
...
}As a workaround I just changed the message to Enter_TOTP_Code as it's only for the client to display this message.
But the --static-challenge option is meant to be something like this: --static-challenge "Enter Google Authenticator Code" 1 but VyOS does not allow any single or double quotes within your value so the escaped space was a good working workaround.
The OpenVPN config option is not the point of this bug though, it's mainly that an escaped space in a double quoted string crashes vyconfd. Actually any escaped character will crash it.
I made a simple reproducible test case for testing:
# stop vyconfd as we will try to execute it manually for testing purposes
systemctl stop vyconfd
# configure and save the quoted string with escaped character (eg: space, but any character will trigger the crash)
configure
set interfaces ethernet eth0 description "Hello\ World"
commit
save
# run vyconfd
vyos@vyos# /usr/libexec/vyos/vyconf/vyconfd --no-daemon --legacy-config-path
Fatal error: exception Failure("lexing: empty token")