Merge pull request #907 from gravitl/feature_v0.12.1_remove_docs

removing docs folder
This commit is contained in:
dcarns 2022-03-17 09:05:39 -04:00 committed by GitHub
commit 8dd65d9cbd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
245 changed files with 2 additions and 41305 deletions

View file

@ -1,6 +1,6 @@
<p align="center">
<img src="netmaker.png" width="75%"><break/>
<img src="./img/netmaker.png" width="75%"><break/>
</p>
<p align="center">
a platform for blazing fast and dynamic virtual networks
@ -45,7 +45,7 @@ a platform for blazing fast and dynamic virtual networks
`wget -qO - https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/nm-quick.sh | sudo bash`
<img src="./docs/images/visit-website.gif" width="50%" /><img src="./docs/images/graph-readme.gif" width="50%" />
<img src="./img/visit-website.gif" width="50%" /><img src="./img/graph-readme.gif" width="50%" />
Upon completion, the logs will display the instructions to connect various devices. These can also be retrieved from the UI under "Access Keys."

View file

@ -1,2 +0,0 @@
FROM nginx:1.19
COPY _build/html /usr/share/nginx/html

View file

@ -1,20 +0,0 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,4 +0,0 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: f5642f0efe1bade3b9e81e56c8b29995
tags: 645f666f9bcd5a90fca523b33c5a78b7

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 409 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 602 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

View file

@ -1,52 +0,0 @@
==========
About
==========
.. image:: images/netmaker-simple.png
:width: 60%
:alt: Netmaker Architecture Diagram
:align: center
What is Netmaker?
==================
Netmaker is a tool for creating and managing virtual overlay networks. If you have at least two machines with internet access which you need to connect with a secure tunnel, Netmaker is for you. If you have thousands of servers spread across multiple locations, data centers, or clouds, Netmaker is also for you. Netmaker connects machines securely, wherever they are.
.. image:: images/mesh-diagram.png
:width: 50%
:alt: WireGuard Mesh
:align: center
Netmaker takes those machines and creates a flat network so that they can all talk to each other easily and securely.
If you're familiar with AWS, it's like a VPC but made up of arbitrary computers. From the machine's perspective, all these other machines are in the same neighborhood, even if they're spread all over the world.
Netmaker has many similarities to Tailscale, ZeroTier, and Nebula. What makes Netmaker different is its speed and flexibility. Netmaker is faster because it uses kernel WireGuard. It is more dynamic because the server and agents are fully configurable, which lets you handle all sorts of different use cases.
How Does Netmaker Work?
=======================
Netmaker relies on WireGuard to create tunnels between machines. At its core, Netmaker is managing WireGuard across machines to create sensible networks. Technically, Netmaker is two things:
- the admin server, called Netmaker
- the agent, called Netclient
As the network manager, you interact with the server to create and manage networks and devices. The server holds configurations for these networks and devices, which are retrieved by the netclients (agent). The server runs an MQTT (message queue) broker for client-server communication.
The netclient is installed on any machine you would like to add to a given network, whether that machine is a VM, Server, or IoT device. The netclient subscribes to the server's MQ broker, and the server tells it how it should configure WireGuard. The client will let the server know when any local changes should be pushed out to the other clients. By doing this across many machines simultaneously, we create a dynamic, fully configurable virtual networks.
The Netmaker server does not typically route traffic. Otherwise, this would be a hub-and-spoke model, which is very slow. Instead, Netmaker just tells the machines on the network how they can reach each other directly. This is called a *full mesh* network and is much faster. Even if the server goes down, as long as none of the existing machines change substantially, your network will still run just fine.
Use Cases for Netmaker
=============================
There are many use cases for Netmaker. In fact, you could probably be using it right now. This list is not all-encompassing, but provides a sample of how you might want to use Netmaker. Guided setup for many of these use cases can be found in the :doc:`Using Netmaker <./usage>` documentation.
0. Automate creation of a WireGuard mesh network
1. Create a flat, secure network between cloud environments and data centers
2. Provide secure access to IoT devices, remote servers, and client sites.
3. Secure a home or office network
4. Add a layer of encryption to an existing network
5. Secure site-to-site connections
6. Manage cryptocurrency proof-of-stake machines
7. Create a dynamic and secure Kubernetes underlay network

View file

@ -1,196 +0,0 @@
=============================================
API Reference
=============================================
API Usage
==========================
Most actions that can be performed via API can be performed via UI. We recommend managing your networks using the official netmaker-ui project. However, Netmaker can also be run without the UI, and all functions can be achieved via API calls. If your use case requires using Netmaker without the UI or you need to do some troubleshooting/advanced configuration, using the API directly may help.
Authentication
==============
API calls must be authenticated via a header of the format `-H "Authorization: Bearer <YOUR_SECRET_KEY>"` There are two methods to obtain YOUR_SECRET_KEY:
1. Using the masterkey. By default, this value is "secret key," but you should change this on your instance and keep it secure. This value can be set via env var at startup or in a config file (config/environments/< env >.yaml). See the [general usage](./USAGE.md) documentation for more details.
2. Using a JWT received for a node. This can be retrieved by calling the `/api/nodes/<network>/authenticate` endpoint, as documented below.
Format of Calls for Curl
========================
Requests take the format of
.. code-block::
curl -H "Authorization: Bearer <YOUR_SECRET_KEY>" -H 'Content-Type: application/json' localhost:8081/api/path/to/endpoint
API Documentation
=================
Networks API
------------
**Get All Networks:** `/api/networks`, `GET`
**Create Network:** `/api/network`, `POST`
**Get Network:** `/api/networks/{network id}`, `GET`
**Update Network:** `/api/networks/{network id}`, `PUT`
**Delete Network:** `/api/networks/{network id}`, `DELETE`
**Cycle PublicKeys on all Nodes:** `/api/networks/{network id}/keyupdate`, `POST`
Networks API Call Examples
--------------------------
.. code-block::
Get All Networks: curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks | jq
Create Network: curl -d '{"addressrange":"10.70.0.0/16","netid":"skynet"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks
Get Network: curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet | jq
Update Network: curl -X PUT -d '{"displayname":"my-house"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks/skynet
Delete Network: curl -X DELETE -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet
Cycle PublicKeys on all Nodes: curl -X POST -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keyupdate
Access Keys API
---------------
**Get All Keys:** `/api/networks/{network id}/keys`, `GET`
**Create Key:** `/api/networks/{network id}/keys`, `GET`
**Delete Key:** `/api/networks/{network id}/keys/{keyname}`, `DELETE`
Access Keys API Call Examples
-----------------------------
.. code-block::
Get All Keys: curl -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keys | jq
Create Key: curl -d '{"uses":10,"name":"mykey"}' -H "Authorization: Bearer YOUR_SECRET_KEY" -H 'Content-Type: application/json' localhost:8081/api/networks/skynet/keys
Delete Key: curl -X DELETE -H "Authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/networks/skynet/keys/mykey
Nodes API
---------
**Get All Nodes:** `/api/nodes`, `GET`
**Get Network Nodes:** `/api/nodes/{network id}`, `GET`
**Create Node:** `/api/nodes/{network id}`, `POST`
**Get Node:** `/api/nodes/{network id}/{macaddress}`, `GET`
**Update Node:** `/api/nodes/{network id}/{macaddress}`, `PUT`
**Delete Node:** `/api/nodes/{network id}/{macaddress}`, `DELETE`
**Check In Node:** `/api/nodes/{network id}/{macaddress}/checkin`, `POST`
**Create a Gateway:** `/api/nodes/{network id}/{macaddress}/creategateway`, `POST`
**Delete a Gateway:** `/api/nodes/{network id}/{macaddress}/deletegateway`, `DELETE`
**Uncordon (Approve) a Pending Node:** `/api/nodes/{network id}/{macaddress}/uncordon`, `POST`
**Get Last Modified Date (Last Modified Node in Network):** `/api/nodes/adm/{network id}/lastmodified`, `GET`
**Authenticate:** `/api/nodes/adm/{network id}/authenticate`, `POST`
Nodes API Call Examples
-----------------------
.. code-block::
Get All Nodes: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes | jq
Get Network Nodes: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes/skynet | jq
Create Node: curl -d '{ "endpoint": 100.200.100.200, "publickey": aorijqalrik3ajflaqrdajhkr,"macaddress": "8c:90:b5:06:f1:d9","password": "reallysecret","localaddress": "172.16.16.1","accesskey": "aA3bVG0rnItIRXDx","listenport": 6400}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet
Get Node: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/nodes/skynet/{macaddress} | jq
Update Node: curl -X PUT -d '{"name":"laptop1"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9
Delete Node: curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/skynet/nodes/8c:90:b5:06:f1:d9
Create a Gateway: curl -d '{ "rangestring": "172.31.0.0/16", "interface": "eth0"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/creategateway
Delete a Gateway: curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/deletegateway
Approve a Pending Node: curl -X POST -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/skynet/8c:90:b5:06:f1:d9/approve
Get Last Modified Date (Last Modified Node in Network): curl -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/nodes/adm/skynet/lastmodified
Authenticate: curl -d '{"macaddress": "8c:90:b5:06:f1:d9", "password": "YOUR_PASSWORD"}' -H 'Content-Type: application/json' localhost:8081/api/nodes/adm/skynet/authenticate
Users API
-----------------------
**Note:** Only able to create Admin user at this time. The "user" is only used by the `user interface <https://github.com/gravitl/netmaker-ui>`_ to authenticate the single admin user.
**Get User:** `/api/users/{username}`, `GET`
**Update User:** `/api/users/{username}`, `PUT`
**Delete User:** `/api/users/{username}`, `DELETE`
**Check for Admin User:** `/api/users/adm/hasadmin`, `GET`
**Create Admin User:** `/api/users/adm/createadmin`, `POST`
**Authenticate:** `/api/users/adm/authenticate`, `POST`
Users API Calls Examples
------------------------
.. code-block::
Get User: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/users/{username} | jq
Update User: curl -X PUT -d '{"password":"noonewillguessthis"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/{username}
Delete User: curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/{username}
Check for Admin User: curl -H "Authorization: Bearer YOUR_SECRET_KEY" http://localhost:8081/api/users/adm/hasadmin
Create Admin User: curl -d '{ "username": "smartguy", "password": "YOUR_PASS"}' -H 'Content-Type: application/json' -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/users/adm/createadmin
Authenticate: curl -d '{"username": "smartguy", "password": "YOUR_PASS"}' -H 'Content-Type: application/json' localhost:8081/api/nodes/adm/skynet/authenticate
Server Management API
---------------------
The Server Mgmt. API allows you to add and remove the server from networks.
**Add to Network:** `/api/server/addnetwork/{network id}`, `POST`
**Remove from Network:** `/api/server/removenetwork/{network id}`, `DELETE`
**Add to Network:** `curl -X POST -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/server/addnetwork/{network id}`
**Remove from Network:** `curl -X DELETE -H "authorization: Bearer YOUR_SECRET_KEY" localhost:8081/api/server/removenetwork/{network id}`
File Server API
---------------
**Get File:** `/meshclient/files/{filename}`, `GET`
**Example:** `curl localhost:8081/meshclient/files/meshclient`

View file

