Author image Tobias Bossert
and 1 contributors

NAME

Wrapper class around the wireguard configuration files

SYNOPSIS

 use Wireguard::WGmeta::Wrapper::Config;
 my $wg_meta = Wireguard::WGmeta::Wrapper::Config->new('<path to wireguard configuration>');

DESCRIPTION

This class serves as wrapper around the Wireguard configurations files. It is able to parse, modify, add and write Wireguard .conf files. In addition, support for metadata is built in. As a small bonus, the parser and encoder are exported ar usable as standalone methods

EXAMPLES

 use Wireguard::WGmeta::Wrapper::Config;
 my $wg-meta = Wireguard::WGmeta::Wrapper::Config->new('<path to wireguard configuration>');

 # set an attribute (non wg-meta attributes forwarded to the original `wg set` command)
 wg_meta->set('wg0', 'WG_0_PEER_A_PUBLIC_KEY', '<attribute_name>', '<attribute_value>');

 # set an alias for a peer
 wg_meta->set('wg0', 'WG_0_PEER_A_PUBLIC_KEY', 'Alias', 'some_fancy_alias');

 # disable peer (this comments out the peer in the configuration file
 wg_meta->disable_by_alias('wg0', 'some_fancy_alias');

 # write config (if parameter is set to True, the config is overwritten, if set to False the resulting file is suffixed with '_dryrun'
 wg_meta->commit(1);

 # Or use just the parser
 my $hash_parsed_configs = read_wg_configs('/etc/wireguard/', '#+', '#-');

 # and similarly to transform the parsed config into a wireguard compatible format again
 my $wg0_config = create_wg_config($hash_parsed_configs{wg0}, '#+', '#-')

METHODS

new($wireguard_home [, $wg_meta_prefix = '#+', $wg_meta_disabled_prefix = '#-'])

Creates a new instance of this class. Default wg-meta attributes: 'Name' and 'Alias'.

Parameters

  • $wireguard_home Path to Wireguard configuration files. Make sure the path ends with a `/`.

  • [, $wg_meta_prefix] A custom wg-meta comment prefix, has to begin with either `;` or `#`. It is recommended to not change this setting, especially in a already deployed installation.

  • [, $wg_meta_disabled_prefix] A custom prefix for the commented out (disabled) sections, has to begin with either `;` or `#` and must not be equal with $wg_meta_prefix! (This is enforced and an exception is thrown if violated) It is recommended to not change this setting, especially in a ready deployed installation.

  • [, $ref_hash_additional_attrs] A reference to a list containing additional wg-meta attributes, the intersect of this list with the default attributes defines the "valid wg-meta attributes".

Returns

An instance of Wrapper::Config

set($interface, $identifier, $attribute, $value [, $allow_non_meta, $forward_function])

Sets a value on a specific interface section.

Parameters

  • $interface Valid interface identifier (e.g 'wg0')

  • $identifier If the target section is a peer, this is usually the public key of this peer. If target is an interface, its again the interface name

  • $attribute Attribute name (Case does not not matter)

  • [$allow_non_meta = FALSE] If set to TRUE, non wg-meta attributes are not forwarded to `wg set`. However be extra careful when using this, just the attribute names are validated but not the data!

  • [$forward_function = undef] A reference to a callback function when $allow_non_meta = TRUE. The following signature is expected: forward_fun($interface, $identifier, $attribute, $value)

Raises

Exception if either the interface or identifier is invalid

Returns

None

attr_value_is_valid($attribute, $value, $ref_valid_attrs)

Simply calls the validate() function defined in Wireguard::WGmeta::Validator

Parameters

Returns

True if validation was successful, False if not

set_by_alias($interface, $alias, $attribute, $value [, $allow_non_meta = FALSE, $forward_function = undef])

Same as "set($interface, $identifier, $attribute, $value [, $allow_non_meta, $forward_function])" - just with alias support.

Raises

Exception if alias is invalid

disable($interface, $identifier)

Disables a peer

Parameters

  • $interface Valid interface name (e.g 'wg0').

  • $identifier A valid identifier: If the target section is a peer, this is usually the public key of this peer. If target is an interface, its again the interface name.

Returns

None

enable($interface, $identifier)

Inverse method if "disable($interface, $identifier)"

disable_by_alias($interface, $alias)

Same as "disable($interface, $identifier)" just with alias support

Raises

Exception if alias is invalid

disable_by_alias($interface, $alias)

Same as "enable($interface, $identifier)"ust with alias support

Raises

Exception if alias is invalid

translate_alias($interface, $alias)

Translates an alias to a valid identifier.

Parameters

  • $interface A valid interface name (e.g 'wg0').

  • $alias An alias to translate

Raises

Exception if alias is invalid

Returns

A valid identifier.

try_translate_alias($interface, $may_alias)

Tries to translate an identifier (which may be an alias). However, unlike "translate_alias($interface, $alias)", no exception is thrown on failure, instead the $may_alias is returned.

Parameters

  • $interface A valid interface name (is not validated)

  • $may_alias An identifier which could be a valid alias for this interface

Returns

If the alias is valid for the specified interface, the corresponding identifier is returned, else $may_alias

read_wg_configs($wireguard_home, $wg_meta_prefix, $disabled_prefix)

