Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ascrod committed Feb 28, 2020
0 parents commit b627492
Show file tree
Hide file tree
Showing 12 changed files with 826 additions and 0 deletions.
51 changes: 51 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# $FreeBSD$

PORTNAME= pfSense-pkg-wireguard
PORTVERSION= 1.0.0
CATEGORIES= net net-vpn
MASTER_SITES= # empty
DISTFILES= # empty
EXTRACT_ONLY= # empty

MAINTAINER= [email protected]
COMMENT= pfSense package wireguard

LICENSE= GPLv2

RUN_DEPENDS= wg:net/wireguard \
wireguard-go:net/wireguard-go

NO_BUILD= yes
NO_MTREE= yes

SUB_FILES= pkg-install pkg-deinstall
SUB_LIST= PORTNAME=${PORTNAME}

do-extract:
${MKDIR} ${WRKSRC}

do-install:
${MKDIR} ${STAGEDIR}/etc/inc/priv
${MKDIR} ${STAGEDIR}${PREFIX}/pkg
${MKDIR} ${STAGEDIR}${PREFIX}/www
${MKDIR} ${STAGEDIR}${PREFIX}/www/shortcuts
${MKDIR} ${STAGEDIR}${DATADIR}
${INSTALL_DATA} ${FILESDIR}/etc/inc/priv/wireguard.priv.inc \
${STAGEDIR}/etc/inc/priv
${INSTALL_DATA} ${FILESDIR}${PREFIX}/pkg/wireguard.inc \
${STAGEDIR}${PREFIX}/pkg
${INSTALL_DATA} ${FILESDIR}${PREFIX}/pkg/wireguard.xml \
${STAGEDIR}${PREFIX}/pkg
${INSTALL_DATA} ${FILESDIR}${PREFIX}/pkg/wireguard_peers.xml \
${STAGEDIR}${PREFIX}/pkg
${INSTALL_DATA} ${FILESDIR}${PREFIX}/www/status_wireguard.php \
${STAGEDIR}${PREFIX}/www
${INSTALL_DATA} ${FILESDIR}${PREFIX}/www/shortcuts/pkg_wireguard.inc \
${STAGEDIR}${PREFIX}/www/shortcuts
${INSTALL_DATA} ${FILESDIR}${DATADIR}/info.xml \
${STAGEDIR}${DATADIR}
@${REINPLACE_CMD} -i '' -e "s|%%PKGVERSION%%|${PKGVERSION}|" \
${STAGEDIR}${DATADIR}/info.xml \
${STAGEDIR}${PREFIX}/pkg/wireguard.xml

.include <bsd.port.mk>
16 changes: 16 additions & 0 deletions files/etc/inc/priv/wireguard.priv.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

global $priv_list;

$priv_list['page-vpn-wireguard'] = array();
$priv_list['page-vpn-wireguard']['name'] = "WebCfg - VPN: WireGuard";
$priv_list['page-vpn-wireguard']['descr'] = "Allow access to the 'VPN: WireGuard' page.";
$priv_list['page-vpn-wireguard']['match'] = array();

$priv_list['page-vpn-wireguard']['match'][] = "pkg.php?xml=wireguard.xml*";
$priv_list['page-vpn-wireguard']['match'][] = "pkg.php?xml=wireguard_peers.xml*";
$priv_list['page-vpn-wireguard']['match'][] = "pkg_edit.php?xml=wireguard.xml*";
$priv_list['page-vpn-wireguard']['match'][] = "pkg_edit.php?xml=wireguard_peers.xml*";
$priv_list['page-vpn-wireguard']['match'][] = "status_wireguard.php*";

?>
3 changes: 3 additions & 0 deletions files/pkg-deinstall.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh

/usr/local/bin/php -f /etc/rc.packages %%PORTNAME%% ${2}
7 changes: 7 additions & 0 deletions files/pkg-install.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh

if [ "${2}" != "POST-INSTALL" ]; then
exit 0
fi

/usr/local/bin/php -f /etc/rc.packages %%PORTNAME%% ${2}
252 changes: 252 additions & 0 deletions files/usr/local/pkg/wireguard.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
<?php