@ -1,205 +0,0 @@
===============
Architecture
===============
.. image:: images/nm-diagram-3.png
:width: 100%
:alt: Netmaker Architecture Diagram
:align: center
*Pictured Above: A detailed diagram of Netmaker's Architecture.*
Core Concepts
==============
Familiarity with several core concepts will help when you encounter them later on in the documentation.
WireGuard
----------
WireGuard is a relatively new but very important technology which was recently added to the Linux kernel. WireGuard creates very fast but simple encrypted tunnels between devices. From the `WireGuard <https://www.wireguard.com/>`_ website, "it might be regarded as the most secure, easiest to use, and simplest VPN solution in the industry."
Previous solutions like OpenVPN and IPSec are considerably more heavy and complex, while being less performant. All existing VPN tunneling solutions will cause a significant increase in your network latency. WireGuard is the first to achieve near over-the-line network speeds, meaning you see no significant performance impact. With the release of WireGuard, there is little reason to use any other existing tunnel encryption technology.
Mesh Network
-------------
When we refer to a mesh network in these documents we are typically referring to a "full mesh."
.. image:: images/mesh.png
:width: 33%
:alt: Full Mesh Network Diagram
:align: center
A full `mesh network <https://www.bbc.co.uk/bitesize/guides/zr3yb82/revision/2>`_ exists where each machine is able to directly talk to every other machine on the network. For example, on your home network, behind your router, all the computers are likely given private addresses and can reach each other directly.
This is in contrast to a hub-and-spoke network, where each machine must first pass its traffic through a relay server before it can reach other machines.
In certain situations you may either want or need a *partial mesh* network, where only some devices can reach each other directly, and other devices must route their traffic through a relay/gateway. Netmaker can use this model in some use cases where it makes sense. In the diagram at the top of this page, the setup is a partial mesh, because the servers (nodes A-D) are meshed, but then external clients come in via a gateway, and are not meshed.
Mesh networks are generally faster than other topologies, but are also more complicated to set up. WireGuard on its own gives you the means to create encrypted tunnels between devices, but it does not provide a method for setting up a full network. This is where Netmaker comes in.
Netmaker
---------
Netmaker is a platform built off of WireGuard which enables users to create mesh networks between their devices. Netmaker can create both full and partial mesh networks depending on the use case.
When we refer to Netmaker in aggregate, we are typically referring to Netmaker and the netclient, as well as other supporting services such as CoreDNS, rqlite, and UI webserver. There is also almost always a proxy server / LB, which is typically Caddy.
From an end user perspective, they typically interact with the Netmaker UI, or even just run the install script for the netclient on their devices. The other components run in the background invisibly.
Netmaker does a lot of work to set configurations for you, so that you don't have to. This includes things like WireGuard ports, endpoints, public IPs, keys, and peers. Netmaker works to abstract away as much of the network management as possible, so that you can just click to create a network, and click to add a machine to a network. That said, every machine (node) is different, and may require special configuration. That is why, while Netmaker sets practical default settings, everything within Netmaker is fully configurable.
Node
------
A machine in a Netmaker network, which is managed by the Netclient, is referred to as a Node, as you will see in the UI. A Node can be a VM, a bare metal server, a desktop computer, an IoT device, or any other number of internet-connected machines on which the netclient is installed. A node is simply an endpoint in the network, which can send traffic to all the other nodes, and receive traffic from all of the other nodes.
SystemD
-------
SystemD is a system service manager for a wide array of Linux operating systems. Not all Linux distributions have adopted systemd, but, for better or worse, it has become a fairly common standard in the Linux world. That said, any non-Linux operating system will not have systemd, and many Linux/Unix distributionshave alternative system service managers.
Netmaker's netclient, the agent which controls networking on all nodes, can be run as a CLI or as a system daemon. On Linux, it runs as a daemon by default, and this requires systemd. As Netmaker evolves, systemd will become just one of the possible service management options, allowing the netclient to be run on a wider array of devices. However, for the time being, the netclient should be run "unmanaged" (netclient join -daemon=off) on systems that do not run systemd, and some other method can be used like a cron job or custom script.
As of 0.8, Mac and Windows are supported. On these operating systems, netclient launches the daemon using LaunchD and Windows Service, respectively, as opposed to SystemD.
Components
===========
Netmaker consists of several core components, which are explained in high-level technical detail below.
Netmaker Server
------------------
The Netmaker server is, at its core, a golang binary. Source code can be found `on GitHub <https://github.com/gravitl/netmaker>`_. The binary, by itself can be compiled for most systems. If you need to run the Netmaker server on a particular system, it likely can be made to work. In typical deployments, it is run as a Docker container. It can also be run as a systemd service as outlined in the non-docker install guide.
The Netmaker server acts as an API to the front end, and as a GRPC server to the machines in the network. GRPC is much faster and more efficient than standard API calls, which increases the speed of transactions. For this reason, the Netmaker server exposes two ports: The default for the API is 8081, and the default for GRPC is 50051. Either the API or the GRPC server can be disabled on any given Netmaker instance, allowing you to deploy two different servers for managing the API (which is largely for the admin's use) and GRPC (which is largely for the nodes' use).
Most server settings are configurable via a config file, or by environment variables (which take precedence). If the server finds neither of these, it sets sensible defaults, including things like the server's reachable IP, ports, and which "modes" to run in.
These modes include client mode and dns mode. Either of these can be disabled but are enabled by default. Client mode allows you to treat the Netmaker host machine (operating system) as a network Node, installing the netclient and controlling the host network. DNS mode has the server write config settings for CoreDNS, a separate component and nameserver, which picks up the config settings to manage node DNS.
The Netmaker server interacts with either sqlite (default), postgres, or rqlite, a distributed version of sqlite, as its database. This DB holds information about nodes, networks, users, and other important data. This data is configuration data. For the most part, Netmaker serves configuration data to Nodes, telling them how they should configure themselves. The Netclient is the agent that actually does that configuration.
The components of the server are usually proxied via Caddy, or an alternative like Nginx and Traefik. The proxy handles SSL certificates to secure traffic, and routes to the UI, API, and gRPC server.
Netclient
----------------
The netclient is, at its core, a golang binary. Source code can be found in the netclient folder of the Netmaker `GitHub Repository <https://github.com/gravitl/netmaker/tree/master/netclient>`_. The binary, by itself, can be compiled for most systems. However, this binary is designed to manage a certain number of Operating Systems. As of version 0.8, the netclient can be run as a system daemon on linux distributions with systemd, or as an "unmanaged" client on distributions without systemd. The netclient for Windows and Mac will run as a Windows Service or LaunchDaemon, respectively.
The netclient is installed via a simple bash script, which pulls the latest binary and runs 'register' and 'join' commands.
The 'register' command adds a WireGuard tunnel directly to the netmaker server, for all subsequent communication.
The 'join' command attempts to add the machine to the Netmaker network using sensible defaults, which can be overridden with a config file or environment variables. Assuming the netclient has a valid key (or the network allows manual node signup), it will be registered into the Netmaker network, and will be returned necessary configuration details for how to set up its local network.
The netclient then sets up the system daemon (if running in daemon mode), and configures WireGuard. At this point it should be part of the network.
If running in daemon mode, the node subscribes to the MQTT server running with Netmaker, which will send it periodic updates when the network changes. The node will also detect local changes and send them to the server. Any change in configuration will lead to a network update to keep everything in sync. If the node is not running with the in daemon on, it is up to the operator to keep the netclient up-to-date by running regular "pulls" (netclient pull).
This pub-sub system allows Netmaker to create dynamic mesh networks. As nodes are added to, removed from, and modified on the network, other nodes are notified, and make appropriate changes.
Database (sqlite, rqlite, postgres)
-------------------------------------
As of v0.8, Netmaker uses sqlite by default as a database. It can also use PostgreSQL, or rqlite, a distributed (RAFT consensus) database. Netmaker interacts with this database to store and retrieve information about nodes, networks, and users.
Additional database support (besides sqlite and rqlite) is very easy to implement for special use cases. Netmaker uses simple key value lookups to run the networks, and the database was designed to be extensible, so support for key-value stores and other SQL-based databases can be achieved by changing a single file.
Netmaker UI
---------------
The Netmaker UI is a ReactJS-based static website which can be run on top of standard webservers such as Apache and Nginx. Source code can be found `here <https://github.com/gravitl/netmaker-ui>`_. In a typical configuration, the Netmaker UI is run on Nginx as a Docker container.
Netmaker can be used in its entirety without the UI, but the UI makes things a lot easier for most users. It has a sensible flow and layout for managing Networks, Nodes, Access Keys, and DNS.
CoreDNS
--------
Netmaker allows users to provide and manage Private DNS for their nodes. This requires a nameserver, and CoreDNS is the chosen nameserver. CoreDNS is lightweight and extensible. CoreDNS loads dns settings from a simple file, managed by Netmaker, and serves out DNS info for managed nodes. DNS can be tricky, and DNS management is currently only supported on a small set of devices, specifically those running systemd-resolved. However, the Netmaker CoreDNS instance can be added manually as a nameserver to other devices. DNS mode can also be turned off.
Caddy
-------
Caddy is the default proxy for Netmaker if you set it up via Quick Start. Caddy is an extremely simple and docker-friendly proxy, which can be compared to Nginx, Traefik, or HAProxy. We use Caddy by default because of the ease of management, and integration with gRPC. A typical setup for Nginx might take dozens of lines of code, and we need to request and manage SSL certificates separately.
Caddy handles all these things automatically in very few lines of code. You can see our default "Caddyfile" here, which is fed to the container and has all the configuration necessary to configure the proxy for our app:
https://github.com/gravitl/netmaker/blob/master/docker/Caddyfile
Mosquitto Broker (MQTT)
-------------------------
The Moquitto broker is the default MQTT broker that ships with Netmaker, though technically, any MQTT broker should work so long as the correct configuration is applied. The broker enables the establishment of a pub-sub messaging system, whereby clients subscribe to recieve updates. When the server recieves a change (via API/UI/gRPC), it will publish that change to the broker that pushes out the change to the appropriate nodes. In Netmaker, the messages are double encrypted. Once by Golang, and again by sending all messages over a WireGuard tunnel.
External Client
----------------
The external client is simply a manually configured WireGuard connection to your network, which Netmaker helps to manage.
Most machines can run WireGuard. It is fairly simple to set up a WireGuard connection to a single endpoint. It is setting up mesh networks and other topologies like site-to-site which becomes complicated.
Mac, Windows, and Linux are handled natively by the Netclient.
Netmaker can issue "external clients" to handle any devices which are not currently compatible with the netclient, including iPhone, Android, and some Unix distributions. Over time, this list will be eliminated and there may not even be a need for the external client.
External clients hook into a Netmaker network via an "Ingress Gateway," which is configured for a given node and allows traffic to flow into the network.
Technical Process
====================
Below is a high level, step-by-step overview of the flow of communications within Netmaker (assuming Netmaker has already been installed):
1. Admin creates a new network with a subnet, for instance 10.10.10.0/24
2. Admin creates an access key for signing up new nodes
3. Both of the above requests are routed to the server via an API call from the front end
4. Admin runs the netclient install script on any given node (machine).
5. Netclient decodes key, which contains the server location
6. Netclient gathers and sets appropriate information to configure itself as a node: it generates key pairs, gets public and local addresses, and sets a port.
7. Netclient sends this information to the server, authenticating with its access key
8. Netmaker server verifies information and creates the node, setting default values for any missing information, and returns a response.
9. Upon successful registration, Netclient pulls the latest peers list from the server and set up a WireGuard interface
10. Netclient configures itself as a daemon (if joining for the first time) and subscribes to MQ using the server's WireGuard address.
11. Netclient regularly retrieves local information, checking for changes in things like IP and keys. If there is a change, it pushes them to the server.
12. If a change occurs in any other peer, or peers are added/removed, an update will be sent to the Netclient via MQ, and it will re-configure WireGuard.
Compatible Systems for Netclient
==================================
To manage a node manually, the Netclient can be compiled and run for most linux distibutions, with a prerequisite of WireGuard with kernel headers. If the netclient from the release pages does not run natively on your system, you may need to compile the netclient binary directly on the machine from the source code. This may be true for some installations of SUSE, Fedora, and some Debian-based systems. However, if the dependencies are installed on the machine, the netclient should run correctly after being compiled.
Simply clone the repo, cd to netmaker/netclient and run "go build" (Golang must be installed).
The following systems should be operable natively with Netclient in daemon mode:
- Windows
- Mac
- FreeBSD
- OpenWRT
- Fedora
- Ubuntu
- Debian
- Mint
- SUSE
- RHEL
- Raspian.
- Arch
- CentOS
- Fedora CoreOS
To manage DNS (optional), the node must have systemd-resolved. Systems that have this enabled include:
- Arch
- Debian
- Ubuntu
- SUSE
Limitations
=============
Install limitations mostly include platform-specific dependencies. A failed netclient install should display information about which command is failing, or which libraries are missing. This can often be solved via machine upgrade, installing missing dependencies, or setting kernel headers on the machine for WireGuard (e.x.: `Installing Kernel Headers on Debian <https://stackoverflow.com/questions/62356581/wireguard-vpn-how-to-fix-operation-not-supported-if-it-worked-before>`_)

View file

@ -1,209 +0,0 @@
================================
Advanced Client Installation
================================
This document tells you how to install the netclient on machines that will be a part of your Netmaker network, as well as non-compatible systems.
These steps should be run after the Netmaker server has been created and a network has been designated within Netmaker.
Introduction to Netclient
===============================
At its heart, the netclient is a simple CLI for managing access to various WireGuard-based networks. It manages WireGuard on the host system, so that you don't have to. Why is this necessary?
If you are setting up a WireGuard-based virtual network, you must configure each machine with very specific settings, so that every machine can reach it, and it can reach every machine. Any changes to the settings of any one of these machines can break those connections. Any machine that is added, removed, or modified on the network requires reconfiguring every peer in the network. This can be very time consuming.
The netmaker server holds configuration details about every machine in your network and how other machines should connect to it.
The netclient agent connects to the server, pushing and pulling information when the network (or its local configuration) changes.
The netclient agent then configures WireGuard (and other network properties) locally, so that the network stays intact.
Notes on Windows
==================================
If running the netclient on windows, you must download the netclient.exe binary and run it from Powershell as an Administrator.
Windows will by default have firewall rules that prevent inbound connections. If you wish to allow inbound connections from particular peers, use the following command:
``netsh advfirewall firewall add rule name="Allow from <peer private addr>" dir=in action=allow protocol=ANY remoteip=<peer private addr>``
If you want to allow all peers access, but do not want to configure firewall rules for all peers, you can configure access for one peer, and set it as a Relay Server.
Running the install script
----------------------------
Some file locations have issues running the install script, such as running from the root C:/ folder. Users have noted the following locations work well for running the install powershell script:
- `C:/Program Files/wireguard`
- `C:/Windows/System32`
Running netclient commands
----------------------------
If running the netclient manually ("netclient join", "netclient checkin", "netclient pull") it should be run from outside of the installed directory, which will be either:
- `C:/Program Files/netclient`
- `C:/ProgramData/netclient`
It is better to call it from a different directory.
High CPU Utilization
--------------------------
With some versions of WireGuard on Windows, high CPU utilization has been found with the netclient. This is typically due to interaction with the WireGuard GUI component (app). If you're experiencing high CPU utilization, close the WireGuard app. WireGuard will still be running, but the CPU usage should go back down to normal.
Notes on OpenWRT
===========================
Deploying on OpenWRT depends a lot on the version of OpenWRT and the hardware being used. If the primary installer does not work, there are two things you can try:
1. This community-run package for OpenWRT: https://github.com/sbilly/netmaker-openwrt
2. Manual installation:
- download (wget) the netclient package for your hardware from the netclient releases: https://github.com/gravitl/netmaker/releases
- rename to "netclient"
- Run as root from a bash shell on OpenWRT
3. You may experience an issue with the length of the token, which has limits on some OpenWRT shells. If you run into this problem, you can use the following script to convert your token into a "netclient join" command:
- `wget https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/token-convert.sh`
- ./token-convert <token value>
- Run the output on your OpenWRT machine
Modes and System Compatibility
==================================
**Note: If you would like to connect non-Linux/Unix machines to your network such as phones and Windows desktops, please see the documentation on External Clients**
The netclient can be run in a few "modes". System compatibility depends on which modes you intend to use. These modes can be mixed and matched across a network, meaning all machines do not have to run with the same "mode."
CLI
------------
In its simplest form, the netclient can be treated as just a simple, manual, CLI tool, which a user can call to configure the machine. The cli can be compiled from source code to run on most systems, and has already been compiled for x86 and ARM devices.
As a CLI, the netclient should function on any Linux or Unix based system that has the wireguard utility (callable with **wg**) installed.
Daemon
----------
The netclient is intended to be run as a system daemon. This allows it to automatically retrieve and send updates. To do this, the netclient can install itself as a systemd service, or launchd/windows service for Mac or Windows.
If running the netclient on non-systemd linux, it is recommended to manually configure the netclient as a daemon using whatever method is acceptable on the chosen operating system.
Private DNS Management
-----------------------
To manage private DNS, the netclient relies on systemd-resolved (resolvectl). Absent this, it cannot set private DNS for the machine.
A user may choose to manually set a private DNS nameserver of <netmaker server>:53. However, beware, as netmaker sets split dns, and the system must be configured properly. Otherwise, this nameserver may break your local DNS.
Prerequisites
=============
To obtain the netclient, go to the GitHub releases: https://github.com/gravitl/netmaker/releases
**For netclient cli:** Linux/Unix with WireGuard installed (wg command available)
**For netclient daemon:** Systemd Linux + WireGuard
**For Private DNS management:** Resolvectl (systemd-resolved)
Configuration
===============
The CLI has information about all commands and variables. This section shows the "help" output for these commands as well as some additional reference.
CLI Reference
--------------------
``sudo netclient --help``
.. literalinclude:: ./examplecode/netclient-help.txt
:language: YAML
``sudo netclient join --help``
.. literalinclude:: ./examplecode/netclient-join.txt
:language: YAML
Config File Reference
------------------------
There is a config file for each node under /etc/netconfig-<network name>. You can change these values and then set "postchanges" to "true", or go to the CLI and run ``netclient push -n <network>``
.. literalinclude:: ./examplecode/netconfig-example.yml
:language: YAML
Installation
======================
To install netmaker, you need a server token for a particular network, unless you're joining a network that allows manual signup, in which case you can join without a token, but the server will quarantine the machine until the admin approves it.
An admin creates a token in the ACCESS KEYS section of the UI. Upon creating a token, it generates 3 values:
**Access Key:** The secret key to authenticate as a node in the network
**Access Token:** The secret key plus information about how to access the server (addresses, ports), all decoded by the netclient to register with the server
**Install Command:** A short script that will obtain the netclient binary, register with the server, and join the network, all in one
For first time installations, you can run the Install Command. For additional networks, simply run ``netclient join -t <access token>``. The raw access key will not be needed unless there are special circumstances, mostly troubleshooting incorrect information in the token (you can instead manually specify the server location).
Managing Netclient
=====================
Viewing Logs
---------------
**to view current networks**
``netclient list``
**to tail logs**
``journalctl -u netclient``
**to get most recent log run**
``systemctl status netclient``
Re-syncing netclient (basic troubleshooting)
-----------------------------------------------
If the daemon is not running correctly run, try restarting the daemon, or pulling changes directly (don't do both at once)
``systemctl restart netclient``
``sudo netclient pull``
Making Updates
----------------
``vim /etc/netclient/config/netconfig-<network>``
Change any of the variables in this file, and changes will be pushed to the server and processed locally on the next checkin.
For instance, change the private address, endpoint, or name. See above example config file for details
Adding/Removing Networks
---------------------------
``netclient join -t <token>``
Set any of the above flags (netclient join --help) to override settings for joining the network.
If a key is provided (-k), then a token is unnecessary, but grpc, server, ports, and network must all be provided via flags.
Uninstalling
---------------
``netclient uninstall``

View file

@ -1,77 +0,0 @@
===============
Code of Conduct
===============
Our Pledge
==========
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and
orientation.
Our Standards
=============
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
Our Responsibilities
====================
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
Scope
=====
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
Enforcement
===========
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at info@gravitl.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
Attribution
===========
This Code of Conduct is adapted from the `Contributor Covenant <https://contributor-covenant.org>`_, version 1.4,
available `here <https://contributor-covenant.org/version/1/4>`_.

View file

@ -1,96 +0,0 @@
=====================================
Egress Gateway
=====================================
Introduction
===============
.. image:: images/egress1.png
:width: 80%
:alt: Gateway
:align: center
Netmaker allows your clients to reach external networks via an Egress Gateway. The Egress Gateway is a netclient which has been deployed to a server or router with access to a given subnet.
In the netmaker UI, that node is set as an "egress gateway." Range(s) are specified which this node has access to. Once created, all clients (and all new ext clients) in the network will be able to reach those ranges via the gateway.
Configuring an Egress Gateway
==================================
Configuring an Egress Gateway is very straight forward. As a prerequisite, you must know what you are trying to access remotely. For instance:
- a VPC
- a Kubernetes network
- a home network
- an office network
- a data center
After you have determined this, you must next deploy a netclient in a compatible location where the network is accessible. For instance, a Linux server or router in the office, or a Kubernetes worker node. This machine should be stable and relatively static (not expected to change its IP frequently or shut down unexpectedly).
Next, you must determine which interface to use in order to reach the internal network. As an example, lets say there is a machine in the network at 10.10.10.2, and you have deployed the netclient on a different machine. You can run
.. code-block::
ip route get 10.10.10.2
This should return the interface used to reach that address (e.x. "eth2")
Finally, once you have determined the interface, the subnet, and deployed your netclient, you can go to your Netmaker UI and set the node as a gateway.
.. image:: images/egress7.png
:width: 80%
:alt: Gateway
:align: center
At this point simply insert the range(s) into the first field, and the interface name into the second field, and click "create".
.. image:: images/ui-6.jpg
:width: 80%
:alt: Gateway
:align: center
Netmaker will set iptables rules on the node, which will then implement these rules, allowing it to route traffic from the network to the specified range(s).
Use Cases
============
1) Remote Access
-------------------
A common scenario would be to combine this with an "Ingress Gateway" to create a simple method for accessing a home or office network. Such a setup would typically have only two nodes: the ingress and egress gateways. The Ingress Gateway should usually be globally accessible, which makes the Netmaker server itself a good candidate. This means you need only the netmaker server as the Ingress, and one additional machine (in the private network you wish to reach), as the Egress.
.. image:: images/egress2.png
:width: 80%
:alt: Gateway
:align: center
In some scenarios, a single node will act as both ingress and egress! For instance, you can enable acess to a VPC using your Netmaker server, deployed with a public IP. Traffic comes in over the public IP (encrypted of course) and then routes to the VPC subnet via the egress gateway.
.. image:: images/egress3.png
:width: 50%
:alt: Gateway
:align: center
2) VPN / NAT Gateway
-----------------------
Most people think of a VPN as a remote server that keeps your internet traffic secure while you browse the web, or as a tool for accessing internet services in another country,using a VPN server based in that country.
These are not typical use cases for Netmaker, but can be easily enabled.
**The most important note is this: Do not use 0.0.0.0/0 as your egress gateway.** This is how you typically set up a "standard" VPN with WireGuard, however, it will not work with Netmaker. The Netclient specifically ignores gateways that overlap with local ranges (for efficiency ranges). 0.0.0.0 overlaps with everything, so it is always ignored.
Instead, use the following list of ranges:
.. code-block::
0.0.0.0/5,8.0.0.0/7,11.0.0.0/8,12.0.0.0/6,16.0.0.0/4,32.0.0.0/3,64.0.0.0/2,128.0.0.0/3,160.0.0.0/5,168.0.0.0/6,172.0.0.0/12,172.32.0.0/11,172.64.0.0/10,172.128.0.0/9,173.0.0.0/8,174.0.0.0/7,176.0.0.0/4,192.0.0.0/9,192.128.0.0/11,192.160.0.0/13,192.169.0.0/16,192.170.0.0/15,192.172.0.0/14,192.176.0.0/12,192.192.0.0/10,193.0.0.0/8,194.0.0.0/7,196.0.0.0/6,200.0.0.0/5,208.0.0.0/4
This list encompasses the standard "public" network ranges, and ignores the standard "private" network ranges.
Simply paste this list into your "egress gateway ranges" and your clients should begin routing public-facing traffic over the gateway.
.. image:: images/egress5.png
:width: 50%
:alt: Gateway
:align: center