Parses all configuration files in $wireguard_home matching .*.conf$ and returns a hash with the following structure:

    {
        'interface_name' => {
            'section_order' => <list_of_available_section_identifiers>,
            'alias_map'     => <mapping_alias_to_identifier>,
            'checksum'      => <calculated_checksum_of_this_interface_config>,
            'a_identifier'    => {
                'type'  => <'Interface' or 'Peer'>,
                'order' => <list_of_attributes_in_their_original_order>,
                'attr0' => <value_of_attr0>,
                'attrN' => <value_of_attrN>
            },
            'an_other_identifier => {
                [...]
            }
        },
        'an_other_interface' => {
            [...]
        }
    }

Remarks

  • This method can be used as stand-alone together with the corresponding "create_wg_config($ref_interface_config, $wg_meta_prefix, $disabled_prefix [, $plain = FALSE])".

  • If the section is of type 'Peer' the identifier equals to its public-key, otherwise its the interface name again

  • wg-meta attributes are always prefixed with $wg_meta_prefix.

  • If a section is marked as "disabled", this is represented in the attribute $wg_meta_prefix. 'Disabled' . However, does only exist if this section has been enabled/disabled once.

  • To check wether a file is actually a Wireguard interface config, the parser first checks the presence of the string [Interface]. If not present, the file is skipped (without warning!).

Parameters

  • $wireguard_home Path to wireguard configuartion files

  • $wg_meta_prefix wg-meta prefix. Must start with '#' or ';'

  • $disabled_prefix disabled prefix. Must start with '#' or ';'

Raises

An exceptions if:

  • If the $wireguard_home directory does not contain any matching config file.

  • If a config files is not readable.

  • If the parser ends up in an invalid state (e.g a section without information).

A warning:

  • On a checksum mismatch

Returns

A reference to a hash with the structure described above.

split_and_trim($line, $separator)

Utility method to split and trim a string separated by $separator.

Parameters

  • $line Input string (e.g 'This = That ')

  • $separator String separator (e.v '=')

Returns

Two strings. With example values given in the parameters this would be 'This' and 'That'.

create_wg_config($ref_interface_config, $wg_meta_prefix, $disabled_prefix [, $plain = FALSE])

Turns a reference of interface-config hash (just a single interface) (as defined in "read_wg_configs($wireguard_home, $wg_meta_prefix, $disabled_prefix)") back into a wireguard config.

Parameters

  • $ref_interface_config Reference to hash containing one interface config.

  • $wg_meta_prefix Has to start with a '#' or ';' character and is optimally the same as in "read_wg_configs($wireguard_home, $wg_meta_prefix, $disabled_prefix)"

  • $wg_meta_prefix Same restrictions as parameter $wg_meta_prefix

  • [, $plain = FALSE] If set to true, no header is added (useful for checksum calculation)

Returns

A string, ready to be written down as a config file.

commit([$is_hot_config = FALSE, $plain = FALSE])

Writes down the parsed config to the wireguard configuration folder

Parameters

  • [$is_hot_config = FALSE]) If set to TRUE, the existing configuration is overwritten. Otherwise, the suffix '_not_applied' is appended to the filename

  • [$plain = FALSE]) If set to TRUE, no header is generated

Raises

Exception if: Folder or file is not writeable

Returns

None

get_interface_list()

Return a list of all interfaces

Returns

A list of all valid interface names. If no interfaces are available, an empty list is returned

get_interface_section($interface, $identifier)

Returns a hash representing a section of a given interface

Parameters

  • $interface Valid interface name

  • $identifier Valid section identifier

Returns

A hash containing the requested section. If the requested section/interface is not present, an empty hash is returned.

get_section_list($interface)

Returns a list of valid sections of an interface (ordered as in the original config file).

Parameters

  • $interface A valid interface name

Returns

A list of all sections of an interface. If interface is not present, an empty list is returned.

add_interface($interface_name, $ip_address, $listen_port, $private_key)

Adds a (minimally configured) interface. If more attributes are needed, please set them using the set() method.

Caveat: No validation is performed on the values!

Parameters

  • $interface_name A new interface name, must be unique.

  • $ip_address A string describing the ip net(s) (e.g '10.0.0.0/24, fdc9:281f:04d7:9ee9::2/64')

  • $listen_port The listen port for this interface.

  • $private_key A private key for this interface

Raises

An exception if the interface name already exists.

Returns

None

add_peer($interface, $name, $ip_address, $public_key [, $alias, $preshared_key])

Adds a peer to an exiting interface.

Caveat: No validation is performed on the values!

Parameters

  • $interface A valid interface.

  • $name A name for this peer (wg-meta).

  • $ip_address A string describing the ip-address(es) of this this peer.

  • $public_key Public-key for this interface. This becomes the identifier of this peer.

  • [$preshared_key] Optional argument defining the psk.

  • [$alias] Optional argument defining an alias for this peer (wg-meta)

Raises

An exception if either the interface is invalid, the alias is already assigned or the public-key is already present on an other peer.

Returns

A tuple consisting of the iface private-key and listen port

remove_peer($interface, $identifier)

Removes a peer (identified by it's public key or alias) from an interface.

Parameters

  • $interface A valid interface name

  • $identifier A valid identifier (or an alias)

Raises

Exception if interface or identifier is invalid

Returns

None

remove_interface($interface [, $keep_file = FALSE])

Removes an interface

Parameters

  • $interface A valid interface name

  • $keep_file = FALSE If set to True, an empty file is left behind.

Raises

Exception if interface or identifier is invalid

Returns

None

dump()

Simple dumper method to print contents of $self->{parsed_config}.