Modify

Opened 5 years ago

Closed 18 months ago

#10518 closed defect (fixed)

Openvpn not parsing the configuration file correctly on r29341

Reported by: Weikai Owned by: developers
Priority: normal Milestone: Barrier Breaker 14.07
Component: packages Version: Trunk
Keywords: Openvpn Cc:

Description

I have push command in the config file such as list push 'route 192.168.3.0 255.255.255.0'. When the config file is processed it generates the following parameters.

--client-to-client --comp-lzo --persist-key --persist-tun --ca /etc/openvpn/ca.crt --cert /etc/openvpn/server.crt --client-config-dir /etc/openvpn/clients --client-connect /etc/openvpn/client_connect.sh --dev tun --dh /etc/openvpn/dh1024.pem --group nogroup --ifconfig-pool-persist /tmp/ipp.txt --keepalive 10 60 --key /etc/openvpn/server.key --log /tmp/openvpn.log --port 1194 --proto udp --route 192.168.0.0 255.255.255.0 --script-security 2 --server 10.8.0.0 255.255.255.0 --status /tmp/openvpn-status.log --user nobody --verb 3 --push 'dhcp-option DNS 10.8.0.1' --push 'route 192.168.3.0 255.255.255.0'

The client doesn't like the pushed route to be in a single quote so it throw up an error saying "Tue Nov 29 16:19:38 2011 us=764000 PUSH: Received control message: 'PUSH_REPLY,'dhcp-option DNS 10.8.0.1','route 192.168.3.0 255.255.255.0',route 10.8.0.0 255.255.255.0,topology net30,ping 10,ping-restart 60,ifconfig 10.8.0.6 10.8.0.5'
Tue Nov 29 16:19:38 2011 us=764000 Options error: Unrecognized option or missing parameter(s) in [PUSH-OPTIONS]:1: dhcp-option DNS 10.8.0.1 (2.2.1)
Tue Nov 29 16:19:38 2011 us=764000 Options error: Unrecognized option or missing parameter(s) in [PUSH-OPTIONS]:2: route 192.168.3.0 255.255.255.0 (2.2.1)"

Once I changed the single quote in the parameters to double quotes, it works correctly.

--client-to-client --comp-lzo --persist-key --persist-tun --ca /etc/openvpn/ca.crt --cert /etc/openvpn/server.crt --client-config-dir /etc/openvpn/clients --client-connect /etc/openvpn/client_connect.sh --dev tun --dh /etc/openvpn/dh1024.pem --group nogroup --ifconfig-pool-persist /tmp/ipp.txt --keepalive 10 60 --key /etc/openvpn/server.key --log /tmp/openvpn.log --port 1194 --proto udp --route 192.168.0.0 255.255.255.0 --script-security 2 --server 10.8.0.0 255.255.255.0 --status /tmp/openvpn-status.log --user nobody --verb 3 --push "dhcp-option DNS 10.8.0.1" --push "route 192.168.3.0 255.255.255.0"

Attachments (0)

Change History (11)

comment:1 follow-up: Changed 5 years ago by Weikai

Removed the single quotes on line 42 in /etc/init.d/openvpn file fixed the problem. At least it works with my configuration file.

updated line 42
[ -n "$v" ] && append_param "$p" && ARGS="$ARGS $v"

comment:2 Changed 4 years ago by Sven Roederer <Sven.Roederer@…>

Hi,

I've the same "push route" issue.
I looked a bit into it and came to the conclusion, it's not really a problem of the configuration parsing.
The issue is raised by r29167 (reorganization of init-script). In line 111 both versions generating the same content for $ARGS and then just start the binary. The changes between r29167 and HEAD (r29485) don't have any influence to the logic.
The point seems to be how the binary get's started. In r29166 it's called directly by the init-script, since r29167 it uses the wrapper-function "service_start". This function comes from "/etc/functions.sh".

comment:3 in reply to: ↑ 1 Changed 4 years ago by Sven Roederer <Sven.Roederer@…>

Replying to Weikai:

Removed the single quotes on line 42 in /etc/init.d/openvpn file fixed the problem. At least it works with my configuration file.

updated line 42
[ -n "$v" ] && append_param "$p" && ARGS="$ARGS $v"

Does it really work? Line 42 is in "append_params()", I think the push-parameters should be handeled by "append_params_quoted()".

comment:4 Changed 4 years ago by Weikai

Here's my updated /etc/init.d/openvpn on r29341

#!/bin/sh /etc/rc.common
# Copyright (C) 2008-2011 OpenWrt.org
# Copyright (C) 2008 Jo-Philipp Wich
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.

START=95

SERVICE_DAEMONIZE=1
SERVICE_WRITE_PID=1