View file

@ -1,77 +0,0 @@
=====================================
Ingress + External Clients
=====================================
Introduction
===============
.. image:: images/ingress1.png
:width: 50%
:alt: Gateway
:align: center
Netmaker allows for "external clients" to reach into a network and access services via an Ingress Gateway. So what is an "external client"? An external client is any machine which cannot or should not be meshed. This can include:
- Phones
- Laptops
- Desktops
An external client is not "managed," meaning it does not automatically pull the latest network configuration, or push changes to its configuration. Instead, it uses a generated WireGuard config file to access the designated **Ingress Gateway**, which **is** a managed server (running netclient). This server then forwards traffic to the appropriate endpoint, acting as a middle-man/relay.
By using this method, you can hook any machine into a netmaker network that can run WireGuard.
It is recommended to run the netclient where compatible, but for all other cases, a machine can be configured as an external client.
Important to note, an external client is not **reachable** by the network, meaning the client can establish connections to other machines, but those machines cannot independently establish a connection back. The External Client method should only be used in use cases where one wishes to access resource running on the virtual network, and **not** for use cases where one wishes to make a resource accessible on the network. For that, use netclient.
Configuring an Ingress Gateway
==================================
External Clients must attach to an Ingress Gateway. By default, your network will not have an ingress gateway. To configure an ingress gateway, you can use any node in your network, but it should have a public IP address (not behind a NAT). Your Netmaker server can be an ingress gateway and makes for a good default choice if you are unsure of which node to select.
.. image:: images/exclient1.png
:width: 80%
:alt: Gateway
:align: center
Adding Clients to a Gateway
=============================
Once you have configured a node as a gateway, you can then add clients to that gateway. Clients will be able to access other nodes in the network just as the gateway node does.
.. image:: images/exclient2.png
:width: 80%
:alt: Gateway
:align: center
After creating a client, you can edit the name to something more logical.
.. image:: images/exclient3.png
:width: 80%
:alt: Gateway
:align: center
Then, you can either download the configuration file directly, or scan the QR code from your phone (assuming you have the WireGuard app installed). It will accept the configuration just as it would accept a typical WireGuard configuration file.
.. image:: images/exclient4.png
:width: 80%
:alt: Gateway
:align: center
Example config file:
.. literalinclude:: ./examplecode/myclient.conf
Your client should now be able to access the network! A client can be invalidated at any time by simply deleting it from the UI.
Configuring DNS for Ext Clients (OPTIONAL)
============================================
If you wish to have a DNS field on your ext clients conf, simply edit the network field as shown below to 1.1.1.1 or 8.8.8.8 for example.
If you do not want DNS on your ext client conf files, simply leave it blank.
.. image:: images/extclient5.png
:width: 80%
:alt: Gateway
:align: center
Important to note, your client automatically adds egress gateway ranges (if any on the same network) to it's allowed IPs.

View file

@ -1,142 +0,0 @@
=================
Getting Started
=================
Once you have Netmaker installed via the :doc:`Quick Install <./quick-start>` guide, you can use this Getting Started guide to help create and manage your first network.
Setup
=================
#. Create your admin user, with a username and password.
#. Login with your new user
#. Create your first network by clicking on Create Network
Create a Network
=================
.. image:: images/create-net.png
:width: 80%
:alt: Create Network Screen
:align: center
This network should have a sensible name (nodes will use it to set their interfaces).
More importantly, it should have a non-overlapping, private address range.
If you are running a small (less than 254 machines) network, and are unsure of which CIDR's to use, you could consider:
- 10.11.12.0/24
- 10.20.30.0/24
- 100.99.98.0/24
Network Settings Description
-------------------------------
The Network creation form has a few fields which may seem unfamiliar. Here is a brief description:
**UDP Hole Punching:** UDP Hole Punching enables the server to perform STUN. This means, when nodes check in, the server will record return addresses and ports. It will then communicate this information to the other nodes when they check in, allowing them to reach their peers more easily. This has two benefits. For one, it%. It also means, you dont usually have to worry about opening up the local firewall for ports (for instance, 51821). **This setting is usually good to turn on, with some noteable exceptions.** This setting cannot be enabled if "client mode" is turned off. This setting can also break peer-to-peer functionality if, for whatever reason, nodes are unable to reach the server.
**Is Local Network:** This is almost always best to leave this turned off and is left for very special circumstances. If you are running a data center or a private WAN, you may want to enable this setting. It defines the range that nodes will set for Endpoints. Usually, Endpoints are just the public IP. But in some cases, you don't want any nodes to be reachable via a public IP, and instead want to use a private range.
**Is Dual Stack:** This setting adds ipv6 private addresses to nodes, in addition to ipv4 addresses. Usually, this is unnecessary, but in some cases, you may have a requirement for ipv6 and can enable this setting.
Once your network is created, you should see that the netmaker server has added itself to the network. From here, you can move on to adding additional nodes to the network.
.. image:: images/netmaker-node.png
:width: 80%
:alt: Node Screen
:align: center
Create a Key
===============
Adding nodes to the network typically requires a key.
#. Click on the ACCESS KEYS tab and select the network you created.
#. Click ADD NEW ACCESS KEY
#. Give it a name (ex: "mykey") and a number of uses (ex: 25)
#. Click CREATE KEY (**Important:** Do not click out of the following screen until you have saved your key details. It will appear only once.)
#. Copy the bottom command under "Your agent install command with access token" and save it somewhere locally. E.x: ``curl -sfL https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/netclient-install.sh | KEY=vm3ow4thatogiwnsla3thsl3894ths sh -``.
.. image:: images/access-key.png
:width: 80%
:alt: Access Key Screen
:align: center
You will use this command to install the netclient on your nodes. There are three different values for three different scenarios:
* The **Access Key** value is the secret string that will allow your node to authenticate with the Netmaker network. This can be used with existing netclient installations where additional configurations (such as setting the server IP manually) may be required. This is not typical. E.g. ``netclient join -k <access key> -s grpc.myserver.com -p 50051``
* The **Access Token** value is a base64 encoded string that contains the server IP and grpc port, as well as the access key. This is decoded by the netclient and can be used with existing netclient installations like this: ``netclient join -t <access token>``. You should use this method for adding a network to a node that is already on a network. For instance, Node A is in the **mynet** network and now you are adding it to **default**.
* The **install command** value is a curl command that can be run on Linux systems. It is a simple script that downloads the netclient binary and runs the install command all in one.
Networks can also be enabled to allow nodes to sign up without keys at all. In this scenario, nodes enter a "pending state" and are not permitted to join the network until an admin approves them.
Deploy Nodes
=================
0. Prereqisite: Every machine on which you install should have wireguard and systemd already installed.
1. SSH to each machine
2. ``sudo su -``
3. **Prerequisite Check:** Every Linux machine on which you run the netclient must have WireGuard and systemd installed
4. For linux machines with SystemD and WireGuard installed, Run the install command, Ex: ``curl -sfL https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/netclient-install.sh | KEY=vm3ow4thatogiwnsla3thsl3894ths sh -``
5. For Mac, Windows, and arch-specific linux distributions (e.g. ARM), `download the appropriate netclient for your system <https://github.com/gravitl/netmaker/releases/tag/latest/>`_ . Then, run "netclient join -t <your token>".
You should get output similar to the below. The netclient retrieves local settings, submits them to the server for processing, and retrieves updated settings. Then it sets the local network configuration. For more information about this process, see the :doc:`client installation <./client-installation>` documentation. If this process failed and you do not see your node in the console (see below), then reference the :doc:`troubleshooting <./troubleshoot>` documentation.
.. image:: images/nc-install-output.png
:width: 80%
:alt: Output from Netclient Install
:align: center
.. image:: images/nm-node-success.png
:width: 80%
:alt: Node Success
:align: center
Repeat the above steps for every machine you would like to add to your network. You can re-use the same install command so long as you do not run out of uses on your access key (after which it will be invalidated and deleted).
Once installed on all nodes, you can test the connection by pinging the private address of any node from any other node.
.. image:: images/ping-node.png
:width: 80%
:alt: Node Success
:align: center
Manage Nodes
===============
Your machines should now be visible in the control pane.
.. image:: images/nodes.png
:width: 80%
:alt: Node Success
:align: center
You can view/modify/delete any node by selecting it in the NODES tab. For instance, you can change the name to something more sensible like "workstation" or "api server". You can also modify network settings here, such as keys or the WireGuard port. These settings will be picked up by the node on its next check in. For more information, see Advanced Configuration in the :doc:`Using Netmaker <./usage>` docs.
.. image:: images/node-details.png
:width: 80%
:alt: Node Success
:align: center
Nodes can be added/removed/modified on the network at any time. Nodes can also be added to multiple Netmaker networks. Any changes will get picked up by any nodes on a given network, and will take aboue ~30 seconds to take effect.
Uninstalling the netclient
=============================
1. To remove your nodes from the default network, run the following on each node: ``sudo netclient leave -n default``
2. To remove the netclient entirely from each node, run ``sudo rm -rf /etc/netclient`` (after running the first step)
Uninstalling Netmaker
===========================
To uninstall Netmaker from the server, simply run ``docker-compose down`` or ``docker-compose down --volumes`` to remove the docker volumes for a future installation.

View file

@ -1,194 +0,0 @@
.. Netmaker documentation master file, created by
sphinx-quickstart on Fri May 14 08:51:40 2021.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
.. image:: images/netmaker.png
:width: 100%
:alt: Netmaker WireGuard
:align: center
=======================================
Welcome to the Netmaker Documentation
=======================================
Netmaker is a platform for creating and managing fast, secure, and dynamic virtual overlay networks using WireGuard.
This documentation covers Netmaker's :doc:`installation <./server-installation>`, :doc:`usage <./usage>`, :doc:`troubleshooting <./support>`, and customization, as well as reference documents for the :doc:`API <./api>`, UI and Agent configuration. All of the `source code <https://github.com/gravitl/netmaker>`_ for Netmaker is on GitHub.
**For Kubernetes-specific guidance, please see the** `Netmaker Kubernetes Documentation. <https://k8s.netmaker.org>`_
About
--------
High-level information about what Netmaker is and how it works.
.. toctree::
:maxdepth: 2
about
architecture
Getting Started
------------------------------------
How to install Netmaker and set up your first network.
.. toctree::
:maxdepth: 2
install
quick-start
getting-started
Ingress, Egress, and Relays
------------------------------
How to give machines outside of the Netmaker network access to network resources via an Ingress Gateway:
.. toctree::
:maxdepth: 2
external-clients
How to give machines inside the Netmaker network access to external network resources via an Egress Gateway:
.. toctree::
:maxdepth: 2
egress-gateway
How to make machines inside the network reachable if they are blocked by NAT/Firewall:
.. toctree::
:maxdepth: 2
relay-server
Kubernetes Documentation
---------------------------
.. toctree::
Kubernetes <https://k8s.netmaker.org>
`Netmaker Kubernetes Documentation <https://k8s.netmaker.org>`_
Advanced Server Installation
-------------------------------
A detailed guide to installing the Netmaker server (API, DB, UI, DNS), and configuration options.
.. toctree::
:maxdepth: 2
server-installation
Advanced Client Installation
--------------------------------
A detailed guide to installing the Netmaker agent (netclient) on devices and configuration options.
.. toctree::
:maxdepth: 2
client-installation
Oauth Configuration
--------------------
A simple guide to configuring OAuth for Netmaker.
.. toctree::
:maxdepth: 2
oauth
External Guides
----------------
A handful of guides for use cases including site-to-site, Kubernetes, private DNS, and more.
.. toctree::
:maxdepth: 2
usage
UI Reference
---------------
A reference document for the Netmaker Server UI, with annotated screenshot detailing each field.
.. toctree::
:maxdepth: 2
ui-reference
API Reference
---------------
A reference document for the Netmaker Server API, and example API calls for various use cases.
.. toctree::
:maxdepth: 1
api
Upgrades
----------------
Upgrading the Netmaker server and clients.
.. toctree::
:maxdepth: 1
upgrades
Troubleshooting
----------------
Help with common Netmaker/netclient issues.
.. toctree::
:maxdepth: 2
troubleshoot
Support
----------------
Where to go for help, and a FAQ.
.. toctree::
:maxdepth: 2
support
Code of Conduct
-----------------
A statement on our expectations and pledge to the community.
.. toctree::
conduct.rst
Licensing
---------------
A link to the Netmaker license.
.. toctree::
license.rst

View file

@ -1,20 +0,0 @@
=========
Install
=========
Choose the install method that makes sense for you.
**For most users, we recommend the** :doc:`Quick Install<./quick-start>` **guide.**
`Trial, PoC, Testing, and Experimenting <https://github.com/gravitl/netmaker/tree/master#get-started-in-5-minutes>`_
:doc:`Quick Install: for general small-to-medium use cases <./quick-start>`
:ref:`Kubernetes Installation <KubeInstall>`
:ref:`Non-Docker (from binary) Install <NoDocker>`
:ref:`Highly Available Installation <HAInstall>`
:doc:`Advanced Install Resources <./server-installation>`

View file

@ -1,6 +0,0 @@
=======
License
=======
Netmaker's source code and all artifacts in this repository are freely available. All versions are published under the Server Side Public License (SSPL), version 1, which can be found `here <https://raw.githubusercontent.com/gravitl/netmaker/master/LICENSE.txt>`_.

View file

@ -1,81 +0,0 @@
====================
Integrating OAuth
====================
Introduction
==============
As of v0.8.5, Netmaker offers integration with the following OAuth providers:
- GitHub
- Google
- Microsoft Azure AD
By integrating with an OAuth provider, your Netmaker users can log in via the provider, rather than the default simple auth.
Configuring your provider
===========================
In order to use OAuth, configure your OAuth provider (GitHub, Google, Azure AD).
You must configure your provider (except for Azure AD) to use the Netmaker Dashboard URI dashboard.<netmaker.base.domain> as the origin URL.
For example: `https://dashboard.netmaker.mydomain.com`
You must configure your provider to use the Netmaker API URI redirect route with the following format: https://api.<netmaker base domain>/api/oauth/callback.
For example: `https://api.netmaker.mydomain.com/api/oauth/callback`
General provider instructions can be found with the following links:
Instructions for GitHub: https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider/#github-auth-provider
Instructions for Google: https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider/#google-auth-provider
Instructions for Microsoft Azure AD: https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider/#microsoft-azure-ad-provider
Configuring Netmaker
======================
After you have configured your OAuth provider, take note of the CLIENT_ID and CLIENT_SECRET. If you are using Azure for oauth, you may also want to note down the Azure tenant ID you wish to use.
Next, Configure Netmaker with the following environment variables. If any are left blank, OAuth will fail.
.. code-block::
AUTH_PROVIDER: "<azure-ad|github|google>"
CLIENT_ID: "<client id of your oauth provider>"
CLIENT_SECRET: "<client secret of your oauth provider>"
SERVER_HTTP_HOST: "api.<netmaker base domain>"
FRONTEND_URL: "https://dashboard.<netmaker base domain>"
AZURE_TENANT: "<only for azure, you may optionally specify the tenant for the OAuth>"
After restarting your server, the Netmaker logs will indicate if the OAuth provider was successfully initialized:
.. code-block::
sudo docker logs netmaker
Once successful, users can click the key symbol on the login page to sign-in with your configured OAuth provider.
.. image:: images/oauth1.png
:width: 80%
:alt: Login Oauth
:align: center
Configuring User Permissions
===============================
All users logging in will have zero permissions on first sign-in. An admin must configure all user permissions.
Admins must navigate to the "Users" screen to configure permissions.
For each user, an admin must specify which networks that user has access to configure. Additionally, an Admin can elevate a user to Admin permissions.
.. image:: images/oauth3.png
:width: 80%
:alt: Edit User 2
:align: center
.. image:: images/oauth2.png
:width: 80%
:alt: Edit User
:align: center

View file

