# Running Gateway on MikroTik routers

By leveraging the ability of some MikroTik routers to run Docker containers, it is possible to deploy the gateway directly on your router.

{% hint style="warning" %}
Proceed with extra caution when working with your core infrastructure. All official [RouterOS containers warnings](https://help.mikrotik.com/docs/display/ROS/Container#Container-Disclaimer) still apply.
{% endhint %}

{% hint style="danger" %}
Running the gateway on a MikroTik router is not fully supported.

Due to custom RouterOS kernel incompatibility this kind of deployment does not support [Access Control List](https://docs.defguard.net/2.0/features/access-control-list) functionality.

To run the gateway you must explicitly disable firewall management using the [`DEFGUARD_DISABLE_FW_MGMT` option](https://docs.defguard.net/2.0/configuration#gateway-configuration).
{% endhint %}

## Prerequisites

* RouterOS device with ARM or ARM64 architecture (popular home lab choices include RB4011 or RB5009)
* `Container` package installed and enabled
* Running Defguard core instance with a WireGuard location configured
* (optional) Self-signed certificate generated by following [gRPC SSL setup guide](https://docs.defguard.net/2.0/deployment-strategies/grpc-ssl-communication)

## Setup

{% hint style="warning" %}
This guide assumes you do not have other Docker containers deployed on your router yet. If this is not the case adjust accordingly.

The same applies if you have some more specific network configuration requirements.
{% endhint %}

{% hint style="info" %}
For brevity we'll be using RouterOS terminal commands, but everything can also be accomplished through WinBox GUI.
{% endhint %}

### Prepare network to install Docker container

* First create a bridge interface for Docker containers and assign it an IP address in a dedicated Docker subnet (`172.17.0.0/24` in our example):

```
/interface/bridge/add name=docker
/ip/address/add address=172.17.0.1/24 interface=docker
```

* Each container must have a dedicated VETH interface; create a `veth1` interface and assign it an IP address in the chosen Docker subnet:

```
/interface/veth/add name=veth1 address=172.17.0.2/24 gateway=172.17.0.1
```

* Add the virtual interface to the Docker bridge:

```
/interface/bridge/port add bridge=docker interface=veth1
```

### Setup firewall rules

* Set up NAT for outgoing traffic from containers:

```
/ip/firewall/nat/add chain=srcnat action=masquerade src-address=172.17.0.0/24
```

* Add port forwarding rule to send UDP traffic from the public WireGuard port to the gateway container:

```
/ip/firewall/nat/add chain=dstnat protocol=udp dst-address=<YOUR PUBLIC IP> dst-port=<YOUR PUBLIC WG PORT> action=dst-nat to-addresses=172.17.0.2 to-ports=<YOUR PUBLIC WG PORT>
```

{% hint style="warning" %}
Container port being forwarded to must match your public WireGuard port.
{% endhint %}

* Add routing for your chosen WireGuard subnet configured in Defguard UI location settings:

```
/ip/route/add dst-address=<YOUR WG SUBNET> gateway=172.17.0.2
```

### Run gateway container

* Configure environment variables for the gateway container:

```
/container/envs/add name=defguard_env key=DEFGUARD_TOKEN value=<YOUR TOKEN>
/container/envs/add name=defguard_env key=DEFGUARD_GRPC_URL value=<YOUR DEFGUARD GRPC URL>
/container/envs/add name=defguard_env key=DEFGUARD_DISABLE_FW_MGMT value=true
```

* (optional) To use SSL for communication between the gateway and your Defguard instance copy the root certificate to your router's filesystem and add a following mount and environment variable:

```
/container/mounts/add name=defguard_cert src=<PATH TO CERT DIR> dst=/certs
/container/envs/add name=defguard_env key=DEFGUARD_GRPC_CA value=/certs/myCA.pem
```

{% hint style="warning" %}
Put the root certificate in a directory and mount the whole directory. Trying to mount a specific file can cause unexpected issues.
{% endhint %}

* Add GitHub container registry to config:

```
/container/config/set registry-url=https://ghcr.io
```

* Finally, create the actual container:

```
/container/add remote-image=ghcr.io/defguard/gateway:latest interface=veth1 envlist=defguard_env
```

At this point you should see that the gateway is connected in your Defguard instance's web UI.
