-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #44 from freeflowuniverse/development_wg
Add SAL for wireguard
- Loading branch information
Showing
13 changed files
with
620 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[Interface] | ||
Address = 10.10.3.0/24 | ||
PrivateKey = wDewSiri8jlaGnUDN6SwK7QhN082U7gfX27YMGILvVA= | ||
[Peer] | ||
PublicKey = 2JEGJQ8FbajdFk0fFs/881H/D3FRjwlUxvNDZFxDeWQ= | ||
AllowedIPs = 10.10.0.0/16, 100.64.0.0/16 | ||
PersistentKeepalive = 25 | ||
Endpoint = 185.206.122.31:3241 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#!/usr/bin/env -S v -n -w -gc none -no-retry-compilation -d use_openssl -enable-globals run | ||
|
||
import freeflowuniverse.herolib.clients.wireguard | ||
import freeflowuniverse.herolib.installers.net.wireguard as wireguard_installer | ||
import time | ||
import os | ||
|
||
mut wg_installer := wireguard_installer.get()! | ||
wg_installer.install()! | ||
|
||
// Create Wireguard client | ||
mut wg := wireguard.get()! | ||
config_file_path := '${os.dir(@FILE)}/wg0.conf' | ||
|
||
wg.start(config_file_path: config_file_path)! | ||
println('${config_file_path} is started') | ||
|
||
time.sleep(time.second * 2) | ||
|
||
info := wg.show()! | ||
println('info: ${info}') | ||
|
||
config := wg.show_config(interface_name: 'wg0')! | ||
println('config: ${config}') | ||
|
||
private_key := wg.generate_private_key()! | ||
println('private_key: ${private_key}') | ||
|
||
public_key := wg.get_public_key(private_key: private_key)! | ||
println('public_key: ${public_key}') | ||
|
||
wg.down(config_file_path: config_file_path)! | ||
println('${config_file_path} is down') | ||
|
||
wg_installer.destroy()! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
|
||
!!hero_code.generate_client | ||
name:'wireguard' | ||
classname:'WireGuard' | ||
singleton:0 | ||
default:1 | ||
hasconfig:1 | ||
reset:0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
module wireguard | ||
|
||
import os | ||
|
||
pub struct WGPeer { | ||
pub mut: | ||
endpoint string | ||
allowed_ips string | ||
latest_handshake string | ||
transfer string | ||
persistent_keepalive string | ||
} | ||
|
||
pub struct WGInterface { | ||
pub mut: | ||
name string | ||
public_key string | ||
listening_port int | ||
} | ||
|
||
pub struct WGInfo { | ||
pub mut: | ||
interface_ WGInterface | ||
peers map[string]WGPeer | ||
} | ||
|
||
pub struct WGShow { | ||
pub mut: | ||
configs map[string]WGInfo | ||
} | ||
|
||
pub fn (wg WireGuard) show() !WGShow { | ||
cmd := 'sudo wg show' | ||
res := os.execute(cmd) | ||
if res.exit_code != 0 { | ||
return error('failed to execute show command due to: ${res.output}') | ||
} | ||
|
||
return wg.parse_show_command_output(res.output) | ||
} | ||
|
||
@[params] | ||
pub struct ShowConfigArgs { | ||
pub: | ||
interface_name string @[required] | ||
} | ||
|
||
pub fn (wg WireGuard) show_config(args ShowConfigArgs) !WGInfo { | ||
configs := wg.show()!.configs | ||
config := configs[args.interface_name] or { | ||
return error('key ${args.interface_name} does not exists.') | ||
} | ||
return config | ||
} | ||
|
||
@[params] | ||
pub struct StartArgs { | ||
pub: | ||
config_file_path string @[required] | ||
} | ||
|
||
pub fn (wg WireGuard) start(args StartArgs) ! { | ||
if !os.exists(args.config_file_path) { | ||
return error('File ${args.config_file_path} does not exists.') | ||
} | ||
|
||
cmd := 'sudo wg-quick up ${args.config_file_path}' | ||
res := os.execute(cmd) | ||
if res.exit_code != 0 { | ||
return error('failed to execute start command due to: ${res.output}') | ||
} | ||
} | ||
|
||
@[params] | ||
pub struct DownArgs { | ||
pub: | ||
config_file_path string @[required] | ||
} | ||
|
||
pub fn (wg WireGuard) down(args DownArgs) ! { | ||
if !os.exists(args.config_file_path) { | ||
return error('File ${args.config_file_path} does not exists.') | ||
} | ||
|
||
cmd := 'sudo wg-quick down ${args.config_file_path}' | ||
res := os.execute(cmd) | ||
if res.exit_code != 0 { | ||
return error('failed to execute down command due to: ${res.output}') | ||
} | ||
} | ||
|
||
pub fn (wg WireGuard) generate_private_key() !string { | ||
cmd := 'wg genkey' | ||
res := os.execute(cmd) | ||
if res.exit_code != 0 { | ||
return error('failed to execute genkey command due to: ${res.output}') | ||
} | ||
return res.output.trim_space() | ||
} | ||
|
||
@[params] | ||
pub struct GetPublicKeyArgs { | ||
pub: | ||
private_key string @[required] | ||
} | ||
|
||
pub fn (wg WireGuard) get_public_key(args GetPublicKeyArgs) !string { | ||
cmd := 'echo ${args.private_key} | wg pubkey' | ||
res := os.execute(cmd) | ||
if res.exit_code != 0 { | ||
return error('failed to execute pubkey command due to: ${res.output}') | ||
} | ||
return res.output.trim_space() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# wireguard | ||
|
||
|
||
|
||
To get started | ||
|
||
```vlang | ||
import freeflowuniverse.herolib.clients. wireguard | ||
mut client:= wireguard.get()! | ||
client... | ||
``` | ||
|
||
## example heroscript | ||
|
||
```hero | ||
!!wireguard.configure | ||
secret: '...' | ||
host: 'localhost' | ||
port: 8888 | ||
``` | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
module wireguard | ||
|
||
fn (wg WireGuard) parse_show_command_output(res string) !WGShow { | ||
mut configs := map[string]WGInfo{} | ||
mut lines := res.split('\n') | ||
mut current_interface := '' | ||
mut current_peers := map[string]WGPeer{} | ||
mut iface := WGInterface{} | ||
mut peer_key := '' | ||
|
||
for line in lines { | ||
mut parts := line.trim_space().split(': ') | ||
if parts.len < 2 { | ||
continue | ||
} | ||
|
||
key := parts[0] | ||
value := parts[1] | ||
|
||
if key.starts_with('interface') { | ||
if current_interface != '' { | ||
configs[current_interface] = WGInfo{ | ||
interface_: iface | ||
peers: current_peers.clone() | ||
} | ||
current_peers.clear() | ||
} | ||
|
||
current_interface = value | ||
iface = WGInterface{ | ||
name: current_interface | ||
public_key: '' | ||
listening_port: 0 | ||
} | ||
} else if key == 'public key' { | ||
iface.public_key = value | ||
} else if key == 'listening port' { | ||
iface.listening_port = value.int() | ||
} else if key.starts_with('peer') { | ||
peer_key = value | ||
mut peer := WGPeer{ | ||
endpoint: '' | ||
allowed_ips: '' | ||
latest_handshake: '' | ||
transfer: '' | ||
persistent_keepalive: '' | ||
} | ||
current_peers[peer_key] = peer | ||
} else if key == 'endpoint' { | ||
current_peers[peer_key].endpoint = value | ||
} else if key == 'allowed ips' { | ||
current_peers[peer_key].allowed_ips = value | ||
} else if key == 'latest handshake' { | ||
current_peers[peer_key].latest_handshake = value | ||
} else if key == 'transfer' { | ||
current_peers[peer_key].transfer = value | ||
} else if key == 'persistent keepalive' { | ||
current_peers[peer_key].persistent_keepalive = value | ||
} | ||
} | ||
|
||
if current_interface != '' { | ||
configs[current_interface] = WGInfo{ | ||
interface_: iface | ||
peers: current_peers.clone() | ||
} | ||
} | ||
|
||
return WGShow{ | ||
configs: configs | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
module wireguard | ||
|
||
import freeflowuniverse.herolib.core.base | ||
import freeflowuniverse.herolib.core.playbook | ||
|
||
__global ( | ||
wireguard_global map[string]&WireGuard | ||
wireguard_default string | ||
) | ||
|
||
/////////FACTORY | ||
|
||
@[params] | ||
pub struct ArgsGet { | ||
pub mut: | ||
name string | ||
} | ||
|
||
fn args_get(args_ ArgsGet) ArgsGet { | ||
mut args := args_ | ||
if args.name == '' { | ||
args.name = wireguard_default | ||
} | ||
if args.name == '' { | ||
args.name = 'wireguard' | ||
} | ||
return args | ||
} | ||
|
||
pub fn get(args_ ArgsGet) !&WireGuard { | ||
mut args := args_get(args_) | ||
if args.name !in wireguard_global { | ||
if args.name == 'wireguard' { | ||
if !config_exists(args) { | ||
if default { | ||
println('When saving') | ||
config_save(args)! | ||
} | ||
} | ||
config_load(args)! | ||
} | ||
} | ||
return wireguard_global[args.name] or { | ||
println(wireguard_global) | ||
panic('could not get config for wireguard with name:${args.name}') | ||
} | ||
} | ||
|
||
fn config_exists(args_ ArgsGet) bool { | ||
mut args := args_get(args_) | ||
mut context := base.context() or { panic('bug') } | ||
return context.hero_config_exists('wireguard', args.name) | ||
} | ||
|
||
fn config_load(args_ ArgsGet) ! { | ||
mut args := args_get(args_) | ||
mut context := base.context()! | ||
mut heroscript := context.hero_config_get('wireguard', args.name)! | ||
play(heroscript: heroscript)! | ||
} | ||
|
||
fn config_save(args_ ArgsGet) ! { | ||
mut args := args_get(args_) | ||
mut context := base.context()! | ||
context.hero_config_set('wireguard', args.name, heroscript_default()!)! | ||
} | ||
|
||
fn set(o WireGuard) ! { | ||
mut o2 := obj_init(o)! | ||
wireguard_global[o.name] = &o2 | ||
wireguard_default = o.name | ||
} | ||
|
||
@[params] | ||
pub struct PlayArgs { | ||
pub mut: | ||
heroscript string // if filled in then plbook will be made out of it | ||
plbook ?playbook.PlayBook | ||
reset bool | ||
} | ||
|
||
pub fn play(args_ PlayArgs) ! { | ||
mut args := args_ | ||
|
||
if args.heroscript == '' { | ||
args.heroscript = heroscript_default()! | ||
} | ||
mut plbook := args.plbook or { playbook.new(text: args.heroscript)! } | ||
|
||
mut install_actions := plbook.find(filter: 'wireguard.configure')! | ||
if install_actions.len > 0 { | ||
for install_action in install_actions { | ||
mut p := install_action.params | ||
cfg_play(p)! | ||
} | ||
} | ||
} | ||
|
||
// switch instance to be used for wireguard | ||
pub fn switch(name string) { | ||
wireguard_default = name | ||
} |
Oops, something went wrong.