@ -1,155 +0,0 @@
===============
Quick Install
===============
This quick start guide is an **opinionated** guide for getting up and running with Netmaker as quickly as possible.
If just trialing netmaker, you may also want to check out the 3-minute PoC install of Netmaker in the README on GitHub. The following is just a guided version of that script, plus a custom domain (instead of nip.io): https://github.com/gravitl/netmaker .
Introduction
==================
We assume for this installation that you want all of the Netmaker features enabled, you want your server to be secure, and you want your server to be accessible from anywhere.
This instance will not be HA. However, it should comfortably handle around one hundred concurrent clients and support the most common use cases.
If you are deploying for a business or enterprise use case and this setup will not fit your needs, please contact info@gravitl.com, or check out the business subscription plans at https://gravitl.com/plans/business.
By the end of this guide, you will have Netmaker installed on a public VM linked to your custom domain, secured behind a Caddy reverse proxy.
For information about deploying more advanced configurations, see the :doc:`Advanced Installation <./server-installation>` docs.
0. Prerequisites
==================
- **Virtual Machine**
- Preferably from a cloud provider (e.x: DigitalOcean, Linode, AWS, GCP, etc.)
- (We do not recommend Oracle Cloud, as VM's here have been known to cause network interference.)
- Public, static IP
- Min 1GB RAM, 1 CPU (4GB RAM, 2CPU preferred for production installs)
- 2GB+ of storage
- Ubuntu 20.04 Installed
- **Domain**
- A publicly owned domain (e.x. example.com, mysite.biz)
- Permission and access to modify DNS records via DNS service (e.x: Route53)
1. Prepare DNS
================
Create a wildcard A record pointing to the public IP of your VM. As an example, \*.netmaker.example.com.
Caddy will create 3 subdomains with this wildcard, EX:
- dashboard.netmaker.example.com
- api.netmaker.example.com
- grpc.netmaker.example.com
2. Install Dependencies
========================
.. code-block::
ssh root@your-host
sudo apt-get update
sudo apt-get install -y docker.io docker-compose wireguard
At this point you should have all the system dependencies you need.
3. Open Firewall
===============================
Make sure firewall settings are set for Netmaker both on the VM and with your cloud security groups (AWS, GCP, etc).
Make sure the following ports are open both on the VM and in the cloud security groups:
- **443 (tcp):** for Dashboard, REST API, and gRPC
- **80 (tcp):** for LetsEncrypt
- **53 (udp and tcp):** for CoreDNS - This is no longer necessary as of 0.10.0, as by default DNS queries will run over WireGuard.
- **51821-518XX (udp):** for WireGuard - Netmaker needs one port per network, starting with 51821, so open up a range depending on the number of networks you plan on having. For instance, 51821-51830.
.. code-block::
sudo ufw allow proto tcp from any to any port 443 && sudo ufw allow 53/udp && sudo ufw allow 53/tcp && sudo ufw allow 51821:51830/udp
**Again, based on your cloud provider, you may additionally need to set inbound security rules for your server (for instance, on AWS). This will be dependent on your cloud provider. Be sure to check before moving on:**
- allow 443/tcp from all
- allow 80/tcp from all
- (optional) allow 53/udp and 53/tcp from all
- allow 51821-51830/udp from all
4. Install Netmaker
========================
Prepare Docker Compose
------------------------
**Note 1 on COREDNS_IP:** As of 0.10.0, the default installation does not require COREDNS_IP to be set. Queries will run over WireGuard.
**Note 2 on COREDNS_IP:** Depending on your cloud provider, the public IP may not be bound directly to the VM on which you are running. In such cases, CoreDNS cannot bind to this IP, and you should use the IP of the default interface on your machine in place of COREDNS_IP. This command will get you the correct IP for CoreDNS in many cases:
.. code-block::
ip route get 1 | sed -n 's/^.*src \([0-9.]*\) .*$/\1/p'
Now, insert the values for your base (wildcard) domain, public ip, and coredns ip.
.. code-block::
wget -O docker-compose.yml https://raw.githubusercontent.com/gravitl/netmaker/master/compose/docker-compose.contained.yml
sed -i 's/NETMAKER_BASE_DOMAIN/<your base domain>/g' docker-compose.yml
sed -i 's/SERVER_PUBLIC_IP/<your server ip>/g' docker-compose.yml
sed -i 's/COREDNS_IP/<default interface ip>/g' docker-compose.yml
Generate a unique master key and insert it:
.. code-block::
tr -dc A-Za-z0-9 </dev/urandom | head -c 30 ; echo ''
sed -i 's/REPLACE_MASTER_KEY/<your generated key>/g' docker-compose.yml
You may want to save this key for future use with the API.
Prepare Caddy
------------------------
.. code-block::
wget -O /root/Caddyfile https://raw.githubusercontent.com/gravitl/netmaker/master/docker/Caddyfile
sed -i 's/NETMAKER_BASE_DOMAIN/<your base domain>/g' /root/Caddyfile
sed -i 's/YOUR_EMAIL/<your email>/g' /root/Caddyfile
Prepare MQ
------------------------
You must retrieve the MQ configuration file for Mosquitto.
.. code-block::
wget -O /root/mosquitto.conf https://raw.githubusercontent.com/gravitl/netmaker/master/docker/mosquitto.conf
Start Netmaker
----------------
``sudo docker-compose up -d``
navigate to dashboard.<your base domain> to begin using Netmaker.
To troubleshoot issues, start with:
``docker logs netmaker``
Or check out the :doc:`troubleshoooting docs <./troubleshoot>`.

View file

@ -1,36 +0,0 @@
=====================================
Relay Servers
=====================================
Introduction
===============
.. image:: images/relay1.png
:width: 80%
:alt: Relay
:align: center
Sometimes nodes are in hard-to-reach places. Typically this will be due to a CGNAT, Double NAT, or restrictive firewall. In such scenarios, a direct peer-to-peer connection with all other nodes might be impossible.
For this reason, Netmaker has a Relay Server functionality. At any time you may designate a publicly reachable node (such as the Netmaker Server) as a Relay, and tell it which machines it should relay. Then, all traffic routing to and from that machine will go through the relay. This allows you to circumvent the above issues and ensure connectivity when direct measures do not work.
Configuring a Relay
==================================
To create a relay, you can use any node in your network, but it should have a public IP address (not behind a NAT). Your Netmaker server can be a relay server and makes for a good default choice if you are unsure of which node to select.
Simply click the relay button in the nodes list. Then, specify the nodes which it should relay. You can either enter the IP's directly, select from a list, or click "Select All."
.. image:: images/ui-7.jpg
:width: 80%
:alt: Relay
:align: center
If you choose "select all" this essentially turns your network into a hub-and-spoke network. All traffic now routes over the relay node. This can create a bottleneck and slow down your network, but in some scenarios may simplify network operations.
After creation, you can change the list of relayed nodes by clicking "edit node" and editing the list (Field #12 below).
.. image:: images/ui-5.jpg
:width: 40%
:alt: Relay
:align: center

View file

@ -1,641 +0,0 @@
=================================
Advanced Server Installation
=================================
This section outlines installing the Netmaker server, including Netmaker, Netmaker UI, rqlite, and CoreDNS
System Compatibility
====================
Netmaker will require elevated privileges to perform network operations. Netmaker has similar limitations to :doc:`netclient <./client-installation>` (client networking agent).
Typically, Netmaker is run inside of containers (Docker). To run a non-docker installation, you must run the Netmaker binary, CoreDNS binary, database, and a web server directly on the host. Each of these components have their own individual requirements.
The quick install guide is recommended for first-time installs.
The following documents are meant for special cases like Kubernetes and LXC, or for more advanced setups.
Server Configuration Reference
==========================================
Netmaker sets its configuration in the following order of precendence:
1. Defaults
2. Config File
3. Environment Variables
Variable Description
----------------------
VERBOSITY:
**Default:** 0
**Description:** Specify level of logging you would like on the server. Goes up to 3 for debugging.
GRPC_SSL:
**Default:** "off"
**Description:** Specifies if GRPC is going over secure GRPC or SSL. This is a setting for the clients and is passed through the access token. Can be set to "on" and "off". Set to on if SSL is configured for GRPC.
SERVER_API_CONN_STRING
**Default:** ""
**Description:** Allows specification of the string used to connect to the server api. Format: IP:PORT or DOMAIN:PORT. Defaults to SERVER_HOST if not specified.
SERVER_GRPC_CONN_STRING
**Default:** ""
**Description:** Allows specification of the string used to connect to grpc. Format: IP:PORT or DOMAIN:PORT. Defaults to SERVER_HOST if not specified.
SERVER_HOST: *(depreciated, use SERVER_API_CONN_STRING and SERVER_GRPC_CONN_STRING)*
**Default:** Server will perform an IP check and set automatically unless explicitly set, or DISABLE_REMOTE_IP_CHECK is set to true, in which case it defaults to 127.0.0.1
**Description:** Sets the SERVER_HTTP_HOST and SERVER_GRPC_HOST variables if they are unset. The address where traffic comes in.
SERVER_HTTP_HOST: *(depreciated, use SERVER_API_CONN_STRING and SERVER_GRPC_CONN_STRING)*
**Default:** Equals SERVER_HOST if set, "127.0.0.1" if SERVER_HOST is unset.
**Description:** Set to make the HTTP and GRPC functions available via different interfaces/networks.
SERVER_GRPC_HOST: *(depreciated, use SERVER_API_CONN_STRING and SERVER_GRPC_CONN_STRING)*
**Default:** Equals SERVER_HOST if set, "127.0.0.1" if SERVER_HOST is unset.
**Description:** Set to make the HTTP and GRPC functions available via different interfaces/networks.
API_PORT:
**Default:** 8081
**Description:** The HTTP API port for Netmaker. Used for API calls / communication from front end.
GRPC_PORT:
**Default:** 50051
**Description:** The GRPC port for Netmaker. Used for communications from nodes.
MASTER_KEY:
**Default:** "secretkey"
**Description:** The admin master key for accessing the API. Change this in any production installation.
CORS_ALLOWED_ORIGIN:
**Default:** "*"
**Description:** The "allowed origin" for API requests. Change to restrict where API requests can come from.
REST_BACKEND:
**Default:** "on"
**Description:** Enables the REST backend (API running on API_PORT at SERVER_HTTP_HOST). Change to "off" to turn off.
AGENT_BACKEND:
**Default:** "on"
**Description:** Enables the AGENT backend (GRPC running on GRPC_PORT at SERVER_GRPC_HOST). Change to "off" to turn off.
DNS_MODE:
**Default:** "off"
**Description:** Enables DNS Mode, meaning config files will be generated for CoreDNS.
DATABASE:
**Default:** "sqlite"
**Description:** Specify db type to connect with. Currently, options include "sqlite", "rqlite", and "postgres".
SQL_CONN:
**Default:** "http://"
**Description:** Specify the necessary string to connect with your local or remote sql database.
SQL_HOST:
**Default:** "localhost"
**Description:** Host where postgres is running.
SQL_PORT:
**Default:** "5432"
**Description:** port postgres is running.
SQL_DB:
**Default:** "netmaker"
**Description:** DB to use in postgres.
SQL_USER:
**Default:** "postgres"
**Description:** User for posgres.
SQL_PASS:
**Default:** "nopass"
**Description:** Password for postgres.
CLIENT_MODE:
**Default:** "on"
**Description:** Specifies if server should deploy itself as a node (client) in each network. May be turned to "off" for more restricted servers.
RCE:
**Default:** "off"
**Description:** The server enables you to set PostUp and PostDown commands for nodes, which is standard for WireGuard with wg-quick, but is also **Remote Code Execution**, which is a critical vulnerability if the server is exploited. Because of this, it's turned off by default, but if turned on, PostUp and PostDown become editable.
SERVER_GRPC_WIREGUARD
**Depreciated:** no longer in use
DISPLAY_KEYS
**Default:** "on"
**Description:** If "on", will allow you to always show the key values of "access keys". This could be considered a vulnerability, so if turned "off", will only display key values once, and it is up to the users to store the key values locally.
NODE_ID
**Default:** <system mac addres>
**Description:** This setting is used for HA configurations of the server, to identify between different servers. Nodes are given ID's like netmaker-1, netmaker-2, and netmaker-3. If the server is not HA, there is no reason to set this field.
TELEMETRY
**Default:** "on"
**Description:** If "on", the server will send anonymous telemetry data once daily, which is used to improve the product. Data sent includes counts (integer values) for the number of nodes, types of nodes, users, and networks. It also sends the version of the server.
MQ_HOST
**Default:** (public IP of server)
**Description:** The address of the mq server. If running from docker compose it will be "mq". If using "host networking", it will find and detect the IP of the mq container. Otherwise, need to input address. If not set, it will use the public IP of the server. the port 1883 will be appended automatically. This is the expected reachable port for MQ and cannot be changed at this time.
HOST_NETWORK:
**Default:** "off"
**Description:** Whether or not host networking is turned on. Only turn on if configured for host networking (see docker-compose.hostnetwork.yml). Will set host-level settings like iptables and forwarding for MQ.
MANAGE_IPTABLES:
**Default:** "on"
**Description:** # Sets iptables on the machine being managed in order to forward properly from wireguard interface to MQ and other services listed in "port forward services." It's better to leave this on unless you know what you're doing.
PORT_FORWARD_SERVICES:
**Default:** ""
**Description:** Comma-separated list of services for which to configure port forwarding on the machine. Options include "mq,dns,ssh". Typically best to leave mq and dns on. ssh can be removed.'ssh' forwards port 22 over wireguard, enabling ssh to server over wireguard. dns enables private dns over wireguard. mq enables mq.
Config File Reference
-----------------------
A config file may be placed under config/environments/<env-name>.yml. To read this file at runtime, provide the environment variable NETMAKER_ENV at runtime. For instance, dev.yml paired with ENV=dev. Netmaker will load the specified Config file. This allows you to store and manage configurations for different environments. Below is a reference Config File you may use.
.. literalinclude:: ../config/environments/dev.yaml
:language: YAML
Compose File - Annotated
--------------------------------------
All environment variables and options are enabled in this file. It is the equivalent to running the "full install" from the above section. However, all environment variables are included, and are set to the default values provided by Netmaker (if the environment variable was left unset, it would not change the installation). Comments are added to each option to show how you might use it to modify your installation.
.. literalinclude:: ../compose/docker-compose.reference.yml
:language: YAML
Available docker-compose files
---------------------------------
The default options for docker-compose can be found here: https://github.com/gravitl/netmaker/tree/master/compose
The following is a brief description of each:
- `docker-compose.contained.yml <https://github.com/gravitl/netmaker/blob/master/compose/docker-compose.contained.yml>`_ - This is the default docker-compose, used in the quick start and deployment script in the README on GitHub. It deploys Netmaker with all options included (Caddy and CoreDNS) and has "self-contained" netclients, meaning they do not affect host networking.
- `docker-compose.coredns.yml <https://github.com/gravitl/netmaker/blob/master/compose/docker-compose.coredns.yml>`_ - This is a simple compose used to spin up a standalone CoreDNS server. Can be useful if, for instance, you are unning Netmaker on baremetal but need CoreDNS.
- `docker-compose.hostnetwork.yml <https://github.com/gravitl/netmaker/blob/master/compose/docker-compose.hostnetwork.yml>`_ - This is similar to the docker-compose.contained.yml but with a key difference: it has advanced permissions and mounts host volumes to control networking on the host level.
- `docker-compose.nocaddy.yml <https://github.com/gravitl/netmaker/blob/master/compose/docker-compose.nocaddy.yml>`_ -= This is the same as docker-compose.contained.yml but without Caddy, in case you need to use a different proxy like Nginx, Traefik, or HAProxy.
- `docker-compose.nodns.yml <https://github.com/gravitl/netmaker/blob/master/compose/docker-compose.nodns.yml>`_ - This is the same as docker-compose.contained.yml but without CoreDNS, in which case you will not have the Private DNS feature.
- `docker-compose.reference.yml <https://github.com/gravitl/netmaker/blob/master/compose/docker-compose.reference.yml>`_ - This is the same as docker-compose.contained.yml but with all variable options on display and annotated (it's what we show right above this section). Use this to determine which variables you should add or change in your configuration.
- `docker-compose.yml <https://github.com/gravitl/netmaker/blob/master/compose/docker-compose.yml>`_ - This is a renamed docker-compose.contained.yml. It is meant only to act as a placeholder for what we consider the "primary" docker-compose that users should work with.
DNS Mode Setup
====================================
If you plan on running the server in DNS Mode, know that a `CoreDNS Server <https://coredns.io/manual/toc/>`_ will be installed. CoreDNS is a light-weight, fast, and easy-to-configure DNS server. It is recommended to bind CoreDNS to port 53 of the host system, and it will do so by default. The clients will expect the nameserver to be on port 53, and many systems have issues resolving a different port.
However, on your host system (for Netmaker), this may conflict with an existing process. On linux systems running systemd-resolved, there is likely a service consuming port 53. The below steps will disable systemd-resolved, and replace it with a generic (e.g. Google) nameserver. Be warned that this may have consequences for any existing private DNS configuration.
With the latest docker-compose, it is not necessary to perform these steps. But if you are running the install and find that port 53 is blocked, you can perform the following steps, which were tested on Ubuntu 20.04 (these should be run prior to deploying the docker containers).
.. code-block::
systemctl stop systemd-resolved
systemctl disable systemd-resolved
vim /etc/systemd/resolved.conf
* uncomment DNS and add 8.8.8.8 or whatever reachable nameserver is your preference *
* uncomment DNSStubListener and set to "no" *
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
Port 53 should now be available for CoreDNS to use.
Docker Compose Install
=======================
The most simple (and recommended) way of installing Netmaker is to use one of the provided `Docker Compose files <https://github.com/gravitl/netmaker/tree/master/compose>`_. Below are instructions for several different options to install Netmaker via Docker Compose, followed by an annotated reference Docker Compose in case your use case requires additional customization.
Test Install - No DNS, No Secure GRPC
--------------------------------------------------------
This install will run Netmaker on a server without HTTPS using an IP address. This is not secure and not recommended, but can be helpful for testing.
It also does not run the CoreDNS server, to simplify the deployment
**Prerequisites:**
* server ports 80, 8081, and 50051 are not blocked by firewall
**Notes:**
* You can change the port mappings in the Docker Compose if the listed ports are already in use.
Assuming you have Docker and Docker Compose installed, you can just run the following, replacing **< Insert your-host IP Address Here >** with your host IP (or domain):
.. code-block::
wget -O docker-compose.yml https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/docker-compose.test.yml
sed -i s/HOST_IP/< Insert your-host IP Address Here >/g docker-compose.yml
docker-compose up -d`
Traefik Proxy
------------------------
To install with Traefik, rather than Nginx or the default Caddy, check out this repo: https://github.com/bsherman/netmaker-traefik
No DNS - CoreDNS Disabled
----------------------------------------------
DNS Mode is currently limited to clients that can run resolvectl (systemd-resolved, see :doc:`Architecture docs <./architecture>` for more info). You may wish to disable DNS mode for various reasons. This installation option gives you the full feature set minus CoreDNS.
To run without DNS, follow the :doc:`Quick Install <./quick-start>` guide, omitting the steps for DNS setup. In addition, when the guide has you pull (wget) the Netmaker docker-compose template, use the following link instead:
#. ``wget -O docker-compose.yml https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/docker-compose.nodns.yml``
This template is equivalent but omits CoreDNS.
.. _NoDocker:
Linux Install without Docker
=============================
Most systems support Docker, but some do not. In such environments, there are many options for installing Netmaker. Netmaker is available as a binary file, and there is a zip file of the Netmaker UI static HTML on GitHub. Beyond the UI and Server, you may want to optionally install a database (sqlite is embedded, rqlite or postgres are supported) and CoreDNS (also optional).
Once this is enabled and configured for a domain, you can continue with the below. The recommended server runs Ubuntu 20.04.
Database Setup (optional)
--------------------------
You can run the netmaker binary standalone and it will run an embedded sqlite server. Data goes in the data/ directory. Optionally, you can run PostgreSQL or rqlite. Instructions for rqlite are below.
1. Install rqlite on your server: https://github.com/rqlite/rqlite
2. Run rqlite: rqlited -node-id 1 ~/node.1
If using rqlite or postgres, you must change the DATABASE environment/config variable and enter connection details.
Server Setup
-------------
1. **Run the install script:**
``sudo curl -sfL https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/netmaker-server.sh | sh -``
2. Check status: ``sudo journalctl -u netmaker``
3. If any settings are incorrect such as host or mongo credentials, change them under /etc/netmaker/config/environments/< your env >.yaml and then run ``sudo systemctl restart netmaker``
UI Setup
-----------
The following uses Nginx as an http server. You may alternatively use Apache or any other web server that serves static web files.
1. Download and Unzip UI asset files
2. Copy Config to Nginx
3. Modify Default Config Path
4. Change Backend URL
5. Start Nginx
.. code-block::
sudo wget -O /usr/share/nginx/html/netmaker-ui.zip https://github.com/gravitl/netmaker-ui/releases/download/latest/netmaker-ui.zip
sudo unzip /usr/share/nginx/html/netmaker-ui.zip -d /usr/share/nginx/html
sudo cp /usr/share/nginx/html/nginx.conf /etc/nginx/conf.d/default.conf
sudo sed -i 's/root \/var\/www\/html/root \/usr\/share\/nginx\/html/g' /etc/nginx/sites-available/default
sudo sh -c 'BACKEND_URL=http://<YOUR BACKEND API URL>:PORT /usr/share/nginx/html/generate_config_js.sh >/usr/share/nginx/html/config.js'
sudo systemctl start nginx
CoreDNS Setup (optional)
----------------------------
CoreDNS is only required if you want private DNS features. Once installed, you must set the CoreDNS variables in the env settings of the server.
See https://coredns.io/manual/toc/#installation
Proxy / Load Balancer
------------------------
You will need to proxy connections to your UI and Server. By default the ports are 8081, 8082, and 50051 (grpc). This proxy should handle SSL certificates. We recommend Caddy or Nginx (you can follow the Nginx guide in these docs). The proxy must be able to handle gRPC connections.
.. _KubeInstall:
Kubernetes Install
=======================
Server Install
--------------------------
This template assumes your cluster uses Nginx for ingress with valid wildcard certificates. If using an ingress controller other than Nginx (ex: Traefik), you will need to manually modify the Ingress entries in this template to match your environment.
This template also requires RWX storage. Please change references to storageClassName in this template to your cluster's Storage Class.
``wget https://raw.githubusercontent.com/gravitl/netmaker/master/kube/netmaker-template.yaml``
Replace the NETMAKER_BASE_DOMAIN references to the base domain you would like for your Netmaker services (ui,api,grpc). Typically this will be something like **netmaker.yourwildcard.com**.
``sed -i s/NETMAKER_BASE_DOMAIN/<your base domain>/g netmaker-template.yaml``
Now, assuming Ingress and Storage match correctly with your cluster configuration, you can install Netmaker.
.. code-block::
kubectl create ns nm
kubectl config set-context --current --namespace=nm
kubectl apply -f netmaker-template.yaml -n nm
In about 3 minutes, everything should be up and running:
``kubectl get ingress nm-ui-ingress-nginx``
Netclient Daemonset
--------------------------
The following instructions assume you have Netmaker running and a network you would like to add your cluster into. The Netmaker server does not need to be running inside of a cluster for this.
.. code-block::
wget https://raw.githubusercontent.com/gravitl/netmaker/master/kube/netclient-template.yaml
sed -i s/ACCESS_TOKEN_VALUE/< your access token value>/g netclient-template.yaml
kubectl apply -f netclient-template.yaml
For a more detailed guide on integrating Netmaker with MicroK8s, `check out this guide <https://itnext.io/how-to-deploy-a-cross-cloud-kubernetes-cluster-with-built-in-disaster-recovery-bbce27fcc9d7>`_.
Nginx Reverse Proxy Setup with https
======================================
The `Swag Proxy <https://github.com/linuxserver/docker-swag>`_ makes it easy to generate a valid ssl certificate for the config bellow. Here is the `documentation <https://docs.linuxserver.io/general/swag>`_ for the installation.
The following file configures Netmaker as a subdomain. This config is an adaption from the swag proxy project.
./netmaker.subdomain.conf:
.. code-block:: nginx
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name netmaker.*; # The external URL
client_max_body_size 0;
# A valid https certificate is needed.
include /config/nginx/ssl.conf;
location / {
# This config file can be found at:
# https://github.com/linuxserver/docker-swag/blob/master/root/defaults/proxy.conf
include /config/nginx/proxy.conf;
# if you use a custom resolver to find your app, needed with swag proxy
# resolver 127.0.0.11 valid=30s;
set $upstream_app netmaker-ui; # The internal URL
set $upstream_port 80; # The internal Port
set $upstream_proto http; # the protocol that is being used
proxy_pass $upstream_proto://$upstream_app:$upstream_port; # combine the set variables from above
}
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name backend-netmaker.*; # The external URL
client_max_body_size 0;
underscores_in_headers on;
# A valid https certificate is needed.
include /config/nginx/ssl.conf;
location / {
# if you use a custom resolver to find your app, needed with swag proxy
# resolver 127.0.0.11 valid=30s;
set $upstream_app netmaker; # The internal URL
set $upstream_port 8081; # The internal Port
set $upstream_proto http; # the protocol that is being used
proxy_pass $upstream_proto://$upstream_app:$upstream_port; # combine the set variables from above
# Forces the header to be the one that is visible from the outside
proxy_set_header Host backend.netmaker.example.org; # Please cange to your URL
# Pass all headers through to the backend
proxy_pass_request_headers on;
}
}
.. _HAInstall:
Highly Available Installation (Kubernetes)
==================================================
Netmaker comes with a Helm chart to deploy with High Availability on Kubernetes:
.. code-block::
helm repo add netmaker https://gravitl.github.io/netmaker-helm/
helm repo update
Requirements
---------------
To run HA Netmaker on Kubernetes, your cluster must have the following:
- RWO and RWX Storage Classes (RWX is only required if running Netmaker with DNS Management enabled).
- An Ingress Controller and valid TLS certificates
- This chart can currently generate ingress for Nginx or Traefik Ingress with LetsEncrypt + Cert Manager
- If LetsEncrypt and CertManager are not deployed, you must manually configure certificates for your ingress
Furthermore, the chart will by default install and use a postgresql cluster as its datastore.
Recommended Settings:
----------------------
A minimal HA install of Netmaker can be run with the following command:
`helm install netmaker --generate-name --set baseDomain=nm.example.com`
This install has some notable exceptions:
- Ingress **must** be manually configured post-install (need to create valid Ingress with TLS)
- Server will use "userspace" WireGuard, which is slower than kernel WG
- DNS will be disabled
Example Installations:
------------------------
An annotated install command:
.. code-block::
helm install netmaker/netmaker --generate-name \ # generate a random id for the deploy
--set baseDomain=nm.example.com \ # the base wildcard domain to use for the netmaker api/dashboard/grpc ingress
--set replicas=3 \ # number of server replicas to deploy (3 by default)
--set ingress.enabled=true \ # deploy ingress automatically (requires nginx or traefik and cert-manager + letsencrypt)
--set ingress.className=nginx \ # ingress class to use
--set ingress.tls.issuerName=letsencrypt-prod \ # LetsEncrypt certificate issuer to use
--set dns.enabled=true \ # deploy and enable private DNS management with CoreDNS
--set dns.clusterIP=10.245.75.75 --set dns.RWX.storageClassName=nfs \ # required fields for DNS
--set postgresql-ha.postgresql.replicaCount=2 \ # number of DB replicas to deploy (default 2)
The below command will install netmaker with two server replicas, a coredns server, and ingress with routes of api.nm.example.com, grpc.nm.example.com, and dashboard.nm.example.com. CoreDNS will be reachable at 10.245.75.75, and will use NFS to share a volume with Netmaker (to configure dns entries).
.. code-block::
helm install netmaker/netmaker --generate-name --set baseDomain=nm.example.com \
--set replicas=2 --set ingress.enabled=true --set dns.enabled=true \
--set dns.clusterIP=10.245.75.75 --set dns.RWX.storageClassName=nfs \
--set ingress.className=nginx
The below command will install netmaker with three server replicas (the default), **no coredns**, and ingress with routes of api.netmaker.example.com, grpc.netmaker.example.com, and dashboard.netmaker.example.com. There will be one UI replica instead of two, and one database instance instead of two. Traefik will look for a ClusterIssuer named "le-prod-2" to get valid certificates for the ingress.
.. code-block::
helm3 install netmaker/netmaker --generate-name \
--set baseDomain=netmaker.example.com --set postgresql-ha.postgresql.replicaCount=1 \
--set ui.replicas=1 --set ingress.enabled=true \
--set ingress.tls.issuerName=le-prod-2 --set ingress.className=traefik
Below, we discuss the considerations for Ingress, Kernel WireGuard, and DNS.
Ingress
----------
To run HA Netmaker, you must have ingress installed and enabled on your cluster with valid TLS certificates (not self-signed). If you are running Nginx as your Ingress Controller and LetsEncrypt for TLS certificate management, you can run the helm install with the following settings:
- `--set ingress.enabled=true`
- `--set ingress.annotations.cert-manager.io/cluster-issuer=<your LE issuer name>`
If you are not using Nginx or Traefik and LetsEncrypt, we recommend leaving ingress.enabled=false (default), and then manually creating the ingress objects post-install. You will need three ingress objects with TLS:
- `dashboard.<baseDomain>`
- `api.<baseDomain>`
- `grpc.<baseDomain>`
If deploying manually, the gRPC ingress object requires special considerations. Look up the proper way to route grpc with your ingress controller. For instance, on Traefik, an IngressRouteTCP object is required.
There are some example ingress objects in the kube/example folder.
Kernel WireGuard
------------------
If you have control of the Kubernetes worker node servers, we recommend **first** installing WireGuard on the hosts, and then installing HA Netmaker in Kernel mode. By default, Netmaker will install with userspace WireGuard (wireguard-go) for maximum compatibility, and to avoid needing permissions at the host level. If you have installed WireGuard on your hosts, you should install Netmaker's helm chart with the following option:
- `--set wireguard.kernel=true`
DNS
----------
By Default, the helm chart will deploy without DNS enabled. To enable DNS, specify with:
- `--set dns.enabled=true`
This will require specifying a RWX storage class, e.g.:
- `--set dns.RWX.storageClassName=nfs`
This will also require specifying a service address for DNS. Choose a valid ipv4 address from the service IP CIDR for your cluster, e.g.:
- `--set dns.clusterIP=10.245.69.69`
**This address will only be reachable from hosts that have access to the cluster service CIDR.** It is only designed for use cases related to k8s. If you want a more general-use Netmaker server on Kubernetes for use cases outside of k8s, you will need to do one of the following:
- bind the CoreDNS service to port 53 on one of your worker nodes and set the COREDNS_ADDRESS equal to the public IP of the worker node
- Create a private Network with Netmaker and set the COREDNS_ADDRESS equal to the private address of the host running CoreDNS. For this, CoreDNS will need a node selector and will ideally run on the same host as one of the Netmaker server instances.
Values
---------
To view all options for the chart, please visit the README in the code repo `here <https://github.com/gravitl/netmaker/tree/master/kube/helm#values>`_ .
Highly Available Installation (VMs/Bare Metal)
==================================================
For an enterprise Netmaker installation, you will need a server that is highly available, to ensure redundant WireGuard routing when any server goes down. To do this, you will need:
1. A load balancer
2. 3+ Netmaker server instances
3. rqlite or PostgreSQL as the backing database
These documents outline general HA installation guidelines. Netmaker is highly customizable to meet a wide range of enterprise environments. If you would like support with an enterprise-grade Netmaker installation, you can `schedule a consultation here <https://gravitl.com/book>`_ .
The main consideration for this document is how to configure rqlite. Most other settings and procedures match the standardized way of making applications HA: Load balancing to multiple instances, and sharing a DB. In our case, the DB (rqlite) is distributed, making HA data more easily achievable.
If using PostgreSQL, follow their documentation for `installing in HA mode <https://www.postgresql.org/docs/14/high-availability.html>`_ and skip step #2.
1. Load Balancer Setup
------------------------
Your load balancer of choice will send requests to the Netmaker servers. Setup is similar to the various guides we have created for Nginx, Caddy, and Traefik. SSL certificates must also be configured and handled by the LB.
2. RQLite Setup
------------------
RQLite is the included distributed datastore for an HA Netmaker installation. If you have a different corporate database you wish to integrate, Netmaker is easily extended to other DB's. If this is a requirement, please contact us.
Assuming you use Rqlite, you must run it on each Netmaker server VM, or alongside that VM as a container. Setup a config.json for database credentials (password supports BCRYPT HASHING) and mount in working directory of rqlite and specify with `-auth config.json` :
.. code-block::
[{
"username": "netmaker",
"password": "<YOUR_DB_PASSWORD>",
"perms": ["all"]
}]
Once your servers are set up with rqlite, the first instance must be started normally, and then additional nodes must be added with the "join" command. For instance, here is the first server node:
.. code-block::
sudo docker run -d -p 4001:4001 -p 4002:4002 rqlite/rqlite -node-id 1 -http-addr 0.0.0.0:4001 -raft-addr 0.0.0.0:4002 -http-adv-addr 1.2.3.4:4001 -raft-adv-addr 1.2.3.4:4002 -auth config.json
And here is a joining node:
.. code-block::
sudo docker run -d -p 4001:4001 -p 4002:4002 rqlite/rqlite -node-id 2 -http-addr 0.0.0.0:4001 -raft-addr 0.0.0.0:4002 -http-adv-addr 2.3.4.5:4001 -raft-adv-addr 2.3.4.5:4002 -join https://netmaker:<YOUR_DB_PASSWORD>@1.2.3.4:4001
- reference for rqlite setup: https://github.com/rqlite/rqlite/blob/master/DOC/CLUSTER_MGMT.md#creating-a-cluster
- reference for rqlite security: https://github.com/rqlite/rqlite/blob/master/DOC/SECURITY.md
Once rqlite instances have been configured, the Netmaker servers can be deployed.
3. Netmaker Setup
------------------
Netmaker will be started on each node with default settings, except with DATABASE=rqlite (or DATABASE=postgress) and SQL_CONN set appropriately to reach the local rqlite instance. Rqlite will maintain consistency with each Netmaker backend.
If deploying HA with PostgreSQL, you will connect with the following settings:
.. code-block::
SQL_HOST = <sql host>
SQL_PORT = <port>
SQL_DB = <designated sql DB>
SQL_USER = <your user>
SQL_PASS = <your password>
DATABASE = postgres
4. Other Considerations
------------------------
This is enough to get a functioning HA installation of Netmaker. However, you may also want to make the Netmaker UI or the CoreDNS server HA as well. The Netmaker UI can simply be added to the same servers and load balanced appropriately. For some load balancers, you may be able to do this with CoreDNS as well.

View file

@ -1,75 +0,0 @@
=========
Support
=========
FAQ
======
Is Netmaker a VPN like NordNPN?
--------------------------------
No. Netmaker makes Virtual Networks, which are technically VPNs, but different. It's more like a corporate VPN, or a VPC (if you're familiar with AWS). Netmaker is often compared to OpenVPN, Tailscale, or Nebula.
If you're looking to achieve self-hosted web browsing, with functionality similar to NordVPN, ExpressVPN, Surfshark, Tunnelbear, or Private Internet Access, this is probably not the project for you. Technically, you can accomplish this with Netmaker, but it would be a little like using a all-terrain vehicle for stock car racing.
There are many good projects out there that support general internet privacy using WireGuard. Here are just a few of them:
https://github.com/trailofbits/algo
https://github.com/pivpn/pivpn
https://github.com/subspacecloud/subspace
https://github.com/mullvad/mullvadvpn-app
Do you have an 'Exit Nodes' feature?
---------------------------------------
Please see the :doc:`Egress Gateway <./egress-gateway>` documentation.
Do you offer any business or enterprise support?
---------------------------------------------------
Yes, please contact info@gravitl.com or visit https://gravitl.com/plans.
Why the SSPL License?
----------------------
As of now, we think the SSPL is the best way to ensure the long-term viability of the project, but we are regularly evaluating this to see if an OSI-approved license makes more sense.
We believe the SSPL lets most people run the project the way they want, for both for private use and business use, while giving us a path to maintain viability. We are working to make sure the guidelines clear, and do not want the license to impact the community's ability to use and modify the project.
If you believe the SSPL will negatively impact your ability to use the project, please do not hesitate to reach out.
Telemetry
==============
As of v0.10.0, Netmaker collects "opt-out" telemetry data. To opt out, simply set "TELEMETRY=off" in your docker-compose file.
Please consider participating in telemetry, as it helps us focus on the features and bug fixes which are most useful to users. Netmaker is a broad platform, and without this data, it is difficult to know where the team should spend its limited resources.
The following is the full list of telemetry data we collect. Besides "Server Version" all data is simply an integer count:
- Randomized server ID
- Count of nodes
- Count of "non-server" nodes
- Count of external clients
- Count of networks
- Count of users
- Count of linux nodes
- Count of freebsd nodes
- Count of macos nodes
- Count of windows nodes
- Count of docker nodes
- Count of k8s nodes
- Server version
We use `PostHog <https://https://posthog.com/>`_, an open source and trusted framework for telemetry data.
To look at exactly we collect telemetry, you can view the source code under serverctl/telemetry.go: https://github.com/gravitl/netmaker/blob/master/serverctl/telemetry.go
Contact
===========
If you need help, try the discord or open a GitHub ticket.
Email: info@gravitl.com
Discord: https://discord.gg/zRb9Vfhk8A

View file

@ -1,139 +0,0 @@
=================
Troubleshooting
=================
Common Issues
--------------
**How can I connect my Android or IOS device to my Netmaker VPN?**
Currently meshing one of these devices is not supported, however it will be soon.
For now you can connect to your VPN by making one of the nodes an Ingress Gateway, then
create an Ext Client for each device. Finally, use the official WG app or another
WG configuration app to connect via QR or downloading the device's WireGuard configuration.
**I've made changes to my nodes but the nodes themselves haven't updated yet, why?**
Please allow your nodes to complete a check in or two, in order to reconfigure themselves.
In some cases, it could take up to a minute or so.
**Do I have to use access keys to join a network?**
Although keys are the preferred way to join a network, Netmaker does allow for manual node sign-ups.
Simply turn on "allow manual signups" on your network and nodes will not connect until you manually aprove each one.
**Is there a community or forum to ask questions about Netmaker?**
Yes, we have an active `discord <https://discord.gg/Pt4T9y9XK8>`_ community and issues on our `github <https://github.com/gravitl/netmaker/issues>`_ are answered frequently!
You can also sign-up for updates at our `gravitl site <https://gravitl.com/>`_!
**How can I get additional support for my business?**
Check out our business support subscriptions at https://gravitl.com/plans. Subscription holders can also purchase consulting credits via the site.
Server
-------
**How do I use a private address from the Netmaker Server? How do I contact nodes using their private addresses from the server?**
Default nodes appear in each network with the "netmaker" name. These nodes are created by, and attached to, the server. The server is contained in docker, meaning these clients are also contained in docker. Their networking stack is also contained in docker. The "netmaker" nodes are meant to function as network utilities. They assist with UDP Hole Punching and can run Relays, Egress, and Ingress. However, they are meant to stay contained in the server. They do not touch the host networking stack.
If you want to give the physical server / VM a private IP in the netmaker network, you must deploy an **additional** node using the standard netclient. The only note here is that the server consumes ports 51821-51831, so you will need to give it a port outside this range, e.x. `./netclient join <token> --port 51835`.
One a netclient is deployed to the underlying server/VM, you will be able to use the private address to reach other nodes from the host, or to reach the server over the private network.
**I upgraded from 0.7 to 0.8 and now I dont have any data in my server!**
In 0.8, sqlite becomes the default database. If you were running with rqlite, you must set the DATABASE environment variable to rqlite in order to continue using rqlite.
**Can I secure/encrypt all the traffic to my server and UI?**
This can fairly simple to achieve assuming you have access to a domain and are familiar with Nginx.
Please refer to the quick-start guide to see!
**Can I connect multiple nodes (mesh clients) behind a single firewall/router?**
Yes! As of version 0.7 Netmaker supports UDP Hole Punching to allow this, without the use of a third party STUN server!
Is UDP hole punching a risk for you? Well you can turn it off and make static nodes/ports for the server to refer to as well.
**What are the minimum specs to run the server?**
We recommend at least 1 CPU and 2 GB Memory.
**Does this support IPv6 addressing?**
Yes, Netmaker supports IPv6 addressing. When you create a network, just make sure to turn on Dual Stack.
Nodes will be given IPv6 addresses along with their IPv4 address. It does not currently support IPv6 only.
**Does Netmaker support Raft Consensus?**
Netmaker does not directly support it, but it uses `rqlite <https://github.com/rqlite/rqlite>`_ (which supports Raft) as the database.
**How do I uninstall Netmaker?**
There is no official uninstall script for the Netmaker server at this time. If you followed the quick-start guide, simply run ``sudo docker-compose -f docker-compose.quickstart.yml down --volumes``
to completely wipe your server. Otherwise kill the running binary and it's up to you to remove database records/volumes.
UI
----
**I want to make a seperate network and give my friend access to only that network.**
Simply navigate to the UI (as an admin account). Select users in the top left and create them an account.
Select the network(s) to give them and they should be good to go! They are an admin of that network(s) only now.
**I'm done with an access key, can I delete it?**
Simply navigate to the UI (as an admin account). Select your network of interest, then the select the ``Access Keys`` tab.
Then delete the rogue access key.
**I can't delete my network, why?**
You **MUST** remove all nodes in a network before you can delete it.
**Can I have multiple nodes with the same name?**
Yes, nodes can share names without issue. It may just be harder on you to know which is which.
Netclient
-----------
**How do I connect a node to my Netmaker network with Netclient?**
First get your access token (not just access key), then run ``sudo netclient join -t <access token>``.
**NOTE:** netclient may be under /etc/netclient/, i.e run ``sudo /etc/netclient/netclient join -t <access token>``
**How do I disconnect a node on a Netmaker network?**
In order to leave a Netmaker network, run ``sudo netclient leave -n <network-name>``
**How do I check the logs of my agent on a node?**
You will need sudo/root permissions, but you can run ``sudo systemctl status netclient@<insert network name>``
or you may also run ``sudo journalctl -u netclient@<network name>``.
Note for journalctl: you should hit the ``end`` key to get to view the most recent logs quickly or use ``journalctl -u netclient@<network name> -f`` instead.
**Can I check the configuration of my node on the node?**
**A:** Yes, on the node simply run ``sudo cat /etc/netclient/netconfig-<network name>`` and you should see what your current configuration is!
You can also see the current WireGuard configuration with ``sudo wg show``
**I am done with the agent on my machine, can I uninstall it?**
Yes, on the node simply run ``sudo /etc/netclient/netclient uninstall``.
**I am running SELinux and when I reboot my node I get a permission denied in my netclient logs and it doesn't connect anymore, why?**
If you're running SELinux, it will interfere with systemd's ability to restart the client properly. Therefore, please run the following:
.. code-block::
sudo semanage fcontext -a -t bin_t '/etc/netclient/netclient'
sudo chcon -Rv -u system_u -t bin_t '/etc/netclient/netclient'
sudo restorecon -R -v /etc/netclient/netclient
**I have a handshake with a peer but can't ping it, what gives?**
This is commonly due to incorrect MTU settings. Typically, it will be because MTU is too high. Try setting MTU lower on the node. This can be done via netconfig, or by editing the node in the UI.
**I have a hard to reach machine behind a firewall or a corporate NAT, what can I do?**
In this situation you can use the Relay Server functionality introduced in Netmaker v0.8 to designate a node as a relay to your "stuck" machine. Simply click the button to make a node into a relay and tell it to relay traffic to this hard-to-reach peer.
**I am unable to run the netclient on my OpenWRT machine, what's wrong?**
Deploying on OpenWRT depends a lot on the version of OpenWRT and the hardware being used. If the primary installer does not work, there are two things you can try:
1. This community-run package for OpenWRT: https://github.com/sbilly/netmaker-openwrt
2. Manual installation:
- download (wget) the netclient package for your hardware from the netclient releases: https://github.com/gravitl/netmaker/releases
- rename to "netclient"
- Run as root from a bash shell on OpenWRT
3. You may experience an issue with the length of the token, which has limits on some OpenWRT shells. If you run into this problem, you can use the following script to convert your token into a "netclient join" command:
- `wget https://raw.githubusercontent.com/gravitl/netmaker/master/scripts/token-convert.sh`
- ./token-convert <token value>
- Run the output on your OpenWRT machine
CoreDNS
--------
**Is CoreDNS required to use Netmaker?**
CoreDNS is not required. Simply start your server with ``DNS_MODE="off"``.
**What is the minimum DNS entry value I can use?**
Netmaker supports down to two characters for DNS names for your networks domains**

View file

@ -1,203 +0,0 @@
=================
UI Reference
=================
This page contains annotated screenshots of most UI components, detailing the configuration options of each field across Nodes, Networks, DNS, Ext Clients, Users, and more.
Dashboard
=================
.. image:: images/ui-1.jpg
:width: 80%
:alt: dashboard
:align: center
Networks
=================
Create
--------
.. image:: images/ui-2.jpg
:width: 80%
:alt: create network
:align: center
.. code-block::
(1) **Autofill:** Provides sensible defaults for network details and makes up a name.
(2) **Network Name:** The name of the network. Character limited, as this translates to the interface name on hosts (nm-<network name>)
(3) **Address Range:** The CIDR of the network. Must be a valid IPv4 Subnet and should be a private address range.
(4) **Udp Hole Punching:** Enables or disables "UDP Hole Punching" on the network. When on, clients will first reach out to the server. The server will keep track of public addresses / ports and send these to all other clients in the network. This increases NAT traversibility, but can also cause issues depending on the server environment (if server is in a private network, for example). Typically good to enable if clients will "roam" frequently or are user devices. Typically better to disable if most clients will be servers with well-defined endpoints / ports. If enabled, you can also disable UDP Hole Punching on any individual machine via the UI (see Node section) but it will be enabled by default.
(5) **Is Local Network:** Turn on if all clients in the network will be in the same "local" network. This is a very rare situation and depends on the use case. Almost always leave this off. Turn on if you are in a large data center with a large private address space over which clients should communicate. Can also enable if using a VPC and are treating a single client as "egress" for the VPC. If enabled, fill out the address range of the local network which should determine endpoints.
(6) **Is Dual Stack:** Turn on to add private ipv6 addresses to all clients in addition to their ipv4 addresses. Not typically necessary. If on, enter a private ipv6 address range to pull from.
Edit
--------
.. image:: images/ui-3.jpg
:width: 80%
:alt: edit network
:align: center
**NOTE:** With the exception of Address Ranges (1-2) any setting that affects nodes will not take effect on existing nodes. It will only set the settings on any **new** node, after the setting has been changed.
(1) **Address Range (ipv4):** The ipv4 private network CIDR. If edited, Netmaker will go through all nodes and update private addresses based on the new range.**
(2) **Address Range (ipv6):** The ipv6 private network CIDR. If edited, Netmaker will go through all nodes and update private addresses based on the new range.**
(3) **Local Range:** Only relevant if "Is Local" was switched on during creation. Specifies the local range that nodes will base their Endpoint off of (note: if a node cannot find an enpoint within the range it will fallback to public ip).
(4) **Display Name:** The display name of the network. Network Name cannot be changed (acts as a unique ID) but display name can be changed. Only effects appearance in UI.
(5) **Default Interface:** The default network interface name configured on each node. This defaults to "nm-<network name>".
(6) **Default Port:** The default WireGuard port each node will attempt to use. Nodes will iterate up from this port until they find a free port.
(7) **Default PostUp:** A default post-up command to run on each node (after interface has been configured). Disabled by default to prevent RCE vulnerabilities.
(8) **Default PostDown:** A default post-down command to run on each node (after interface has been removed). Disabled by default to prevent RCE vulnerabilities.
(9) **Default Keepalive:** How often nodes should send packets to keep connection alive with all peers (in seconds).
(10) **Default Ext Client DNS:** If set, adds a "DNS=<value>" line to each ext client config. Set this to add DNS to clients. Typically will set this to the server's public IP.
(11) **Default MTU:** Default MTU for interfaces of all clients in network. Can be useful to set lower in certain difficult environments such as Kubernetes.
(12) **Allow Node Signup Without Keys:** Allows nodes to join the network without a valid Access Key. Nodes will be put in "pending" status until approved via UI by an admin. Useful if an arbitrary number of people need to join the network and there is no easy way to distribute keys to users.
(13) **Is Dual Stack:** Enable the Dual Stack feature of networks and add ipv6 addresses to nodes.
(14) **Default Saveconfig:** Typically ignore this. Sets the SaveConfig field on wireguard config.
(15) **UDP Hole Punching:** Whether or not UDP Hole Punching is turned on (see Network Create notes). Only effects new nodes. Enables or disables "UDP Hole Punching" on the network. When on, clients will first reach out to the server. The server will keep track of public addresses / ports and send these to all other clients in the network. This increases NAT traversibility, but can also cause issues depending on the server environment (if server is in a private network, for example). Typically good to enable if clients will "roam" frequently or are user devices. Typically better to disable if most clients will be servers with well-defined endpoints / ports. If enabled, you can also disable UDP Hole Punching on any individual machine via the UI (see Node section) but it will be enabled by default.
Nodes
========
Node List
-------------
.. image:: images/ui-4.jpg
:width: 80%
:alt: dashboard
:align: center
(1) **Search Nodes:** Look up a node by name.
(2) **Select Network:** Filter nodes by network.
(3) **Node Name:** Name of node. By default set to hostname of machine.
(4) **IP Address:** Private IP of node within network.
(5) **Network:** Network the node is in.
(6) **Egress:** Indicates if node is an egress gateway. Click to convert into egress gateway. Egress gateways route traffic from the network into a specific subnet or subnets. Egress gateways should be servers in a static location with a reliable IP.
(7) **Ingress:** Indicates if the node is an ingress. Click to convert into ingress gateway. Ingress gateways route traffic into the network over the WireGuard interface using "ext clients," which are static WireGuard config files. Ingress gateways should be servers in a static location with a reliable IP.
(8) **Relay:** Indicates if the node is a relay. Click to convert into relay. Relays route traffic to specified nodes for the network (typically hard to reach / CGNAT'ted nodes. Relays should be servers in a static location with a reliable IP.
(9) **Status:** Indicates how recently the node checked into the server. Displays "Warning" after 5 minutes and "Error" after 30 minutes without a check in. Does **not** indicate the health of the node's virtual network connections.
(10) **Delete:** Delete the node.
Create Egress
---------------
.. image:: images/ui-6.jpg
:width: 80%
:alt: dashboard
:align: center
(1) **Egress Gateway Ranges:** A comma-separated list of the subnets for which the gateway will route traffic. For instance, with Kubernetes this could be both the Service Network and Pod Network. For a standard VPN, Netmaker can use a list of the public CIDR's (see the docs). Typically, this will be something like a data center network, VPC, or home network.
(2) **Interface:** The interface on the machine used to access the provided egress gateway ranges. For instance, on a typical linux machine, the interface for public traffic would be "eth0". Usually you will need to check on the machine first to find the right interface. For instance, on Linux, you can find the interface by running this: ip route get <address in subnet>.
Create Relay
-------------
.. image:: images/ui-7.jpg
:width: 80%
:alt: dashboard
:align: center
(1) **Relay Addresses:** Specify which private addresses (of nodes) that this node should relay for.
(2) **Select Nodes:** Rather than specify by IP, you can just select from a list of node names instead.
(3) **Select All:** Rather than select a list, you can "select all", which converts the network from "pure mesh" into "hub-and-spoke", meaning there are no p2p connections, everything goes through this relay first.
Edit Node / Node Details
--------------------------
.. image:: images/ui-5.jpg
:width: 80%
:alt: dashboard
:align: center
(1) **IP Address:** The primary private IP address of the node. Assigned automatically by Netmaker but can be changed to whatever you want within the Network CIDR.
(2) **IPv6 Address:** (Only if running dual stack) the primary private IPv6 address of the node. Assigned automatically by Netmaker but can be changed to whatever you want within the Network CIDR.
(3) **Local Address:** The "locally reachable" address of the node. Other nodes will take note of this to see if this node is on the same network. If so, they will use this address instead of the public "Endpoint." If running a few nodes inside of a VPC, home network, or similar, make sure the local address is populated correctly for faster and more secure inter-node communication.
(4) **Node Name:** The name of the node within the network. Hostname by default but can be anything (within the character limits).
(5) **Port:** The port used by the node locally. **This value is ignored if UDP Hole Punching is on,** because port is set dynamically every time interface is created. If UDP Hole Punching is off, the port can be set to any reasonable (and available) value you'd like for the local machine. Typi
(6) **Public Key:** (Uneditable) The public key of the node, distributed to other peers in the network.
(7) **Endpoint:** The (typically public) IP of the machine, which peers will use to reach it, in combination with the port. If changing this value, make sure Roaming is turned off, since otherwise, the node will check to see if there is a change in the public IP regularly and update it.
(8) **PostUp:** Uneditable by default to disable RCE. Commands to run after the interface is created. If an ingress or egress gateway are created, this field will populate automatically with appropriate iptables commands.
(9) **PostDown:** Uneditable by default to disable RCE. Commands to run after the interface is brought down. If an ingress or egress gateway are created, this field will populate automatically with appropriate iptables commands.
(10) **Allowed IPs:** Additional private addresses given to the node (in addition to the IPAddress and IPv6Address). Useful in some scenarios where there is a known address a server should have. Any IPs added here will be tacked onto the AllowedIPs of other peers, so this node will be shown to have multiple reachable private addresses.
(11) **Persistent Keepalive:** How often packets are sent to keep connections open with other peers.
(12) **Relay Addresses:** If "Relay" is enabled on this node, this field can be edited to add and remove nodes from the relay. So if you are currently relaying just one node but wish to relay an additional node, just add it's private IP here.
(13) **Node Expiration Datetime:** If a node should become invalid after a length of time, you can set it in this field, after which time, it will lose access to the network and will not populate to other nodes. Useful for scenarios where temporary access is granted to 3rd parties.
(14) **Last Checkin:** Unix timestamp of the last time the node checked in with the server. Used to determine generic health of node.
(15) **Mac Address:** The hardware mac address of the machine. Used to be used as the unique ID, but is being depreciated.
(16) **Network:** The network this 1node belongs to.
(17) **Egress Gateway Ranges:** If Egress is enabled, the gateway ranges that this machine routes to.
(18) **Local Range:** If IsLocal has been enabled on the network, this is the local range in which the node will look for a private address from it's local interfaces, to use as an endpoint.
(19) **Node Operating System:** The OS of the machine.
(20) **MTU:** The MTU that the node will use on the interface. If "wg show" displays a valid handshake but pings are not working, many times the issue is MTU. Making this value lower can solve this issue. Some typical values are 1024, 1280, and 1420.
(21) **Saveconfig:** Usually best to ignore this. Sets the "SaveConfig" value on wireguard config files.
(22) **Is Static:** Ports and Endpoints can be changed automatically by the netclient. Switching on "Is Static" means the port and endpoint will stay the same until you change it. This can be good to set if the machine is a server sitting in a location that is not expected to change. It is also good to have Is Static switched on for Ingress, Egress, and Relay Servers, since they should be in a reliable location.
(23) **UDP Hole Punching:** If on, the node's port will be randomized. The port and endpoint distributed to other nodes are no longer determined by the settings in this file. Instead, the node will "check in" with the server regularly. The server will track the IP and port used to open a connection, and store these values. These values then get distributed to nodes. This is helpful for getting around NAT's which may obscure the node's location.
(24) **Is DNS On:** DNS is solely handled by resolvectl at the moment, which is on many Linux distributions. For anything else, this value should remain off. If you wish to configure DNS for non-compatible systems, you must do so manually.
(25) **Dualstack:** Whether or not this machine should have both a private ipv4 address and ipv6 address.
(26) **Is Local:** If on, will only communicate over the local address (Assumes IsLocal tuned to 'yes' on the network level.)
(27) **Roaming:** If on, will check regularly for changes in the Endpoint and modify the Endpoint value appropriately. This allows a client to "roam" between wifi networks and maintain a connection. Good to keep on for machines where the public address may change.
(28) **IPforwarding:** If on, ipforwarding is enabled on the machine. Should almost always be kept on.
Ext Clients
================
.. image:: images/ui-8.jpg
:width: 80%
:alt: dashboard
:align: center
(1) **Gateway Name / IP Address:** Information about which Node is the Ingress Gateway.
(2) **Add External Client:** Button to generate a new ext client.
(3) **Client ID:** The randomly-generated name of the client. Click on the ID to change the name to something sensible.
(4) **IP Address:** The private ip address of the ext client.
(5) **QR Code:** If joining form iOS or Android, open the WireGuard app and scan the QR code to join the network.
(6) **Download Client Configuration:** If joining from a laptop/desktop, download the config file and run "wg-quick up /path/to/config"
(7) **Delete:** Delete the ext client and remove its network access.
DNS
===========
.. image:: images/ui-10.jpg
:width: 80%
:alt: dashboard
:align: center
(1) **DNS Name:** The private DNS entry. Must end in ".<network name>" (added automatically). This avoids conflicts between networks.
(2) **IP Address:** The IP address of the entry. Can be anything (public addresses too!) but typically a node IP.
(3) **Select Node Address:** Select a node name to populate its IP address automatically.
Create / Edit Users
=====================
.. image:: images/ui-11.jpg
:width: 80%
:alt: dashboard
:align: center
(1) **Username:** Specify Username.
(2) **Password:** Specify password.
(3) **Confirm Password:** Confirm password.
(4) **Make Admin:** Make into a server admin or "super admin", which has access to all networks and server-level settings.
(5) **Networks:** If not made into an "admin", select the networks which this user has access to. The user will be a "network admin" of these networks, but other networks will be invisible/unaccessible.
Node Graph
=====================
.. image:: images/node-graph-1.png
:width: 80%
:alt: dashboard
:align: center
View all nodes in your network, zoom in, zoom out, and search for node names. A legend is on the side to identify each node status / configuration.
.. image:: images/node-graph-2.png
:width: 80%
:alt: dashboard
:align: center
(1) **hover:** Hover over a node to see its direct connections.
(2) **Configuration Pane:** Manage the node in this pane just like you would in the Nodes pane. See the "Node List" and "Edit Node" sections for more details.

View file

@ -1,45 +0,0 @@
=====================================
Upgrades
=====================================
Introduction
===============
As of 0.10.0, upgrading Netmaker is a manual process. This is expected to be automated in the future, but for now is still a relatively straightforward process.
Critical Notes for 0.10.0
=============================================
At the time of this writing, an upgrade process has not been defined for 0.10.0. DO NOT follow this documentation to upgrade from a prior version to 0.10.0. An upgrade process will be defined shortly. For now, if you seek to upgrade to 0.10.0, you must clear your server entirely (docker-compose down --volumes), uninstall your netclients, and re-install netmaker + netclients.
Upgrade the Server (prior to 0.10.0)
======================================
To upgrade the server, you only need to change the docker image versions:
1. `ssh root@my-server-ip`
2. `docker-compose down`
3. `vi docker-compose.yml`
4. Change gravitl/netmaker:<version> and gravitl/netmaker-ui:<version> to the new version.
5. Save and close the file
6. `docker-compose up -d`
Upgrade the Clients (prior to 0.10.0)
======================================
To upgrade the client, you must get the new client binary and place it in /etc/netclient. Depending on the new vs. old version, there may be minor incompatibilities (discussed below).
1. Vists https://github.com/gravitl/netmaker/releases/
2. Find the appropriate binary for your machine.
3. Download. E.x.: `wget https://github.com/gravitl/netmaker/releases/download/vX.X.X/netclient-myversion`
4. Rename binary to `netclient` and move to folder. E.x.: `mv netclient-myversion /etc/netclient/netclient`
5. `netclient --version` (confirm it's the correct version)
6. `netclient pull`
This last step helps ensure any newly added fields are now present. You may run into a "panic" based on missing fields and your version mismatch. In such cases, you can either:
1. Add the missing field to /etc/netclient/config/netconfig-yournetwork and then run "netclient checkin"
or
2. Leave and rejoin the network

View file

@ -1,21 +0,0 @@
=================
External Guides
=================
Netmaker has many use cases, from a basic virtual network to an office gateway VPN to a Kubernetes underlay. It can be a bit overwhelming to figure out where to start. If you don't find your use case here, but think Netmaker is a good fit, let us know!
Video Tutorials
==================
* `Intro/Overview <https://youtu.be/PWLPT320Ybo>`_: Tutorial on first-time usage, setting up a mesh network.
* `Site-to-Site Gateway <https://youtu.be/krCKBJhwwDk>`_: Tutorial on setting up site-to-site connections, allowing peers to access external networks via gateways.
* `IPv6 and Private DNS <https://youtu.be/b4diaKWUcXI>`_: Tutorial on dual-stack IPv6 in Netmaker and Private DNS management (separate topics).
* `Kubernetes Networking <https://youtu.be/z2jvlFVU3dw>`_: Tutorial on setting up cross-cloud Kubernetes clusters using Netmaker.
Written Tutorials
==================
* `K3s Cross-cloud cluster <https://itnext.io/how-to-deploy-a-single-kubernetes-cluster-across-multiple-clouds-using-k3s-and-wireguard-a5ae176a6e81>`_: Tutorial on setting up cross-cloud K3s clusters using Netmaker.
* `MicroK8s Cross-cloud cluster <https://itnext.io/how-to-deploy-a-cross-cloud-kubernetes-cluster-with-built-in-disaster-recovery-bbce27fcc9d7>`_: Tutorial on setting up cross-cloud MicroK8s clusters using Netmaker.
* `Secure access to private services <https://afeiszli.medium.com/how-to-enable-secure-access-to-your-hosted-services-using-netmaker-and-wireguard-1b3282d4b7aa>`_: Tutorial on setting up secure Nextcloud with Netmaker.

View file

@ -1,905 +0,0 @@
/*
* basic.css
* ~~~~~~~~~
*
* Sphinx stylesheet -- basic theme.
*
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/* -- main layout ----------------------------------------------------------- */
div.clearer {
clear: both;
}
div.section::after {
display: block;
content: '';
clear: left;
}
/* -- relbar ---------------------------------------------------------------- */
div.related {
width: 100%;
font-size: 90%;
}
div.related h3 {
display: none;
}
div.related ul {
margin: 0;
padding: 0 0 0 10px;
list-style: none;
}
div.related li {
display: inline;
}
div.related li.right {
float: right;
margin-right: 5px;
}
/* -- sidebar --------------------------------------------------------------- */
div.sphinxsidebarwrapper {
padding: 10px 5px 0 10px;
}
div.sphinxsidebar {
float: left;
width: 230px;
margin-left: -100%;
font-size: 90%;
word-wrap: break-word;
overflow-wrap : break-word;
}
div.sphinxsidebar ul {
list-style: none;
}
div.sphinxsidebar ul ul,
div.sphinxsidebar ul.want-points {
margin-left: 20px;
list-style: square;
}
div.sphinxsidebar ul ul {
margin-top: 0;
margin-bottom: 0;
}
div.sphinxsidebar form {
margin-top: 10px;
}
div.sphinxsidebar input {
border: 1px solid #98dbcc;
font-family: sans-serif;
font-size: 1em;
}
div.sphinxsidebar #searchbox form.search {
overflow: hidden;
}
div.sphinxsidebar #searchbox input[type="text"] {
float: left;
width: 80%;
padding: 0.25em;
box-sizing: border-box;
}
div.sphinxsidebar #searchbox input[type="submit"] {
float: left;
width: 20%;
border-left: none;
padding: 0.25em;
box-sizing: border-box;
}
img {
border: 0;
max-width: 100%;
}
/* -- search page ----------------------------------------------------------- */
ul.search {
margin: 10px 0 0 20px;
padding: 0;
}
ul.search li {
padding: 5px 0 5px 20px;
background-image: url(file.png);
background-repeat: no-repeat;
background-position: 0 7px;
}
ul.search li a {
font-weight: bold;
}
ul.search li p.context {
color: #888;
margin: 2px 0 0 30px;
text-align: left;
}
ul.keywordmatches li.goodmatch a {
font-weight: bold;
}
/* -- index page ------------------------------------------------------------ */
table.contentstable {
width: 90%;
margin-left: auto;
margin-right: auto;
}
table.contentstable p.biglink {
line-height: 150%;
}
a.biglink {
font-size: 1.3em;
}
span.linkdescr {
font-style: italic;
padding-top: 5px;
font-size: 90%;
}
/* -- general index --------------------------------------------------------- */
table.indextable {
width: 100%;
}
table.indextable td {
text-align: left;
vertical-align: top;
}
table.indextable ul {
margin-top: 0;
margin-bottom: 0;
list-style-type: none;
}
table.indextable > tbody > tr > td > ul {
padding-left: 0em;
}
table.indextable tr.pcap {
height: 10px;
}
table.indextable tr.cap {
margin-top: 10px;
background-color: #f2f2f2;
}
img.toggler {
margin-right: 3px;
margin-top: 3px;
cursor: pointer;
}
div.modindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
div.genindex-jumpbox {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
margin: 1em 0 1em 0;
padding: 0.4em;
}
/* -- domain module index --------------------------------------------------- */
table.modindextable td {
padding: 2px;
border-collapse: collapse;
}
/* -- general body styles --------------------------------------------------- */
div.body {
min-width: 450px;
max-width: 800px;
}
div.body p, div.body dd, div.body li, div.body blockquote {
-moz-hyphens: auto;
-ms-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
a.headerlink {
visibility: hidden;
}
a.brackets:before,
span.brackets > a:before{
content: "[";
}
a.brackets:after,
span.brackets > a:after {
content: "]";
}
h1:hover > a.headerlink,
h2:hover > a.headerlink,
h3:hover > a.headerlink,
h4:hover > a.headerlink,
h5:hover > a.headerlink,
h6:hover > a.headerlink,
dt:hover > a.headerlink,
caption:hover > a.headerlink,
p.caption:hover > a.headerlink,
div.code-block-caption:hover > a.headerlink {
visibility: visible;
}
div.body p.caption {
text-align: inherit;
}
div.body td {
text-align: left;
}
.first {
margin-top: 0 !important;
}
p.rubric {
margin-top: 30px;
font-weight: bold;
}
img.align-left, figure.align-left, .figure.align-left, object.align-left {
clear: left;
float: left;
margin-right: 1em;
}
img.align-right, figure.align-right, .figure.align-right, object.align-right {
clear: right;
float: right;
margin-left: 1em;
}
img.align-center, figure.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
img.align-default, figure.align-default, .figure.align-default {
display: block;
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left;
}
.align-center {
text-align: center;
}
.align-default {
text-align: center;
}
.align-right {
text-align: right;
}
/* -- sidebars -------------------------------------------------------------- */
div.sidebar,
aside.sidebar {
margin: 0 0 0.5em 1em;
border: 1px solid #ddb;
padding: 7px;
background-color: #ffe;
width: 40%;
float: right;
clear: right;
overflow-x: auto;
}
p.sidebar-title {
font-weight: bold;
}
div.admonition, div.topic, blockquote {
clear: left;
}
/* -- topics ---------------------------------------------------------------- */
div.topic {
border: 1px solid #ccc;
padding: 7px;
margin: 10px 0 10px 0;
}
p.topic-title {
font-size: 1.1em;
font-weight: bold;
margin-top: 10px;
}
/* -- admonitions ----------------------------------------------------------- */
div.admonition {
margin-top: 10px;
margin-bottom: 10px;
padding: 7px;
}
div.admonition dt {
font-weight: bold;
}
p.admonition-title {
margin: 0px 10px 5px 0px;
font-weight: bold;
}
div.body p.centered {
text-align: center;
margin-top: 25px;
}
/* -- content of sidebars/topics/admonitions -------------------------------- */
div.sidebar > :last-child,
aside.sidebar > :last-child,
div.topic > :last-child,
div.admonition > :last-child {
margin-bottom: 0;
}
div.sidebar::after,
aside.sidebar::after,
div.topic::after,
div.admonition::after,
blockquote::after {
display: block;
content: '';
clear: both;
}
/* -- tables ---------------------------------------------------------------- */
table.docutils {
margin-top: 10px;
margin-bottom: 10px;
border: 0;
border-collapse: collapse;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
table.align-default {
margin-left: auto;
margin-right: auto;
}
table caption span.caption-number {
font-style: italic;
}
table caption span.caption-text {
}
table.docutils td, table.docutils th {
padding: 1px 8px 1px 5px;
border-top: 0;
border-left: 0;
border-right: 0;
border-bottom: 1px solid #aaa;
}
table.footnote td, table.footnote th {
border: 0 !important;
}
th {
text-align: left;
padding-right: 5px;
}
table.citation {
border-left: solid 1px gray;
margin-left: 1px;
}
table.citation td {
border-bottom: none;
}
th > :first-child,
td > :first-child {
margin-top: 0px;
}
th > :last-child,
td > :last-child {
margin-bottom: 0px;
}
/* -- figures --------------------------------------------------------------- */
div.figure, figure {
margin: 0.5em;
padding: 0.5em;
}
div.figure p.caption, figcaption {
padding: 0.3em;
}
div.figure p.caption span.caption-number,
figcaption span.caption-number {
font-style: italic;
}
div.figure p.caption span.caption-text,
figcaption span.caption-text {
}
/* -- field list styles ----------------------------------------------------- */
table.field-list td, table.field-list th {
border: 0 !important;
}
.field-list ul {
margin: 0;
padding-left: 1em;
}
.field-list p {
margin: 0;
}
.field-name {
-moz-hyphens: manual;
-ms-hyphens: manual;
-webkit-hyphens: manual;
hyphens: manual;
}
/* -- hlist styles ---------------------------------------------------------- */
table.hlist {
margin: 1em 0;
}
table.hlist td {
vertical-align: top;
}
/* -- object description styles --------------------------------------------- */
.sig {
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
}
.sig-name, code.descname {
background-color: transparent;
font-weight: bold;
}
.sig-name {
font-size: 1.1em;
}
code.descname {
font-size: 1.2em;
}
.sig-prename, code.descclassname {
background-color: transparent;
}
.optional {
font-size: 1.3em;
}
.sig-paren {
font-size: larger;
}
.sig-param.n {
font-style: italic;
}
/* C++ specific styling */
.sig-inline.c-texpr,
.sig-inline.cpp-texpr {
font-family: unset;
}
.sig.c .k, .sig.c .kt,
.sig.cpp .k, .sig.cpp .kt {
color: #0033B3;
}
.sig.c .m,
.sig.cpp .m {
color: #1750EB;
}
.sig.c .s, .sig.c .sc,
.sig.cpp .s, .sig.cpp .sc {
color: #067D17;
}
/* -- other body styles ----------------------------------------------------- */
ol.arabic {
list-style: decimal;
}
ol.loweralpha {
list-style: lower-alpha;
}
ol.upperalpha {
list-style: upper-alpha;
}
ol.lowerroman {
list-style: lower-roman;
}
ol.upperroman {
list-style: upper-roman;
}
:not(li) > ol > li:first-child > :first-child,
:not(li) > ul > li:first-child > :first-child {
margin-top: 0px;
}
:not(li) > ol > li:last-child > :last-child,
:not(li) > ul > li:last-child > :last-child {
margin-bottom: 0px;
}
ol.simple ol p,
ol.simple ul p,
ul.simple ol p,
ul.simple ul p {
margin-top: 0;
}
ol.simple > li:not(:first-child) > p,
ul.simple > li:not(:first-child) > p {
margin-top: 0;
}
ol.simple p,
ul.simple p {
margin-bottom: 0;
}
dl.footnote > dt,
dl.citation > dt {
float: left;
margin-right: 0.5em;
}
dl.footnote > dd,
dl.citation > dd {
margin-bottom: 0em;
}
dl.footnote > dd:after,
dl.citation > dd:after {
content: "";
clear: both;
}
dl.field-list {
display: grid;
grid-template-columns: fit-content(30%) auto;
}
dl.field-list > dt {
font-weight: bold;
word-break: break-word;
padding-left: 0.5em;
padding-right: 5px;
}
dl.field-list > dt:after {
content: ":";
}
dl.field-list > dd {
padding-left: 0.5em;
margin-top: 0em;
margin-left: 0em;
margin-bottom: 0em;
}
dl {
margin-bottom: 15px;
}
dd > :first-child {
margin-top: 0px;
}
dd ul, dd table {
margin-bottom: 10px;
}
dd {
margin-top: 3px;
margin-bottom: 10px;
margin-left: 30px;
}
dl > dd:last-child,
dl > dd:last-child > :last-child {
margin-bottom: 0;
}
dt:target, span.highlighted {
background-color: #fbe54e;
}
rect.highlighted {
fill: #fbe54e;
}
dl.glossary dt {
font-weight: bold;
font-size: 1.1em;
}
.versionmodified {
font-style: italic;
}
.system-message {
background-color: #fda;
padding: 5px;
border: 3px solid red;
}
.footnote:target {
background-color: #ffa;
}
.line-block {
display: block;
margin-top: 1em;
margin-bottom: 1em;
}
.line-block .line-block {
margin-top: 0;
margin-bottom: 0;
margin-left: 1.5em;
}
.guilabel, .menuselection {
font-family: sans-serif;
}
.accelerator {
text-decoration: underline;
}
.classifier {
font-style: oblique;
}
.classifier:before {
font-style: normal;
margin: 0 0.5em;
content: ":";
display: inline-block;
}
abbr, acronym {
border-bottom: dotted 1px;
cursor: help;
}
/* -- code displays --------------------------------------------------------- */
pre {
overflow: auto;
overflow-y: hidden; /* fixes display issues on Chrome browsers */
}
pre, div[class*="highlight-"] {
clear: both;
}
span.pre {
-moz-hyphens: none;
-ms-hyphens: none;
-webkit-hyphens: none;
hyphens: none;
}
div[class*="highlight-"] {
margin: 1em 0;
}
td.linenos pre {
border: 0;
background-color: transparent;
color: #aaa;
}
table.highlighttable {
display: block;
}
table.highlighttable tbody {
display: block;
}
table.highlighttable tr {
display: flex;
}
table.highlighttable td {
margin: 0;
padding: 0;
}
table.highlighttable td.linenos {
padding-right: 0.5em;
}
table.highlighttable td.code {
flex: 1;
overflow: hidden;
}
.highlight .hll {
display: block;
}
div.highlight pre,
table.highlighttable pre {
margin: 0;
}
div.code-block-caption + div {
margin-top: 0;
}
div.code-block-caption {
margin-top: 1em;
padding: 2px 5px;
font-size: small;
}
div.code-block-caption code {
background-color: transparent;
}
table.highlighttable td.linenos,
span.linenos,
div.highlight span.gp { /* gp: Generic.Prompt */
user-select: none;
-webkit-user-select: text; /* Safari fallback only */
-webkit-user-select: none; /* Chrome/Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* IE10+ */
}
div.code-block-caption span.caption-number {
padding: 0.1em 0.3em;
font-style: italic;
}
div.code-block-caption span.caption-text {
}
div.literal-block-wrapper {
margin: 1em 0;
}
code.xref, a code {
background-color: transparent;
font-weight: bold;
}
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
background-color: transparent;
}
.viewcode-link {
float: right;
}
.viewcode-back {
float: right;
font-family: sans-serif;
}
div.viewcode-block:target {
margin: -1px -10px;
padding: 0 10px;
}
/* -- math display ---------------------------------------------------------- */
img.math {
vertical-align: middle;
}
div.body div.math p {
text-align: center;
}
span.eqno {
float: right;
}
span.eqno a.headerlink {
position: absolute;
z-index: 1;
}
div.math:hover a.headerlink {
visibility: visible;
}
/* -- printout stylesheet --------------------------------------------------- */
@media print {
div.document,
div.documentwrapper,
div.bodywrapper {
margin: 0 !important;
width: 100%;
}
div.sphinxsidebar,
div.related,
div.footer,
#top-link {
display: none;
}
}