require_once("globals.inc");
require_once("config.inc");
require_once("pfsense-utils.inc");
require_once("system.inc");
require_once("service-utils.inc");
require_once("util.inc");

# Rather than the traditional "wg0" name, we prefix with "tun" so that pfSense
# doesn't freak out about non-existant interfaces on boot and instead just ignores
# it. Technically wireguard interfaces are tun anyway, so we aren't lying.
global $ifname;
$ifname = "tunwg0";

function wireguard_generate_privkey() {
$fh = popen("/usr/local/bin/wg genkey 2>/dev/null", "r");
if (!$fh) {
return;
}

$key = trim(stream_get_contents($fh));
pclose($fh);

return $key;
}

function wireguard_generate_pubkey($privkey) {
$fh = popen("echo \"" . $privkey . "\" | /usr/local/bin/wg pubkey 2>/dev/null", "r");
if (!$fh) {
return;
}

$key = trim(stream_get_contents($fh));
pclose($fh);

return $key;
}

function wireguard_generate_psk() {
$fh = popen("/usr/local/bin/wg genpsk 2>/dev/null", "r");
if (!$fh) {
return;
}

$key = trim(stream_get_contents($fh));
pclose($fh);

return $key;
}

function wireguard_validate_interface($post, &$input_errors) {
$address = explode("\r\n", trim($post["address"]));
$listenport = $post["listenport"];
$dns = explode("\r\n", trim($post["dns"]));
$privatekey = $post["privatekey"];
$genkeys = $post["genkeys"];
$mtu = $post["mtu"];

foreach($address as $entry) {
$entry = trim($entry);
if (($entry <> "") && (!is_subnet($entry))) {
$input_errors[] = gettext("{$entry} is not a valid address range for the network.");
}
}

if (($listenport <> "") && (!is_port($listenport))) {
$input_errors[] = gettext("Please enter a valid listen port number, or leave the field blank.");
}

foreach($dns as $entry) {
$entry = trim($entry);
if (($entry <> "") && (!is_ipaddr($entry))) {
$input_errors[] = gettext("{$entry} is not a valid DNS server address.");
}
}

if (($privatekey == "") && (!isset($genkeys))) {
$input_errors[] = gettext("Please enter a private key, or select the option to generate a new one.");
}

if (($mtu <> "") && ((!ctype_digit($mtu)) || ($mtu < 1))) {
$input_errors[] = gettext("Please enter a valid MTU.");
}
}

function wireguard_validate_peer($post, &$input_errors) {
$endpoint = $post["endpoint"];
$keepalive = $post["keepalive"];
$allowedips = explode("\r\n", trim($post["allowedips"]));

if (($endpoint <> "") && (!is_ipaddrwithport($endpoint)) && (!is_hostnamewithport($endpoint))) {
$input_errors[] = gettext("Please enter a valid endpoint address and port.");
}

foreach($allowedips as $entry) {
$entry = trim($entry);
if (($entry <> "") && (!is_subnet($entry))) {
$input_errors[] = gettext("{$entry} is not a valid address range for allowed IPs.");
}
}

if (($keepalive <> "") && ((!ctype_digit($keepalive)) || (intval($keepalive) < 0) || (intval($keepalive) > 65535))) {
$input_errors[] = gettext("Please enter a valid keepalive value.");
}
}