EXTRA_COMMANDS="up down"

LIST_SEP="
"

append_param() {
        local v="$1"
        case "$v" in
                *_*_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
                *_*_*)   v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
                *_*)     v=${v%%_*}-${v#*_} ;;
        esac
        ARGS="$ARGS --$v"
        return 0
}

append_bools() {
        local p; local v; local s="$1"; shift
        for p in $*; do
                config_get_bool v "$s" "$p"
                [ "$v" == 1 ] && append_param "$p"
        done
}

append_params() {
        local p; local v; local s="$1"; shift
        for p in $*; do
                config_get v "$s" "$p"
                IFS="$LIST_SEP"
                for v in $v; do
                        [ -n "$v" ] && append_param "$p" && ARGS="$ARGS $v"
                done
                unset IFS
        done
}

append_params_quoted() {
        local p; local v; local s="$1"; shift
        for p in $*; do
                config_get v "$s" "$p"
                IFS="$LIST_SEP"
                for v in $v; do
                        [ -n "$v" ] && append_param "$p" && ARGS="$ARGS $v"
                done
                unset IFS
        done
}

section_enabled() {
        config_get_bool enabled "$1" 'enabled' 0
        [ $enabled -gt 0 ]
}

start_instance() {
        local s="$1"

        section_enabled "$s" || return 1

        ARGS=""

        # append flags
        append_bools "$s" \
                auth_nocache auth_retry auth_user_pass_optional bind ccd_exclusive client client_cert_not_required \
                client_disconnect client_to_client comp_lzo comp_noadapt disable \
                disable_occ down_pre duplicate_cn fast_io float http_proxy_retry \
                ifconfig_noexec ifconfig_nowarn ifconfig_pool_linear management_forget_disconnect management_hold \
                management_query_passwords management_signal mktun mlock mtu_test multihome mute_replay_warnings \
                nobind no_iv no_name_remapping no_replay opt_verify passtos persist_key persist_local_ip \
                persist_remote_ip persist_tun ping_timer_rem pull push_reset \
                remote_random rmtun route_noexec route_nopull single_session socks_proxy_retry \
                suppress_timestamps tcp_nodelay test_crypto tls_client tls_exit tls_server \
                tun_ipv6 up_delay up_restart username_as_common_name

        # append params
        append_params "$s" \
                cd askpass auth auth_user_pass auth_user_pass_verify bcast_buffers ca cert \
                chroot cipher client_config_dir client_connect config connect_freq \
                connect_retry connect_timeout connect_retry_max crl_verify dev dev_node dev_type dh \
                echo engine explicit_exit_notify fragment group hand_window hash_size \
                http_proxy http_proxy_option http_proxy_timeout ifconfig ifconfig_pool \
                ifconfig_pool_persist ifconfig_push inactive ipchange iroute keepalive \
                key key_method keysize learn_address link_mtu lladdr local log log_append \
                lport management management_log_cache max_clients \
                max_routes_per_client mode mssfix mtu_disc mute nice ns_cert_type ping \
                ping_exit ping_restart pkcs12 plugin port port_share prng proto rcvbuf \
                redirect_gateway remap_usr1 remote remote_cert_eku remote_cert_ku remote_cert_tls \
                reneg_bytes reneg_pkts reneg_sec \
                replay_persist replay_window resolv_retry route route_delay route_gateway \
                route_metric route_up rport script_security secret server server_bridge setenv shaper sndbuf \
                socks_proxy status status_version syslog tcp_queue_limit tls_auth \
                tls_cipher tls_remote tls_timeout tls_verify tmp_dir topology tran_window \
                tun_mtu tun_mtu_extra txqueuelen user verb

        # append multi-value params
        append_params_quoted "$s" \
                down push up


        SERVICE_PID_FILE="/var/run/openvpn-$s.pid"
        service_start /usr/sbin/openvpn --syslog "openvpn($s)" --writepid "$SERVICE_PID_FILE" $ARGS
}

stop_instance() {
        local s="$1"

        section_enabled "$s" || return 1

        SERVICE_PID_FILE="/var/run/openvpn-$s.pid"
        service_stop /usr/sbin/openvpn
}

reload_instance() {
        local s="$1"

        section_enabled "$s" || return 1

        SERVICE_PID_FILE="/var/run/openvpn-$s.pid"
        service_reload /usr/sbin/openvpn
}

start() {
        config_load 'openvpn'
        config_foreach start_instance 'openvpn'
}

stop() {
        config_load 'openvpn'
        config_foreach stop_instance 'openvpn'
}

reload() {
        config_load 'openvpn'
        config_foreach reload_instance 'openvpn'
}