View file

@ -1,323 +0,0 @@
/*
* doctools.js
* ~~~~~~~~~~~
*
* Sphinx JavaScript utilities for all documentation.
*
* :copyright: Copyright 2007-2021 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
/**
* select a different prefix for underscore
*/
$u = _.noConflict();
/**
* make the code below compatible with browsers without
* an installed firebug like debugger
if (!window.console || !console.firebug) {
var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
"dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
"profile", "profileEnd"];
window.console = {};
for (var i = 0; i < names.length; ++i)
window.console[names[i]] = function() {};
}
*/
/**
* small helper function to urldecode strings
*
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
*/
jQuery.urldecode = function(x) {
if (!x) {
return x
}
return decodeURIComponent(x.replace(/\+/g, ' '));
};
/**
* small helper function to urlencode strings
*/
jQuery.urlencode = encodeURIComponent;
/**
* This function returns the parsed url parameters of the
* current request. Multiple values per key are supported,
* it will always return arrays of strings for the value parts.
*/
jQuery.getQueryParameters = function(s) {
if (typeof s === 'undefined')
s = document.location.search;
var parts = s.substr(s.indexOf('?') + 1).split('&');
var result = {};
for (var i = 0; i < parts.length; i++) {
var tmp = parts[i].split('=', 2);
var key = jQuery.urldecode(tmp[0]);
var value = jQuery.urldecode(tmp[1]);
if (key in result)
result[key].push(value);
else
result[key] = [value];
}
return result;
};
/**
* highlight a given string on a jquery object by wrapping it in
* span elements with the given class name.
*/
jQuery.fn.highlightText = function(text, className) {
function highlight(node, addItems) {
if (node.nodeType === 3) {
var val = node.nodeValue;
var pos = val.toLowerCase().indexOf(text);
if (pos >= 0 &&
!jQuery(node.parentNode).hasClass(className) &&
!jQuery(node.parentNode).hasClass("nohighlight")) {
var span;
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
if (isInSVG) {
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
} else {
span = document.createElement("span");
span.className = className;
}
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
document.createTextNode(val.substr(pos + text.length)),
node.nextSibling));
node.nodeValue = val.substr(0, pos);
if (isInSVG) {
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
var bbox = node.parentElement.getBBox();
rect.x.baseVal.value = bbox.x;
rect.y.baseVal.value = bbox.y;
rect.width.baseVal.value = bbox.width;
rect.height.baseVal.value = bbox.height;
rect.setAttribute('class', className);
addItems.push({
"parent": node.parentNode,
"target": rect});
}
}
}
else if (!jQuery(node).is("button, select, textarea")) {
jQuery.each(node.childNodes, function() {
highlight(this, addItems);
});
}
}
var addItems = [];
var result = this.each(function() {
highlight(this, addItems);
});
for (var i = 0; i < addItems.length; ++i) {
jQuery(addItems[i].parent).before(addItems[i].target);
}
return result;
};
/*
* backward compatibility for jQuery.browser
* This will be supported until firefox bug is fixed.
*/
if (!jQuery.browser) {
jQuery.uaMatch = function(ua) {
ua = ua.toLowerCase();
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
/(msie) ([\w.]+)/.exec(ua) ||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
[];
return {
browser: match[ 1 ] || "",
version: match[ 2 ] || "0"
};
};
jQuery.browser = {};
jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
}
/**
* Small JavaScript module for the documentation.
*/
var Documentation = {
init : function() {
this.fixFirefoxAnchorBug();
this.highlightSearchWords();
this.initIndexTable();
if (DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) {
this.initOnKeyListeners();
}
},
/**
* i18n support
*/
TRANSLATIONS : {},
PLURAL_EXPR : function(n) { return n === 1 ? 0 : 1; },
LOCALE : 'unknown',
// gettext and ngettext don't access this so that the functions
// can safely bound to a different name (_ = Documentation.gettext)
gettext : function(string) {
var translated = Documentation.TRANSLATIONS[string];
if (typeof translated === 'undefined')
return string;
return (typeof translated === 'string') ? translated : translated[0];
},
ngettext : function(singular, plural, n) {
var translated = Documentation.TRANSLATIONS[singular];
if (typeof translated === 'undefined')
return (n == 1) ? singular : plural;
return translated[Documentation.PLURALEXPR(n)];
},
addTranslations : function(catalog) {
for (var key in catalog.messages)
this.TRANSLATIONS[key] = catalog.messages[key];
this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
this.LOCALE = catalog.locale;
},
/**
* add context elements like header anchor links
*/
addContextElements : function() {
$('div[id] > :header:first').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this headline')).
appendTo(this);
});
$('dt[id]').each(function() {
$('<a class="headerlink">\u00B6</a>').
attr('href', '#' + this.id).
attr('title', _('Permalink to this definition')).
appendTo(this);
});
},
/**
* workaround a firefox stupidity
* see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
*/
fixFirefoxAnchorBug : function() {
if (document.location.hash && $.browser.mozilla)
window.setTimeout(function() {
document.location.href += '';
}, 10);
},
/**
* highlight the search words provided in the url in the text
*/
highlightSearchWords : function() {
var params = $.getQueryParameters();
var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
if (terms.length) {
var body = $('div.body');
if (!body.length) {
body = $('body');
}
window.setTimeout(function() {
$.each(terms, function() {
body.highlightText(this.toLowerCase(), 'highlighted');
});
}, 10);
$('<p class="highlight-link"><a href="javascript:Documentation.' +
'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>')
.appendTo($('#searchbox'));
}
},
/**
* init the domain index toggle buttons
*/
initIndexTable : function() {
var togglers = $('img.toggler').click(function() {
var src = $(this).attr('src');
var idnum = $(this).attr('id').substr(7);
$('tr.cg-' + idnum).toggle();
if (src.substr(-9) === 'minus.png')
$(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
else
$(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
}).css('display', '');
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
togglers.click();
}
},
/**
* helper function to hide the search marks again
*/
hideSearchWords : function() {
$('#searchbox .highlight-link').fadeOut(300);
$('span.highlighted').removeClass('highlighted');
},
/**
* make the url absolute
*/
makeURL : function(relativeURL) {
return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
},
/**
* get the current relative url
*/
getCurrentURL : function() {
var path = document.location.pathname;
var parts = path.split(/\//);
$.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
if (this === '..')
parts.pop();
});
var url = parts.join('/');
return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
},
initOnKeyListeners: function() {
$(document).keydown(function(event) {
var activeElementType = document.activeElement.tagName;
// don't navigate when in search box, textarea, dropdown or button
if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT'
&& activeElementType !== 'BUTTON' && !event.altKey && !event.ctrlKey && !event.metaKey
&& !event.shiftKey) {
switch (event.keyCode) {
case 37: // left
var prevHref = $('link[rel="prev"]').prop('href');
if (prevHref) {
window.location.href = prevHref;
return false;
}
break;
case 39: // right
var nextHref = $('link[rel="next"]').prop('href');
if (nextHref) {
window.location.href = nextHref;
return false;
}
break;
}
}
});
}
};
// quick alias for translations
_ = Documentation.gettext;
$(document).ready(function() {
Documentation.init();
});