function wireguard_resync() {
global $config, $configpath, $ifname;
$configpath = "/usr/local/etc/wireguard/{$ifname}.conf";

if (is_array($config['installedpackages']['wireguard']['config'][0])) {
$ifconf = $config['installedpackages']['wireguard']['config'][0];
} else {
$ifconf = array();
}

# See if we need to create new private and public keys for the interface.
if ($ifconf['genkeys']) {
$ifconf['privatekey'] = base64_encode(wireguard_generate_privkey());
$ifconf['publickey'] = base64_encode(wireguard_generate_pubkey(base64_decode($ifconf['privatekey'])));

$config['installedpackages']['wireguard']['config'][0]['privatekey'] = $ifconf['privatekey'];
$config['installedpackages']['wireguard']['config'][0]['publickey'] = $ifconf['publickey'];
$config['installedpackages']['wireguard']['config'][0]['genkeys'] = false;

# Trigger a resync to update the package config again.
write_config("[wireguard] Generated new private/public key pair.");
log_error("[wireguard] Generated new private/public key pair.");
}

# Set up the interface config.
$output = "[Interface]\n";
$output .= "# Generated by pfSense\n";

$address = implode(",", explode("\r\n", base64_decode($ifconf["address"])));
$output .= "Address = {$address}\n";

$listenport = $ifconf["listenport"];
if ($listenport) {
$output .= "ListenPort = {$listenport}\n";
}

$dns = implode(",", explode("\r\n", base64_decode($ifconf["dns"])));
if ($dns) {
$output .= "DNS = {$dns}\n";
}

$privatekey = base64_decode($ifconf["privatekey"]);
$output .= "PrivateKey = {$privatekey}\n";

$table = $ifconf["table"];
if ($table) {
$output .= "Table = {$table}\n";
}

$mtu = $ifconf["mtu"];
if ($mtu) {
$output .= "MTU = {$mtu}\n";
}

$preup = explode("\r\n", base64_decode($ifconf["preup"]));
if ($preup[0] <> "") {
foreach ($preup as $entry) {
$output .= "PreUp = {$entry}\n";
}
}

$postup = explode("\r\n", base64_decode($ifconf["postup"]));
if ($postup[0] <> "") {
foreach ($postup as $entry) {
$output .= "PostUp = {$entry}\n";
}
}

$predown = explode("\r\n", base64_decode($ifconf["predown"]));
if ($predown[0] <> "") {
foreach ($predown as $entry) {
$output .= "PreDown = {$entry}\n";
}
}

$postdown = explode("\r\n", base64_decode($ifconf["postdown"]));
if ($postdown[0] <> "") {
foreach ($postdown as $entry) {
$output .= "PostDown = {$entry}\n";
}
}

$i = 0;
foreach ($config['installedpackages']['wireguardpeers']['config'] as $peerconf) {
# See if we need to create a preshared key for the peer.
if ($peerconf["genpsk"]) {
$peerconf['psk'] = base64_encode(wireguard_generate_psk());

$config['installedpackages']['wireguardpeers']['config'][$i]['psk'] = $peerconf['psk'];
$config['installedpackages']['wireguardpeers']['config'][$i]['genpsk'] = false;

# Trigger a resync to update the package config again.
write_config("[wireguard] Generated new preshared key.");
log_error("[wireguard] Generated new preshared key.");
}

# Set up the peer config.
$output .= "\n[Peer]\n";
$output .= "# {$peerconf['name']}\n";

$endpoint = $peerconf['endpoint'];
if ($endpoint) {
$output .= "Endpoint = {$endpoint}\n";
}

$pubkey = base64_decode($peerconf['publickey']);
$output .= "PublicKey = {$pubkey}\n";

$allowedips = implode(",", explode("\r\n", base64_decode($peerconf["allowedips"])));
$output .= "AllowedIPs = {$allowedips}\n";

$psk = base64_decode($peerconf['psk']);
if ($psk) {
$output .= "PresharedKey = {$psk}\n";
}

$keepalive = $peerconf['keepalive'];
if ($keepalive <> "") {
$output .= "PersistentKeepalive = {$keepalive}\n";
}

$i++;
}

# Write out the config file.
file_put_contents($configpath, $output);
}

function wireguard_write_rcfile() {
global $ifname;
$start = "/usr/local/bin/wg-quick up {$ifname}";
$stop = "/usr/local/bin/wg-quick down {$ifname}";

$rcfile['file'] = 'wireguard.sh';
$rcfile['start'] = $start;
$rcfile['stop'] = $stop;
write_rcfile($rcfile);
unlink_if_exists("/usr/local/etc/rc.d/wireguard");
}

function wireguard_install() {
wireguard_write_rcfile();
}

?>
Loading

0 comments on commit b627492

Please sign in to comment.