up() {
        local exists
        local instance
        config_load 'openvpn'
        for instance in "$@"; do
                config_get exists "$instance" 'TYPE'
                if [ "$exists" == "openvpn" ]; then
                        start_instance "$instance"
                fi
        done
}

down() {
        local exists
        local instance
        config_load 'openvpn'
        for instance in "$@"; do
                config_get exists "$instance" 'TYPE'
                if [ "$exists" == "openvpn" ]; then
                        stop_instance "$instance"
                fi
        done
}

comment:5 Changed 4 years ago by anonymous

The start script wraps a "push" option in single
quotes (append_params_quoted). But the openvpn executable does not
understand --push 'route network netmask', it expects --push route
network netmask!

This directly contradicts the OpenVPN manpage:

--push option

Push a config file option back to the client for remote execu-
tion. Note that option must be enclosed in double quotes ("").

The config *file* parser removes single and double quotes, but the
command line parser expects bare, unquoted words. Sigh.

The entire append_params_quoted logic in /etc/init.d/openvpn has to go.
I checked the --up option, and it only takes the name of a command. The
same goes for --down. Curious thing - these two parameters are dequoted
by the options processing.

The scripts for --up or --down are called with arguments as described in
the openvpn manpage.

BTW - the bug title is completely off. The scripts does parse correctly, what it does
with the result is the culprit.

comment:6 Changed 4 years ago by risa2000

So, what is the resolution?
Currently I am facing the same issue, getting this on client side:

Feb 19 10:25:45 pepik-wrt daemon.notice openvpn(pepik_wrt)[2241]: PUSH: Received control message: 'PUSH_REPLY,'route 192.168.6.0 255.255.255.0',route 192.168.100.1,topology net30,ping 10,ping-restart 120,ifconfig 192.168.100.6 192.168.100.5'
Feb 19 10:25:45 pepik-wrt daemon.err openvpn(pepik_wrt)[2241]: Options error: Unrecognized option or missing parameter(s) in [PUSH-OPTIONS]:1: route 192.168.6.0 255.255.255.0 (2.2.1)

Apparently there are abundant single quotes on the input client side parses. I checked my /etc/init.d/openvpn and it seems to be the same as proposed by Weikai above, but clearly does not solve the issue. Interestingly the "other" route command (to the server) is passed correctly.

comment:7 Changed 4 years ago by jow

  • Resolution set to fixed
  • Status changed from new to closed

Fixed in r30719.

comment:8 Changed 4 years ago by risa2000

Confirmed on my setup. Thanks!

comment:9 Changed 22 months ago by jow

  • Milestone changed from Attitude Adjustment 12.09 to Barrier Breaker 14.07

Milestone Attitude Adjustment 12.09 deleted

comment:10 Changed 18 months ago by ISO

  • Resolution fixed deleted
  • Status changed from closed to reopened

DISTRIB_ID="OpenWrt"
DISTRIB_RELEASE="14.07"
DISTRIB_REVISION="r42625"
DISTRIB_CODENAME="barrier_breaker"
DISTRIB_TARGET="ar71xx/generic"
DISTRIB_DESCRIPTION="OpenWrt Barrier Breaker 14.07"
DISTRIB_TAINTS=""

This issue i believe persist, SOME settings from /etc/config/openvpn are NOT passed through to /var/etc/openvpn-*.cnf by /etc/init.d/openvpn.

For example in /etc/config/openvpn i have:

option persist-key '1'
option persist-tun '1'

But i have an error in /tmp/openvpn.log:

WARNING: you are using user/group/chroot/setcon without persist-tun --
WARNING: you are using user/group/chroot/setcon without persist-key --

If i manually edit /var/etc/openvpn-*.cnf and manually add persist-tun and persist-key, and i invoke directly the conf file in a shell like so:

$ openvpn /var/etc/openvpn-*.cnf

i will not see the WARNING messages in /tmp/openvpn.log. As soon as i redo /etc/init.d/openvpn restart, persist-tun and persist-key dissappear.

OpenVPN 2.3.4 mips-openwrt-linux-gnu [SSL (OpenSSL)] [LZO] [EPOLL] [MH] [IPv6] built on Sep 20 2014
library versions: OpenSSL 1.0.1j 15 Oct 2014, LZO 2.08
Originally developed by James Yonan
Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>

comment:11 Changed 18 months ago by cyrus

  • Resolution set to fixed
  • Status changed from reopened to closed

OpenWrt doesn't support option names with dashes (-) in them you have to turn them into underscores (_), e.g. persistent-key -> persistent_key

Add Comment

Modify Ticket

Action
as closed .
The resolution will be deleted. Next status will be 'reopened'.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.