diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..ecf9fb5 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,15 @@ +--- +include: https://raw.githubusercontent.com/hassio-addons/organization/master/gitlabci/addon.yml + +variables: + ADDON_GITHUB_REPO: "hassio-addons/addon-wireguard" + ADDON_SLUG: "wireguard" + ADDON_TARGET: "wireguard" + + ADDON_LEGACY_TAGS: "true" + + ADDON_AARCH64_BASE: "hassioaddons/base-aarch64:4.1.1" + ADDON_AMD64_BASE: "hassioaddons/base-amd64:4.1.1" + ADDON_ARMHF_BASE: "hassioaddons/base-armhf:4.1.1" + ADDON_ARMV7_BASE: "hassioaddons/base-armv7:4.1.1" + ADDON_I386_BASE: "hassioaddons/base-i386:4.1.1" diff --git a/README.md b/README.md new file mode 100644 index 0000000..c1b49ff --- /dev/null +++ b/README.md @@ -0,0 +1,225 @@ +# Community Hass.io Add-ons: WireGuard + +[![GitHub Release][releases-shield]][releases] +![Project Stage][project-stage-shield] +[![License][license-shield]](LICENSE.md) + +![Supports armhf Architecture][armhf-shield] +![Supports armv7 Architecture][armv7-shield] +![Supports aarch64 Architecture][aarch64-shield] +![Supports amd64 Architecture][amd64-shield] +![Supports i386 Architecture][i386-shield] + +[![GitLab CI][gitlabci-shield]][gitlabci] +![Project Maintenance][maintenance-shield] +[![GitHub Activity][commits-shield]][commits] + +[![Discord][discord-shield]][discord] +[![Community Forum][forum-shield]][forum] + +[![Buy me a coffee][buymeacoffee-shield]][buymeacoffee] + +[![Support my work on Patreon][patreon-shield]][patreon] + +WireGuard: fast, modern, secure VPN tunnel. + +## About + +WireGuard® is an extremely simple yet fast and modern VPN that utilizes +state-of-the-art cryptography. It aims to be faster, simpler, leaner, +and more useful than IPsec, while avoiding the massive headache. + +It intends to be considerably more performant than OpenVPN. WireGuard is +designed as a general purpose VPN for running on embedded interfaces and +super computers alike, fit for many different circumstances. + +Initially released for the Linux kernel, it is now cross-platform (Windows, +macOS, BSD, iOS, Android) and widely deployable, +including via an Hass.io add-on! + +WireGuard is currently under heavy development, but already it might be +regarded as the most secure, easiest to use, and simplest VPN solution +in the industry. + +## Installation + +The installation of this add-on is pretty straightforward and not different in +comparison to installing any other Hass.io add-on. + +1. [Add our Hass.io add-ons repository][repository] to your Hass.io instance. +2. Install the "WireGuard" add-on. +3. Start the "WireGuard" add-on +4. Check the logs of the "WireGuard" add-on to see if everything went well. + +**NOTE**: Do not add this repository to Hass.io, please use: +`https://github.com/hassio-addons/repository`. + +## Configuration + +**Note**: _Remember to restart the add-on when the configuration is changed._ + +Example add-on configuration: + +```json +{ + "log_level": "info", + "server": { + "host": "hassio.local", + "addresses": [ + "10.200.100.8/24", + "10.10.0.1/16" + ], + "dns": [ + "8.8.8.8", + "8.8.4.4" + ], + "private_key": "" + }, + "peers": [ + { + "name": "", + "public_key": "", + "allowed_ips": [ + "0.0.0.0/0" + ], + "persistent_keep_alive": 42, + "endpoint": "demo.wireguard.com:51820", + "pre_shared_key": "" + } + ] +} +``` + +**Note**: _This is just an example, don't copy and paste it! Create your own!_ + +### Option: `log_level` + +The `log_level` option controls the level of log output by the addon and can +be changed to be more or less verbose, which might be useful when you are +dealing with an unknown issue. Possible values are: + +- `trace`: Show every detail, like all called internal functions. +- `debug`: Shows detailed debug information. +- `info`: Normal (usually) interesting events. +- `warning`: Exceptional occurrences that are not errors. +- `error`: Runtime errors that do not require immediate action. +- `fatal`: Something went terribly wrong. Add-on becomes unusable. + +Please note that each level automatically includes log messages from a +more severe level, e.g., `debug` also shows `info` messages. By default, +the `log_level` is set to `info`, which is the recommended setting unless +you are troubleshooting. + +## TODO: Document all configuration options + +Some work to do... + +## Changelog & Releases + +This repository keeps a change log using [GitHub's releases][releases] +functionality. The format of the log is based on +[Keep a Changelog][keepchangelog]. + +Releases are based on [Semantic Versioning][semver], and use the format +of ``MAJOR.MINOR.PATCH``. In a nutshell, the version will be incremented +based on the following: + +- ``MAJOR``: Incompatible or major changes. +- ``MINOR``: Backwards-compatible new features and enhancements. +- ``PATCH``: Backwards-compatible bugfixes and package updates. + +## Support + +Got questions? + +You have several options to get them answered: + +- The [Community Hass.io Add-ons Discord chat server][discord] for add-on + support and feature requests. +- The [Home Assistant Discord chat server][discord-ha] for general Home + Assistant discussions and questions. +- The Home Assistant [Community Forum][forum]. +- Join the [Reddit subreddit][reddit] in [/r/homeassistant][reddit] + +You could also [open an issue here][issue] GitHub. + +## Contributing + +This is an active open-source project. We are always open to people who want to +use the code or contribute to it. + +We have set up a separate document containing our +[contribution guidelines](CONTRIBUTING.md). + +Thank you for being involved! :heart_eyes: + +## Authors & contributors + +The original setup of this repository is by [Franck Nijhof][frenck]. + +For a full list of all authors and contributors, +check [the contributor's page][contributors]. + +## We have got some Hass.io add-ons for you + +Want some more functionality to your Hass.io Home Assistant instance? + +We have created multiple add-ons for Hass.io. For a full list, check out +our [GitHub Repository][repository]. + +## License + +MIT License + +Copyright (c) 2019 Franck Nijhof + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +[aarch64-shield]: https://img.shields.io/badge/aarch64-yes-green.svg +[amd64-shield]: https://img.shields.io/badge/amd64-yes-green.svg +[armhf-shield]: https://img.shields.io/badge/armhf-yes-green.svg +[armv7-shield]: https://img.shields.io/badge/armv7-yes-green.svg +[buymeacoffee-shield]: https://www.buymeacoffee.com/assets/img/guidelines/download-assets-sm-2.svg +[buymeacoffee]: https://www.buymeacoffee.com/frenck +[commits-shield]: https://img.shields.io/github/commit-activity/y/hassio-addons/addon-wireguard.svg +[commits]: https://github.com/hassio-addons/addon-wireguard/commits/master +[contributors]: https://github.com/hassio-addons/addon-wireguard/graphs/contributors +[discord-ha]: https://discord.gg/c5DvZ4e +[discord-shield]: https://img.shields.io/discord/478094546522079232.svg +[discord]: https://discord.me/hassioaddons +[dockerhub]: https://hub.docker.com/r/hassioaddons/wireguard +[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg +[forum]: https://community.home-assistant.io/?u=frenck +[frenck]: https://github.com/frenck +[gitlabci-shield]: https://gitlab.com/hassio-addons/addon-wireguard/badges/master/pipeline.svg +[gitlabci]: https://gitlab.com/hassio-addons/addon-wireguard/pipelines +[home-assistant]: https://home-assistant.io +[i386-shield]: https://img.shields.io/badge/i386-yes-green.svg +[issue]: https://github.com/hassio-addons/addon-wireguard/issues +[keepchangelog]: http://keepachangelog.com/en/1.0.0/ +[license-shield]: https://img.shields.io/github/license/hassio-addons/addon-wireguard.svg +[maintenance-shield]: https://img.shields.io/maintenance/yes/2019.svg +[patreon-shield]: https://www.frenck.nl/images/patreon.png +[patreon]: https://www.patreon.com/ +[project-stage-shield]: https://img.shields.io/badge/project%20stage-experimental-yellow.svg +[reddit]: https://reddit.com/r/homeassistant +[releases-shield]: https://img.shields.io/github/release/hassio-addons/addon-wireguard.svg +[releases]: https://github.com/hassio-addons/addon-wireguard/releases +[repository]: https://github.com/hassio-addons/repository +[semver]: http://semver.org/spec/v2.0.0.htm diff --git a/wireguard/.README.j2 b/wireguard/.README.j2 new file mode 100644 index 0000000..61e3d10 --- /dev/null +++ b/wireguard/.README.j2 @@ -0,0 +1,84 @@ +# Community Hass.io Add-ons: WireGuard + +[![Release][release-shield]][release] ![Project Stage][project-stage-shield] ![Project Maintenance][maintenance-shield] + +[![Discord][discord-shield]][discord] [![Community Forum][forum-shield]][forum] + +[![Buy me a coffee][buymeacoffee-shield]][buymeacoffee] + +[![Support my work on Patreon][patreon-shield]][patreon] + +WireGuard: fast, modern, secure VPN tunnel. + +## About + +WireGuard® is an extremely simple yet fast and modern VPN that utilizes +state-of-the-art cryptography. It aims to be faster, simpler, leaner, +and more useful than IPsec, while avoiding the massive headache. + +It intends to be considerably more performant than OpenVPN. WireGuard is +designed as a general purpose VPN for running on embedded interfaces and +super computers alike, fit for many different circumstances. + +Initially released for the Linux kernel, it is now cross-platform (Windows, +macOS, BSD, iOS, Android) and widely deployable, +including via an Hass.io add-on! + +WireGuard is currently under heavy development, but already it might be +regarded as the most secure, easiest to use, and simplest VPN solution +in the industry. + +[Click here for the full documentation][docs] + +{% if channel == "edge" %} +## WARNING! THIS IS AN EDGE VERSION! + +This Hass.io Add-ons repository contains edge builds of add-ons. Edge builds +add-ons are based upon the latest development version. + +- They may not work at all. +- They might stop working at any time. +- They could have a negative impact on your system. + +This repository was created for: + +- Anybody willing to test. +- Anybody interested in trying out upcoming add-ons or add-on features. +- Developers. + +If you are more interested in stable releases of our add-ons: + + + +{% endif %} +{% if channel == "beta" %} +## WARNING! THIS IS A BETA VERSION! + +This Hass.io Add-ons repository contains beta releases of add-ons. + +- They might stop working at any time. +- They could have a negative impact on your system. + +This repository was created for: + +- Anybody willing to test. +- Anybody interested in trying out upcoming add-ons or add-on features. + +If you are more interested in stable releases of our add-ons: + + + +{% endif %} +[buymeacoffee-shield]: https://www.buymeacoffee.com/assets/img/guidelines/download-assets-sm-2.svg +[buymeacoffee]: https://www.buymeacoffee.com/frenck +[discord-shield]: https://img.shields.io/discord/478094546522079232.svg +[discord]: https://discord.me/hassioaddons +[docs]: {{ repo }}/blob/{{ version }}/README.md +[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg +[forum]: https://community.home-assistant.io/?u=frenck +[maintenance-shield]: https://img.shields.io/maintenance/yes/2019.svg +[patreon-shield]: https://www.frenck.nl/images/patreon.png +[patreon]: https://www.patreon.com/frenck +[project-stage-shield]: https://img.shields.io/badge/project%20stage-experimental-yellow.svg +[release-shield]: https://img.shields.io/badge/version-{{ version }}-blue.svg +[release]: {{ repo }}/tree/{{ version }} diff --git a/wireguard/Dockerfile b/wireguard/Dockerfile new file mode 100755 index 0000000..6d995b9 --- /dev/null +++ b/wireguard/Dockerfile @@ -0,0 +1,55 @@ +ARG BUILD_FROM=hassioaddons/base:4.1.1 +# hadolint ignore=DL3006 +FROM ${BUILD_FROM} + +# Set shell +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +# Setup base +RUN \ + apk add --no-cache --virtual .build-dependencies \ + build-base=0.5-r1 \ + git=2.22.0-r0 \ + \ + && apk add --no-cache \ + go@edge=1.12.8-r0 \ + libqrencode=4.0.2-r0 \ + openresolv=3.9.0-r0 \ + wireguard-tools@edge=0.0.20190601-r1 \ + \ + && git clone --branch "v0.0.20190805" --depth=1 \ + "https://git.zx2c4.com/wireguard-go" /tmp/wireguard \ + \ + && cd /tmp/wireguard \ + && make \ + && make install \ + \ + && rm -f -r /tmp/* \ + && apk del --no-cache --purge .build-dependencies + +# Copy root filesystem +COPY rootfs / + +# Build arguments +ARG BUILD_ARCH +ARG BUILD_DATE +ARG BUILD_REF +ARG BUILD_VERSION + +# Labels +LABEL \ + io.hass.name="WireGuard" \ + io.hass.description="Fast, modern, secure VPN tunnel" \ + io.hass.arch="${BUILD_ARCH}" \ + io.hass.type="addon" \ + io.hass.version=${BUILD_VERSION} \ + maintainer="Franck Nijhof " \ + org.label-schema.description="Fast, modern, secure VPN tunnel" \ + org.label-schema.build-date=${BUILD_DATE} \ + org.label-schema.name="WireGuard" \ + org.label-schema.schema-version="1.0" \ + org.label-schema.url="https://community.home-assistant.io/?u=frenck" \ + org.label-schema.usage="https://github.com/hassio-addons/addon-wireguard/tree/master/README.md" \ + org.label-schema.vcs-ref=${BUILD_REF} \ + org.label-schema.vcs-url="https://github.com/hassio-addons/addon-wireguard" \ + org.label-schema.vendor="Community Hass.io Add-ons" diff --git a/wireguard/build.json b/wireguard/build.json new file mode 100644 index 0000000..8c31243 --- /dev/null +++ b/wireguard/build.json @@ -0,0 +1,10 @@ +{ + "build_from": { + "aarch64": "hassioaddons/base-aarch64:4.1.1", + "amd64": "hassioaddons/base-amd64:4.1.1", + "armhf": "hassioaddons/base-armhf:4.1.1", + "armv7": "hassioaddons/base-armv7:4.1.1", + "i386": "hassioaddons/base-i386:4.1.1" + }, + "args": {} +} diff --git a/wireguard/config.json b/wireguard/config.json new file mode 100755 index 0000000..9aa6317 --- /dev/null +++ b/wireguard/config.json @@ -0,0 +1,75 @@ +{ + "name": "WireGuard", + "version": "dev", + "slug": "wireguard", + "description": "Fast, modern, secure VPN tunnel", + "url": "https://github.com/hassio-addons/addon-wireguard", + "startup": "application", + "arch": [ + "aarch64", + "amd64", + "armhf", + "armv7", + "i386" + ], + "ports": { + "51820/udp": 51820 + }, + "boot": "auto", + "hassio_api": true, + "hassio_role": "default", + "privileged": [ + "NET_ADMIN" + ], + "devices": [ + "/dev/net/tun:/dev/net/tun:rwm" + ], + "map": [ + "config", + "ssl:rw" + ], + "options": { + "server": { + "host": "hassio.local", + "addresses": [ + "10.200.100.8/24", + "10.10.0.1/16" + ], + "dns": [ + "8.8.8.8", + "8.8.4.4" + ] + }, + "peers": [ + { + "name": "", + "addresses": [ + "10.200.100.9/24" + ], + "allowed_ips": [ + "0.0.0.0/0" + ] + } + ] + }, + "schema": { + "log_level": "match(^(trace|debug|info|notice|warning|error|fatal)$)?", + "server": { + "host": "str", + "addresses": ["str"], + "dns": ["str"], + "private_key": "str?" + }, + "peers": [ + { + "name": "match(^!secret [a-zA-Z0-9_\\-]+$|^[a-zA-Z0-9\\d](?:[a-zA-Z0-9\\d]|-(?=[a-zA-Z0-9\\d])){0,32}$)", + "public_key": "str?", + "addresses": ["str"], + "allowed_ips": ["str"], + "persistent_keep_alive": "int?", + "endpoint": "str?", + "pre_shared_key": "str?" + } + ] + } +} diff --git a/wireguard/icon.png b/wireguard/icon.png new file mode 100644 index 0000000..feec0ef Binary files /dev/null and b/wireguard/icon.png differ diff --git a/wireguard/logo.png b/wireguard/logo.png new file mode 100644 index 0000000..296bad4 Binary files /dev/null and b/wireguard/logo.png differ diff --git a/wireguard/rootfs/etc/cont-init.d/config.sh b/wireguard/rootfs/etc/cont-init.d/config.sh new file mode 100644 index 0000000..971b5b9 --- /dev/null +++ b/wireguard/rootfs/etc/cont-init.d/config.sh @@ -0,0 +1,133 @@ +#!/usr/bin/with-contenv bashio +# ============================================================================== +# Community Hass.io Add-ons: WireGuard +# Creates the interface configuration +# ============================================================================== +readonly CONFIG="/etc/wireguard/wg0.conf" +declare addresses +declare allowed_ips +declare config_dir +declare dns +declare endpoint +declare host +declare keep_alive +declare name +declare port +declare pre_shared_key +declare private_key +declare public_key + +echo "[Interface]" > "${CONFIG}" + +# Add all server addresses to the configuration +for address in $(bashio::config 'server.addresses'); do + echo "Address = ${address}" >> "${CONFIG}" +done + +# Add all server DNS addresses to the configuration +for dns in $(bashio::config 'server.dns'); do + echo "DNS = ${dns}" >> "${CONFIG}" +done + +# Add the server's private key to the configuration +if bashio::config.has_value 'server.private_key'; then + private_key=$(bashio::config 'server.private_key') +else + if ! bashio::fs.file_exists '/ssl/wireguard/private_key'; then + umask 077 || bashio::exit.nok "Could not set a proper umask" + wg genkey > /ssl/wireguard/private_key || + bashio::exit.nok "Could not generate private key!" + fi + private_key=$(> "${CONFIG}" + +# Fetch all the peers +for peer in $(bashio::config 'peers|keys'); do + + name=$(bashio::config "peers[${peer}].name") + config_dir="/ssl/wireguard/${name}" + + mkdir -p "${config_dir}" || + bashio::exit.nok "Failed creating client folder for ${name}" + + # Write peer header + echo "[Peer]" >> "${CONFIG}" + + # Get the public key + if bashio::config.has_value "peers[${peer}].public_key"; then + public_key=$(bashio::config "peers[${peer}].public_key") + elif bashio::fs.file_exists "${config_dir}/public_key"; then + public_key=$(<"${config_dir}/public_key") + else + umask 077 || bashio::exit.nok "Could not set a proper umask" + wg genkey > "${config_dir}/private_key" || + bashio::exit.nok "Could not generate private key for ${name}!" + + wg pubkey < "${config_dir}/private_key" > "${config_dir}/public_key" || + bashio::exit.nok "Could not get public key for ${name}!" + + public_key=$(<"${config_dir}/public_key") + fi + + echo "PublicKey = ${public_key}" >> "${CONFIG}" + + # Addresses in peer configuration become AllowedIPS from server side. + allowed_ips=$(bashio::config "peers[${peer}].addresses | join(\", \")") + echo "AllowedIPs = ${allowed_ips}" >> "${CONFIG}" + + if bashio::config.has_value "peers[${peer}].persistent_keep_alive"; then + keep_alive=$(bashio::config "peers[${peer}].persistent_keep_alive") + echo "PersistentKeepalive = ${keep_alive}" >> "${CONFIG}" + fi + + if bashio::config.has_value "peers[${peer}].pre_shared_key"; then + pre_shared_key=$(bashio::config "peers[${peer}].pre_shared_key") + echo "PreSharedKey = ${pre_shared_key}" >> "${CONFIG}" + fi + + if bashio::config.has_value "peers[${peer}].endpoint"; then + endpoint=$(bashio::config "peers[${peer}].endpoint") + echo "Endpoint = ${endpoint}" >> "${CONFIG}" + fi + + # End file with an empty line + echo "" >> "${CONFIG}" + + # Generate client config + echo "[Interface]" > "${config_dir}/client.conf" + + if bashio::fs.file_exists "${config_dir}/private_key"; then + private_key=$(<"${config_dir}/private_key") + echo "PrivateKey = ${private_key}" >> "${config_dir}/client.conf" + fi + + addresses=$(bashio::config "peers[${peer}].addresses | join(\", \")") + dns=$(bashio::config "server.dns | join(\", \")") + public_key=$(wg pubkey < /data/private_key) + host=$(bashio::config 'server.host') + port=$(bashio::addon.port "51820/udp") + allowed_ips=$(bashio::config "peers[${peer}].allowed_ips | join(\", \")") + + { + echo "Address = ${addresses}" + echo "DNS = ${dns}" + echo "" + echo "[Peer]" + echo "PublicKey = ${public_key}" + echo "Endpoint = ${host}:${port}" + echo "AllowedIPs = ${allowed_ips}" + echo "" + } >> "${config_dir}/client.conf" + + qrencode -t PNG -o "${config_dir}/qrcode.png" < "${config_dir}/client.conf" +done diff --git a/wireguard/rootfs/etc/services.d/status/run b/wireguard/rootfs/etc/services.d/status/run new file mode 100644 index 0000000..9dca7ae --- /dev/null +++ b/wireguard/rootfs/etc/services.d/status/run @@ -0,0 +1,8 @@ +#!/usr/bin/with-contenv bashio +# ============================================================================== +# Community Hass.io Add-ons: WireGuard +# Shows current WireGuard status +# ============================================================================== +sleep 15 +bashio::log.info "Requesting current status from WireGuard..." +exec wg show diff --git a/wireguard/rootfs/etc/services.d/wireguard/run b/wireguard/rootfs/etc/services.d/wireguard/run new file mode 100644 index 0000000..44e24c0 --- /dev/null +++ b/wireguard/rootfs/etc/services.d/wireguard/run @@ -0,0 +1,15 @@ +#!/usr/bin/with-contenv bashio +# ============================================================================== +# Community Hass.io Add-ons: WireGuard +# Runs WireGuard +# ============================================================================== +s6-svc -O /var/run/s6/services/wireguard + +bashio::log.info "Starting WireGuard..." + +# This is alpha software. We need to set this to instruct +# WireGuard we are OK to go. +export WG_I_PREFER_BUGGY_USERSPACE_TO_POLISHED_KMOD=1 + +# Run the WireGuard +exec wg-quick up wg0