View file

@ -1,12 +0,0 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.10.0',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
BUILDER: 'html',
FILE_SUFFIX: '.html',
LINK_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt',
NAVIGATION_WITH_KEYS: false
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 B

File diff suppressed because one or more lines are too long

View file

@ -1,13 +0,0 @@
/*!
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE
* DISTRIBUTED UNDER THE LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
* SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING PERMISSIONS AND
* LIMITATIONS UNDER THE LICENSE.
*/@font-face{font-display:swap;font-family:"Material Icons";font-style:normal;font-weight:400;src:local("Material Icons"),local("MaterialIcons-Regular"),url("specimen/MaterialIcons-Regular.woff2") format("woff2"),url("specimen/MaterialIcons-Regular.woff") format("woff"),url("specimen/MaterialIcons-Regular.ttf") format("truetype")}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 521 B

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="352" height="448" viewBox="0 0 352 448" id="__bitbucket"><path fill="currentColor" d="M203.75 214.75q2 15.75-12.625 25.25t-27.875 1.5q-9.75-4.25-13.375-14.5t-.125-20.5 13-14.5q9-4.5 18.125-3t16 8.875 6.875 16.875zm27.75-5.25q-3.5-26.75-28.25-41T154 165.25q-15.75 7-25.125 22.125t-8.625 32.375q1 22.75 19.375 38.75t41.375 14q22.75-2 38-21t12.5-42zM291.25 74q-5-6.75-14-11.125t-14.5-5.5T245 54.25q-72.75-11.75-141.5.5-10.75 1.75-16.5 3t-13.75 5.5T60.75 74q7.5 7 19 11.375t18.375 5.5T120 93.75Q177 101 232 94q15.75-2 22.375-3t18.125-5.375T291.25 74zm14.25 258.75q-2 6.5-3.875 19.125t-3.5 21-7.125 17.5-14.5 14.125q-21.5 12-47.375 17.875t-50.5 5.5-50.375-4.625q-11.5-2-20.375-4.5T88.75 412 70.5 401.125t-13-15.375q-6.25-24-14.25-73l1.5-4 4.5-2.25q55.75 37 126.625 37t126.875-37q5.25 1.5 6 5.75t-1.25 11.25-2 9.25zM350.75 92.5q-6.5 41.75-27.75 163.75-1.25 7.5-6.75 14t-10.875 10T291.75 288q-63 31.5-152.5 22-62-6.75-98.5-34.75-3.75-3-6.375-6.625t-4.25-8.75-2.25-8.5-1.5-9.875T25 232.75q-2.25-12.5-6.625-37.5t-7-40.375T5.5 118 0 78.5Q.75 72 4.375 66.375T12.25 57t11.25-7.5T35 43.875t12-4.625q31.25-11.5 78.25-16 94.75-9.25 169 12.5Q333 47.25 348 66.25q4 5 4.125 12.75t-1.375 13.5z"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="352" height="448" viewBox="0 0 352 448" id="__bitbucket"><path fill="currentColor" d="M203.75 214.75q2 15.75-12.625 25.25t-27.875 1.5q-9.75-4.25-13.375-14.5t-.125-20.5 13-14.5q9-4.5 18.125-3t16 8.875 6.875 16.875zm27.75-5.25q-3.5-26.75-28.25-41T154 165.25q-15.75 7-25.125 22.125t-8.625 32.375q1 22.75 19.375 38.75t41.375 14q22.75-2 38-21t12.5-42zM291.25 74q-5-6.75-14-11.125t-14.5-5.5T245 54.25q-72.75-11.75-141.5.5-10.75 1.75-16.5 3t-13.75 5.5T60.75 74q7.5 7 19 11.375t18.375 5.5T120 93.75Q177 101 232 94q15.75-2 22.375-3t18.125-5.375T291.25 74zm14.25 258.75q-2 6.5-3.875 19.125t-3.5 21-7.125 17.5-14.5 14.125q-21.5 12-47.375 17.875t-50.5 5.5-50.375-4.625q-11.5-2-20.375-4.5T88.75 412 70.5 401.125t-13-15.375q-6.25-24-14.25-73l1.5-4 4.5-2.25q55.75 37 126.625 37t126.875-37q5.25 1.5 6 5.75t-1.25 11.25-2 9.25zM350.75 92.5q-6.5 41.75-27.75 163.75-1.25 7.5-6.75 14t-10.875 10T291.75 288q-63 31.5-152.5 22-62-6.75-98.5-34.75-3.75-3-6.375-6.625t-4.25-8.75-2.25-8.5-1.5-9.875T25 232.75q-2.25-12.5-6.625-37.5t-7-40.375T5.5 118 0 78.5Q.75 72 4.375 66.375T12.25 57t11.25-7.5T35 43.875t12-4.625q31.25-11.5 78.25-16 94.75-9.25 169 12.5Q333 47.25 348 66.25q4 5 4.125 12.75t-1.375 13.5z"/></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

Some files were not shown because too many files have changed in this diff Show more