diff --git a/plinth/modules/wireguard/__init__.py b/plinth/modules/wireguard/__init__.py
new file mode 100644
index 000000000..6656b4cdb
--- /dev/null
+++ b/plinth/modules/wireguard/__init__.py
@@ -0,0 +1,96 @@
+#
+# This file is part of FreedomBox.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+"""
+FreedomBox app for wireguard.
+"""
+
+from django.utils.translation import ugettext_lazy as _
+
+from plinth import app as app_module
+from plinth import cfg, frontpage, menu
+from plinth.modules.firewall.components import Firewall
+from plinth.utils import format_lazy
+
+from .manifest import clients # noqa, pylint: disable=unused-import
+
+
+version = 1
+
+managed_packages = ['wireguard']
+
+name = _('WireGuard')
+
+short_description = _('Virtual Private Network')
+
+description = [
+ _('WireGuard is a fast, modern, secure VPN tunnel.'),
+ format_lazy(
+ _('It can be used to connect to a VPN provider which supports '
+ 'WireGuard, and to route all outgoing traffic from {box_name} '
+ 'through the VPN.'), box_name=_(cfg.box_name)),
+ format_lazy(
+ _('A second use case is to connect a mobile device to {box_name} '
+ 'while travelling. While connected to a public Wi-Fi network, all '
+ 'traffic can be securely relayed through {box_name}.'),
+ box_name=_(cfg.box_name))
+]
+
+clients = clients
+
+port_forwarding_info = [('UDP', 51820)]
+
+app = None
+
+
+class WireguardApp(app_module.App):
+ """FreedomBox app for wireguard."""
+
+ app_id = 'wireguard'
+
+ def __init__(self):
+ """Create components for the app."""
+ super().__init__()
+ menu_item = menu.Menu('menu-wireguard', name, short_description,
+ 'wireguard', 'wireguard:index',
+ parent_url_name='apps')
+ self.add(menu_item)
+
+ shortcut = frontpage.Shortcut(
+ 'shortcut-wireguard', name, short_description=short_description,
+ icon='wireguard', url='/wireguard', clients=clients,
+ login_required=True)
+ self.add(shortcut)
+
+ firewall = Firewall('firewall-wireguard', name,
+ ports=['wireguard-freedombox'], is_external=True)
+ self.add(firewall)
+
+
+def init():
+ """Initialize the module."""
+ global app
+ app = WireguardApp()
+
+ setup_helper = globals()['setup_helper']
+ if setup_helper.get_state() != 'needs-setup' and app.is_enabled():
+ app.set_enabled(True)
+
+
+def setup(helper, old_version=None):
+ """Install and configure the module."""
+ helper.install(managed_packages)
+ helper.call('post', app.enable)
diff --git a/plinth/modules/wireguard/data/etc/plinth/modules-enabled/wireguard b/plinth/modules/wireguard/data/etc/plinth/modules-enabled/wireguard
new file mode 100644
index 000000000..e6d87e33c
--- /dev/null
+++ b/plinth/modules/wireguard/data/etc/plinth/modules-enabled/wireguard
@@ -0,0 +1 @@
+plinth.modules.wireguard
diff --git a/plinth/modules/wireguard/data/usr/lib/firewalld/services/wireguard-freedombox.xml b/plinth/modules/wireguard/data/usr/lib/firewalld/services/wireguard-freedombox.xml
new file mode 100644
index 000000000..9aba2f29e
--- /dev/null
+++ b/plinth/modules/wireguard/data/usr/lib/firewalld/services/wireguard-freedombox.xml
@@ -0,0 +1,6 @@
+
+
+ WireGuard
+ WireGuard is a fast, modern, secure VPN tunnel.
+
+
diff --git a/plinth/modules/wireguard/manifest.py b/plinth/modules/wireguard/manifest.py
new file mode 100644
index 000000000..ac8c286f5
--- /dev/null
+++ b/plinth/modules/wireguard/manifest.py
@@ -0,0 +1,68 @@
+#
+# This file is part of FreedomBox.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+"""
+Application manifest for WireGuard.
+"""
+
+from django.utils.translation import ugettext_lazy as _
+
+from plinth.clients import store_url, validate
+
+_wireguard_package_id = 'com.wireguard.android'
+
+clients = validate([{
+ 'name':
+ _('WireGuard'),
+ 'platforms': [{
+ 'type':
+ 'download',
+ 'os':
+ 'windows',
+ 'url':
+ 'https://download.wireguard.com/windows-client/wireguard-amd64-0.0.23.msi'
+ }, {
+ 'type':
+ 'download',
+ 'os':
+ 'macos',
+ 'url':
+ 'https://itunes.apple.com/us/app/wireguard/id1451685025?ls=1&mt=12'
+ }, {
+ 'type': 'package',
+ 'format': 'deb',
+ 'name': 'wireguard'
+ }, {
+ 'type': 'store',
+ 'os': 'android',
+ 'store_name': 'f-droid',
+ 'url': store_url('f-droid', _wireguard_package_id)
+ }, {
+ 'type': 'store',
+ 'os': 'android',
+ 'store_name': 'google-play',
+ 'url': store_url('google-play', _wireguard_package_id)
+ }, {
+ 'type':
+ 'store',
+ 'os':
+ 'ios',
+ 'store_name':
+ 'app-store',
+ 'url':
+ 'https://itunes.apple.com/us/app/wireguard/id1441195209?ls=1&mt=8'
+ }]
+}])
diff --git a/plinth/modules/wireguard/templates/wireguard.html b/plinth/modules/wireguard/templates/wireguard.html
new file mode 100644
index 000000000..cb59e21d5
--- /dev/null
+++ b/plinth/modules/wireguard/templates/wireguard.html
@@ -0,0 +1,43 @@
+{% extends "app.html" %}
+{% comment %}
+#
+# This file is part of FreedomBox.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+{% endcomment %}
+
+{% load bootstrap %}
+{% load i18n %}
+
+{% block configuration %}
+
{% trans "Server" %}
+
{% trans "Peers allowed to connect to this server" %}
+
{% trans "public key" %}
+
{% trans "last connected time" %}
+
{% trans "edit" %}
+
{% trans "Add Client" %}
+
+
{% trans "Client" %}
+
{% trans "Peer servers that FreedomBox will connect to" %}
+
{% trans "endpoint" %}
+
{% trans "public key" %}
+
{% trans "last connected time" %}
+
{% trans "edit" %}
+
{% trans "No connections to remove servers are configured yet." %}
+
{% trans "Add Server" %}
+
+ {{ block.super }}
+
+{% endblock %}
diff --git a/plinth/modules/wireguard/urls.py b/plinth/modules/wireguard/urls.py
new file mode 100644
index 000000000..7fb96603b
--- /dev/null
+++ b/plinth/modules/wireguard/urls.py
@@ -0,0 +1,27 @@
+#
+# This file is part of FreedomBox.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+"""
+URLs for the wireguard module.
+"""
+
+from django.conf.urls import url
+
+from plinth.modules.wireguard import views
+
+urlpatterns = [
+ url(r'^apps/wireguard/$', views.WireguardView.as_view(), name='index'),
+]
diff --git a/plinth/modules/wireguard/views.py b/plinth/modules/wireguard/views.py
new file mode 100644
index 000000000..7962659ec
--- /dev/null
+++ b/plinth/modules/wireguard/views.py
@@ -0,0 +1,34 @@
+#
+# This file is part of FreedomBox.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+"""
+Views for WireGuard application.
+"""
+
+import plinth.modules.wireguard as wireguard
+from plinth.views import AppView
+
+
+class WireguardView(AppView):
+ """Serve configuration page."""
+ app_id = 'wireguard'
+ clients = wireguard.clients
+ name = wireguard.name
+ description = wireguard.description
+ diagnostics_module_name = 'wireguard'
+ show_status_block = False
+ template_name = 'wireguard.html'
+ port_forwarding_info = wireguard.port_forwarding_info
diff --git a/static/themes/default/icons/wireguard.svg b/static/themes/default/icons/wireguard.svg
new file mode 100644
index 000000000..5e54e35a2
--- /dev/null
+++ b/static/themes/default/icons/wireguard.svg
@@ -0,0 +1,120 @@
+
+
+
+
\ No newline at end of file