diff --git a/README.md b/README.md index fbe60d4..b5ef882 100644 --- a/README.md +++ b/README.md @@ -46,10 +46,23 @@ in the industry. The installation of this add-on is pretty straightforward and not different in comparison to installing any other Hass.io add-on. +This is an installation manual & quick start: + 1. [Add our Hass.io add-ons repository][repository] to your Hass.io instance. 1. Install the "WireGuard" add-on. +1. Set the `host` configuration option to your Hass.io (external) address, + e.g., `myhome.duckdns.org`. +1. Change the name of the peer to something useful, e.g., `myphone`. +1. Save the configuration. 1. Start the "WireGuard" add-on 1. Check the logs of the "WireGuard" add-on to see if everything went well. +1. Forward port `51820` (UDP!) in your router to your Hass.io IP. +1. Download/Open the file `/ssl/wireguard/myphone/qrcode.png` stored on your + Hass.io machine, e.g., using Samba, Visual Studio Code or the Configurator + add-on. +1. Install the WireGuard app on your phone. +1. Add a new WireGuard connection to your phone, by scanning the QR code. +1. Connect! **NOTE**: Do not add this repository to Hass.io, please use: `https://github.com/hassio-addons/repository`. @@ -58,7 +71,17 @@ comparison to installing any other Hass.io add-on. **Note**: _Remember to restart the add-on when the configuration is changed._ -Example add-on configuration: +If you are familiar with WireGuard, please note the following: +The configuration of WireGuard looks very similar to all terms used in the +WireGuard configuration. There is, however, one big difference: The +add-on is able to generate configurations for the add-on, but also for the +peers (clients). + +Furthermore, the add-on takes care of a lot of default settings handling +for you. By default, only some basic settings are shown in the configuration +section of the add-on. However, more WireGuard setting are available! + +An more extensive example add-on configuration, please do not copy paste. ```json { @@ -66,33 +89,210 @@ Example add-on configuration: "server": { "host": "hassio.local", "addresses": [ - "10.200.100.8/24", - "10.10.0.1/16" + "10.10.10.1" ], "dns": [ - "8.8.8.8", - "8.8.4.4" - ], - "private_key": "" + "1.1.1.1", + "1.0.0.1" + ] }, "peers": [ - { - "name": "", - "public_key": "", - "allowed_ips": [ - "0.0.0.0/0" - ], - "persistent_keep_alive": 42, - "endpoint": "demo.wireguard.com:51820", - "pre_shared_key": "" - } + { + "name": "frenck", + "addresses": [ + "10.10.10.2" + ], + "allowed_ips": [], + "client_allowed_ips": [] + } + { + "name": "ninja", + "addresses": [ + "10.10.10.2" + ], + "allowed_ips": [], + "client_allowed_ips": [ + "10.10.10.0/24", + "192.168.1.0/24" + ] + } ] } ``` **Note**: _This is just an example, don't copy and paste it! Create your own!_ -### Option: `log_level` +### Option: `server.host` + +This configuration option is the hostname that your clients will use to connect +to your WireGuard add-on. The `host` is mainly used to generate client +configurations and SHOULD NOT contain a port. If you want to change the port, +use the "Network" section of the add-on configuration. + +Example: `myhome.duckdns.org`, for local testing `hassio.local` will actually +work. + +### Option: `server.addresses` + +A list of IP (ipv4 or ipv6) addresses (optionally with CIDR masks) to be +assigned to the server/add-on interface. + +It is strongly advised to create/use a separate IP address space from your +home network, e.g., if your home network uses `192.168.1.x` then DON'T use +that for the add-on. + +### Option: `server.dns` _(optional)_ + +A list of DNS servers used by the add-on and the configuration generated for +the clients. This configuration option is optional, if no DNS servers are +set, it will use the build-in DNS server from Hass.io. + +If you are running the [AdGuard][adguard] or [Pi-hole][pihole] add-on, you can +add the internal IP address of your Hass.io system to the list. This will +cause your clients to use those. What this does, it effectively making your +client (e.g., your mobile phone) having ad-filtering, while not at home. + +### Option: `server.private_key` _(optional)_ + +Allows you to provide your own base64 private key generated by `wg genkey`. +This option supports the use of `!secret`. If you don't supply one, +the add-on will generate one for you and store it in: +`/ssl/wireguard/private_key`. + +### Option: `server.public_key` _(optional)_ + +Allows you to provide your own a base64 public key calculated by `wg pubkey` +from a private key. This option supports the use of `!secret`. + +If you don't supply one, the add-on will calculate one based on the private +key that was supplied via the `server.private_key` or, in case no private key +was supplied, calculated it from the generated private key. + +### Option: `server.post_up` _(optional)_ + +Allows you to run commands after WireGuard has been started. This is useful +for modifing things like routing. If not provided, the add-on will by default +route all traffic coming in from the VPN through your home network. + +If you like to disable that, setting this option to `true` (yes, true), will +disable that behaviour. + +By default it executes the following: + +`iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE` + +### Option: `server.post_down` _(optional)_ + +Allows you to run commands after WireGuard has been stopped. This is useful +for modifing things like routing. If not provided, the add-on will by default +remove the default rules created by the `post_up` defaults. + +If you like to disable that, setting this option to `true` (yes, true), will +disable that behaviour. + +By default it executes the following: + +`iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE` + +### Option: `peers.name` + +This is an identifier for you. It helps you to know what this peer is, e.g., +`myphone`, `mylaptop`, `ninja`. + +This name is also used for creating the directory in `/ssl/wireguard` where +the generated client configuration and QR codes are stored. Therefor, a name +has a maximum of 32 characters, can only contains A-Z (or a-z) and 0-9. +Names contain a hyphen (-) but must not start or end with one. + +### Option: `peers.addresses` + +A list of IP (ipv4 or ipv6) addresses (optionally with CIDR masks) to be +assigned to the peer. + +This is used in the client configuration, but also for used by the add-on to +set the allowed IPs (unless override by the `peers.allowed_ips` option.) + +### Option: `peers.private_key` _(optional)_ + +Allows you to provide your own base64 private key generated by `wg genkey` for +the peer. This option supports the use of `!secret`. + +Technically, the add-on does not need this, however, since the add-on can +generate client configurations, it can be helpful. + +If no private key and no public key is provided, the add-on will generate one +for you and store it in: `/ssl/wireguard//`. + +### Option: `peers.public_key` _(optional)_ + +Allows you to provide your own a base64 public key calculated by `wg pubkey` +from a private key. This option supports the use of `!secret`. + +If you don't supply one, the add-on will calculate one based on the private +key that was supplied via the `peer.private_key` or, in case no private key +was supplied, calculated it from the generated private key for this peer. + +### Option: `peers.allowed_ips` _(optional)_ + +**This configuration only valid for the add-on/server end and does not +affect client configurations.!** + +A list of IPs (ipv4 or ipv6) addresses (optionally with CIDR masks) from which +incoming traffic for this peer is allowed and to which outgoing traffic for +this peer is directed. + +If there are no IP addresses configured, the add-on will use the addresses +listed in `peers.addresses`. + +The catch-all `0.0.0.0/0` may be specified for matching all IPv4 addresses, +and `::/0` may be specified for matching all IPv6 addresses. + +### Option: `peers.client_allowed_ips` _(optional)_ + +**This configuration only valid for the peer end/client configuration and does +not affect the server/add-on!** + +A list of IPs (ipv4 or ipv6) addresses (optionally with CIDR masks) from which +incoming traffic from the server is allowed and to which outgoing traffic for +this peer is directed. + +The catch-all `0.0.0.0/0` may be specified for matching all IPv4 addresses, +and `::/0` may be specified for matching all IPv6 addresses. + +If not configured, the add-on will use `0.0.0.0/0` in the generate client +configuration, routing all traffic on your client though the VPN tunnel. + +### Option: `peers.persistent_keep_alive` _(optional)_ + +A seconds interval, between 1 and 65535 inclusive, of how often to send an +authenticated empty packet to the peer for the purpose of keeping a stateful +firewall or NAT mapping valid persistently. + +For example, if the interface very rarely sends traffic, but it might at +anytime receive traffic from a peer, and it is behind NAT, the interface might +benefit from having a persistent keepalive interval of 25 seconds. + +If set to 0 or "off", this option is disabled. + +By default or when unspecified, this option is off. +Most users will not need this. + +### Option: `peers.endpoint` _(optional)_ + +An endpoint IP or hostname, followed by a colon, and then a port number. This +is used by the add-on/server to connect to its peer. + +This is completely optional as the endpoint will be updated automatically +to the most recent source IP address and port of correctly authenticated +packets from the peer/client. + +### Option: `peers.pre_shared_key` _(optional)_ + +A base64 preshared key generated by `wg genpsk`. This option adds an additional +layer of symmetric-key cryptography to be mixed into the already existing +public-key cryptography, for post-quantum resistance. + +### Option: `log_level` _(optional)_ 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 @@ -110,9 +310,90 @@ 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 +## Finding generated client configurations -Some work to do... +All generated files are stored in `/ssl/wireguard`. This includes the +client configurations generated by this add-on. + +Each peer/client will have its own folder, by the name specified in the +add-on configuration. The add-on additionally generates a image for each +client containing a QR code, to allow a quick an easy set up on, e.g., your +mobile phone. + +## Running this add-on on a Generic/Debian/Ubuntu based Hass.io + +The HassOS operating system for Hass.io by default has installed WireGuard +support in its Linux kernel. However, if you run Hass.io on a generic Linux +installation (e.g., based on Ubuntu or Debian), WireGuard support is not +available by default. + +This will cause the add-on to throw a large warning during the start up. +However, the add-on will work as advertised! + +When this happens, the add-on falls back on a standalone instance of WireGuard +running inside the add-on itself. This method has drawback in terms of +performance. + +In order to run WireGuard optimal, you should install WireGuard on your +host system. The add-on will pick that up automatically on the next start. + +### Ubuntu + +```bash +sudo add-apt-repository ppa:wireguard/wireguard +sudo apt-get update +sudo apt-get install wireguard +``` + +### Debian + +```bash +sudo echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list +sudo printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' > /etc/apt/preferences.d/limit-unstable +sudo apt update +sudo apt install wireguard +``` + +### Fedora + +```bash +sudo dnf copr enable jdoss/wireguard +sudo dnf install wireguard-dkms wireguard-tools +``` + +### Other + +If you have a different operating system on which you run Hass.io on, please +consult [WireGuard installation manul][wireguard-install] + +## _"Missing WireGuard kernel module. Falling back to slow userspace implementation."_ + +If you've seen this warning in the add-on logs files, please check the chapter +above for more information. + +## _"IP forwarding is disabled on the host system!"_ + +IP forwarding is the ability for an operating system to accept incoming +network packets on one interface, recognize that it is not meant for the +system itself, but that it should be passed on to another network, +and then forwards it accordingly. + +Basically, it allows for data coming in from your VPN client will be routed to +other places like your home network, or the internet. + +## Snapshots + +The WireGuard add-on can be backed up using Hass.io snapshots. There is one +caveat to take into account: A partial snapshot of the add-on DOES NOT contain +the generated client configurations, including their public/private keys. + +Client configurations are stored in the `/ssl/wireguard` folder. If you +use partial snapshots, please besure to backup both the `ssl` folder and the +add-on. + +## WireGuard status API + +Lorem ipsum. ## Changelog & Releases @@ -223,3 +504,6 @@ SOFTWARE. [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 +[adguard]: https://github.com/hassio-addons/addon-adguard-home +[pihole]: https://github.com/hassio-addons/addon-pi-hole +[wireguard-install]: https://www.wireguard.com/install/ diff --git a/wireguard/rootfs/etc/cont-init.d/config.sh b/wireguard/rootfs/etc/cont-init.d/config.sh index cbce687..6444d4e 100644 --- a/wireguard/rootfs/etc/cont-init.d/config.sh +++ b/wireguard/rootfs/etc/cont-init.d/config.sh @@ -222,13 +222,18 @@ for peer in $(bashio::config 'peers|keys'); do allowed_ips=$(IFS=", "; echo "${list[*]}") fi + # Determine persistent keep alive + keep_alive=25 + if bashio::config.has_value "peers[${peer}].persistent_keep_alive"; then + keep_alive=$(bashio::config "peers[${peer}].persistent_keep_alive") + fi + # Start writing peer information in server config { echo "[Peer]" echo "PublicKey = ${peer_public_key}" echo "AllowedIPs = ${allowed_ips}" - bashio::config.has_value "peers[${peer}].persistent_keep_alive" \ - && echo "PersistentKeepalive = ${keep_alive}" + echo "PersistentKeepalive = ${keep_alive}" bashio::config.has_value "peers[${peer}].pre_shared_key" \ && echo "PreSharedKey = ${pre_shared_key}" bashio::config.has_value "peers[${peer}].endpoint" \ @@ -260,6 +265,7 @@ for peer in $(bashio::config 'peers|keys'); do echo "PublicKey = ${server_public_key}" echo "Endpoint = ${host}:${port}" echo "AllowedIPs = ${allowed_ips}" + echo "PersistentKeepalive = ${keep_alive}" echo "" } > "${config_dir}/client.conf"