├── .gitattributes ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── build.sh ├── sshd_config ├── tailscale.sh └── upgrade.rsc /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | tailscale/ 3 | build-multi.sh 4 | tailscale.tar 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Fluent Networks Inc & AUTHORS All rights reserved. 2 | # Use of this source code is governed by a BSD-style 3 | # license that can be found in the LICENSE file. 4 | 5 | ############################################################################ 6 | # 7 | # WARNING: Tailscale is not yet officially supported in Docker, 8 | # Kubernetes, etc. 9 | # 10 | # It might work, but we don't regularly test it, and it's not as polished as 11 | # our currently supported platforms. This is provided for people who know 12 | # how Tailscale works and what they're doing. 13 | # 14 | # Our tracking bug for officially support container use cases is: 15 | # https://github.com/tailscale/tailscale/issues/504 16 | # 17 | # Also, see the various bugs tagged "containers": 18 | # https://github.com/tailscale/tailscale/labels/containers 19 | # 20 | ############################################################################ 21 | 22 | FROM golang:1.23-alpine AS build-env 23 | 24 | WORKDIR /go/src/tailscale 25 | 26 | COPY tailscale/go.mod tailscale/go.sum ./ 27 | RUN go mod download 28 | 29 | RUN apk add --no-cache upx 30 | 31 | # Pre-build some stuff before the following COPY line invalidates the Docker cache. 32 | RUN go install \ 33 | github.com/aws/aws-sdk-go-v2/aws \ 34 | github.com/aws/aws-sdk-go-v2/config \ 35 | gvisor.dev/gvisor/pkg/tcpip/adapters/gonet \ 36 | gvisor.dev/gvisor/pkg/tcpip/stack \ 37 | golang.org/x/crypto/ssh \ 38 | golang.org/x/crypto/acme \ 39 | github.com/coder/websocket \ 40 | github.com/mdlayher/netlink 41 | 42 | COPY tailscale/. . 43 | 44 | # see build.sh 45 | ARG VERSION_LONG="" 46 | ENV VERSION_LONG=$VERSION_LONG 47 | ARG VERSION_SHORT="" 48 | ENV VERSION_SHORT=$VERSION_SHORT 49 | ARG VERSION_GIT_HASH="" 50 | ENV VERSION_GIT_HASH=$VERSION_GIT_HASH 51 | ARG TARGETARCH 52 | 53 | RUN GOARCH=$TARGETARCH go install -ldflags="-w -s\ 54 | -X tailscale.com/version.Long=$VERSION_LONG \ 55 | -X tailscale.com/version.Short=$VERSION_SHORT \ 56 | -X tailscale.com/version.GitCommit=$VERSION_GIT_HASH" \ 57 | -v ./cmd/tailscale ./cmd/tailscaled 58 | 59 | RUN upx /go/bin/tailscale && upx /go/bin/tailscaled 60 | 61 | FROM alpine:3.19 62 | 63 | RUN apk add --no-cache ca-certificates iptables iptables-legacy iproute2 bash openssh curl jq 64 | 65 | RUN rm /sbin/iptables && ln -s /sbin/iptables-legacy /sbin/iptables 66 | RUN rm /sbin/ip6tables && ln -s /sbin/ip6tables-legacy /sbin/ip6tables 67 | 68 | RUN ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa 69 | RUN ssh-keygen -f /etc/ssh/ssh_host_dsa_key -N '' -t dsa 70 | 71 | COPY --from=build-env /go/bin/* /usr/local/bin/ 72 | COPY sshd_config /etc/ssh/ 73 | COPY tailscale.sh /usr/local/bin 74 | 75 | EXPOSE 22 76 | CMD ["/usr/local/bin/tailscale.sh"] 77 | 78 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2024 Fluent Networks Pty Ltd & AUTHORS. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tailscale for Mikrotik Container 2 | 3 | This project provides build and configuration information to run [Tailscale](https://tailscale.com) in [Mikrotik Container](https://help.mikrotik.com/docs/display/ROS/Container). Container is Mikrotik's own implementation of Docker(TM), allowing users to run containerized environments within RouterOS. 4 | 5 | This project is only recommended for research and testing purposes. Note the container can impact router performance: running a IPerf test of 50 Mbps via the container on a Mikrotik hAP ax3 consumes ~30% of the router's CPU. 6 | 7 | The instructions below assume a use case for tailscale-enabled hosts accessing a router connected LAN subnet. Both Tailscale and Headscale control servers are supported. 8 | 9 | Other site to site scenarios are outlined in the [project wiki](https://github.com/Fluent-networks/tailscale-mikrotik/wiki). 10 | 11 | ## Requirements 12 | 13 | The Mikrotik Container package is compatible with ARM, ARM64 and x86 architectures and the router must be be running RouterOS v7.6 or later. Refer to the [Mikrotik Container documentation](https://help.mikrotik.com/docs/display/ROS/Container) for recommendations, disclaimer and security risks. 14 | 15 | ## Instructions 16 | 17 | The example container runs as a [tailscale subnet router](https://tailscale.com/kb/1019/subnets/) on a Mikrotik hAP ac3. There are two subnets configured: 18 | 19 | * 192.168.88.0/24: the default bridge with physical LAN interface ports, routed to the tailscale network 20 | * 172.17.0.0/16: the docker bridge with a virtual ethernet (veth) interface port for the container 21 | 22 | A WAN interface is configured as per default configuration on **ether1** for connectivity to the Tailscale Network. 23 | 24 | Note storage of the docker image on the router uses a USB drive mounted as **disk1** due to the limited storage (128MB) available on the router. To configure storage devices see the [Mikrotik Disks guide](https://help.mikrotik.com/docs/display/ROS/Disks). 25 | 26 | ### Build the Docker Image 27 | 28 | **Note**: this step is only required if you are uploading a tar image file to your router as per Configuration Step 6b. 29 | 30 | The build script uses [Docker Buildx](https://docs.docker.com/buildx/working-with-buildx/). 31 | 32 | 1. In `build.sh` set the PLATFORM shell script variable as required for the target router CPU - see [https://mikrotik.com/products/matrix](https://mikrotik.com/products/matrix) 33 | 34 | 2. Run `./build.sh` to build the image. The build process will generate a container image archive file **`tailscale.tar`** 35 | 36 | ### Configure the Router 37 | 38 | This section follows the Mikrotik Container documentation with additional steps to route the LAN subnet via the tailscale container. 39 | 40 | 41 | 1. Enable container mode, and reboot. 42 | 43 | ``` 44 | /system/device-mode/update container=yes 45 | ``` 46 | 47 | 2. Create a veth interface for the container. 48 | 49 | ``` 50 | /interface/veth add name=veth1 address=172.17.0.2/16 gateway=172.17.0.1 51 | ``` 52 | 53 | 3. Create a bridge for the container and add veth1 as a port. 54 | 55 | ``` 56 | /interface/bridge add name=dockers 57 | /ip/address add address=172.17.0.1/16 interface=dockers 58 | /interface/bridge/port add bridge=dockers interface=veth1 59 | ``` 60 | 61 | 4. Enable routing from the LAN to the Tailscale Network 62 | 63 | ``` 64 | /ip/route/add dst-address=100.64.0.0/10 gateway=172.17.0.2 65 | ``` 66 | 67 | 5. Add environment variables and container mount 68 | 69 | | Variable | Description | Comment | 70 | | ----------------- | --------------------------------------------- | -------------------------------------------- | 71 | | PASSWORD | System root user password | | 72 | | AUTH_KEY | Tailscale non-reusable key, [Oauth secret](https://tailscale.com/kb/1215/oauth-clients#registering-new-nodes-using-oauth-credentials) or Headscale pre-authenticated key | Generate from the Tailscale console or Headscale CLI | 73 | | ADVERTISE_ROUTES | Comma-separated list of routes to advertise | | 74 | | CONTAINER_GATEWAY | The container bridge (veth1) IP address on the router | | 75 | | LOGIN_SERVER | Headscale login server | Only required for Headscale control server. Do not set if using Tailscale | 76 | | UPDATE_TAILSCALE | Update tailscale on container startup | | 77 | | TAILSCALE_ARGS | Additional arguments passed to tailscale | Optional. Note: 78 | ```--accept-routes``` is required to accept the advertised routes of the other subnet routers. 79 | ```--netfilter-mode``` controls the degree of firewall configuration using iptables. See [tailscale up](https://tailscale.com/kb/1241/tailscale-up). | 80 | | TAILSCALED_ARGS | Additional arguments passed to tailscaled | Optional | 81 | | STARTUP_SCRIPT | Extra script to execute in container before tailscaled | Optional | 82 | 83 | Example Tailscale control server configuration: 84 | ``` 85 | /container/envs 86 | add name="tailscale" key="PASSWORD" value="xxxxxxxxxxxxxx" 87 | add name="tailscale" key="AUTH_KEY" value="tskey-xxxxxxxxxxxxxxxxxxxxxxxx" 88 | add name="tailscale" key="ADVERTISE_ROUTES" value="192.168.88.0/24" 89 | add name="tailscale" key="CONTAINER_GATEWAY" value="172.17.0.1" 90 | add name="tailscale" key="UPDATE_TAILSCALE" 91 | add name="tailscale" key="TAILSCALE_ARGS" value="--accept-routes --advertise-exit-node" 92 | ``` 93 | Example Headscale control server configuration: 94 | ``` 95 | /container/envs 96 | add name="tailscale" key="PASSWORD" value="xxxxxxxxxxxxxx" 97 | add name="tailscale" key="AUTH_KEY" value="xxxxxxxxxxxxxxxxxxxxxxxxxxxx" 98 | add name="tailscale" key="ADVERTISE_ROUTES" value="192.168.88.0/24" 99 | add name="tailscale" key="CONTAINER_GATEWAY" value="172.17.0.1" 100 | add name="tailscale" key="LOGIN_SERVER" value="http://headscale.example.com:8080" 101 | add name="tailscale" key="TAILSCALE_ARGS" value="--accept-routes --advertise-exit-node" 102 | ``` 103 | 104 | Define the the mount as per below. 105 | 106 | ``` 107 | /container mounts 108 | add name="tailscale" src="/tailscale" dst="/var/lib/tailscale" 109 | ``` 110 | 111 | It's possible to execute extra script during container startup. To do this, firstly make sure that script is accessible inside 112 | container. For example put it to `/var/lib/tailscale` folder and then add `STARTUP_SCRIPT` environment variable: 113 | 114 | ``` 115 | /container/envs 116 | add name="tailscale" key="STARTUP_SCRIPT" value="/var/lib/tailscale/startup.sh" 117 | ``` 118 | 119 | 6. Create the container 120 | 121 | The container can be created via the container registry (Step 6a) or using the `tailscale.tar` file generated by building the Docker image locally (Step 6b or 6c). 122 | 123 | 6a. Container registry 124 | 125 | Configure the registry URL and add the container. 126 | 127 | ``` 128 | /container/config 129 | set registry-url=https://ghcr.io tmpdir=disk1/pull 130 | 131 | /container add remote-image=fluent-networks/tailscale-mikrotik:latest interface=veth1 envlist=tailscale root-dir=disk1/containers/tailscale mounts=tailscale start-on-boot=yes hostname=mikrotik dns=8.8.4.4,8.8.8.8 132 | ``` 133 | 134 | 6b. Tar archive file 135 | 136 | Using the file `tailscale.tar` generated by running `build.sh`, upload the file to your router. Below we assume the image has been uploaded to the router as `disk1/tailscale.tar` 137 | 138 | ``` 139 | /container add file=disk1/tailscale.tar interface=veth1 envlist=tailscale root-dir=disk1/containers/tailscale mounts=tailscale start-on-boot=yes hostname=mikrotik dns=8.8.4.4,8.8.8.8 140 | ``` 141 | 142 | If you want to see the container output in the router log add `logging=yes` to the container add command. 143 | 144 | 6c. Tar archive file (routers without external storage) 145 | 146 | For routers without USB port (tested on hAP ax2) it's possible to use ramdisk to temporary store `tailscale.tar` file. 147 | 148 | Firstly make sure that there is no old version of container installed. Firstly create `tmpfs` disk: 149 | 150 | ``` 151 | /disk add type=tmpfs tmpfs-max-size=200M 152 | ``` 153 | Upload `tailscale.tar` file to `tmp1/` disk (or move it after uploading to root folder) 154 | 155 | Then start container like in 6b: 156 | 157 | ``` 158 | /container add file=tmp1/tailscale.tar interface=veth1 envlist=tailscale root-dir=containers/tailscale mounts=tailscale start-on-boot=yes hostname=mikrotik dns=8.8.4.4,8.8.8.8 159 | ``` 160 | 161 | Router will unpack tarball to internal storage. Once container is created it's ok to remove tarball from `tmpfs`. Also, 162 | container will be preserved after router reboot. 163 | 164 | ### Start the Container 165 | 166 | Ensure the container has been extracted and added by verifying `status=stopped` using `/container/print` 167 | 168 | ``` 169 | /container/start 0 170 | ``` 171 | 172 | ### Verify Connectivity 173 | 174 | In the Tailscale console, check the router is authenticated and enable the subnet routes. Your tailscale hosts should now be able to reach the router's LAN subnet. 175 | 176 | The container exposes a SSH server for management purposes using root credentials, and can be accessed via the router's tailscale address or the veth interface address. Alternatively, you can access the container via the router CLI: 177 | 178 | ``` 179 | /container/shell 0 180 | bash-5.1# 181 | ``` 182 | 183 | ## Upgrading 184 | 185 | ### Manual 186 | To upgrade, first stop and remove the container. 187 | 188 | ``` 189 | /container/stop 0 190 | /container/remove 0 191 | ``` 192 | 193 | Create the upgraded container as per Step 6. 194 | 195 | ### Via Script 196 | The script **upgrade.rsc** automates the upgrade process. To use the script, edit the *hostname* variable to match your container 197 | and import the script - note the script assumes the container repository is being used. 198 | 199 | ``` 200 | /system script add name=upgrade source=[ /file get upgrade.rsc contents]; 201 | ``` 202 | 203 | Run the script: 204 | ``` 205 | /system script 206 | run [find name="upgrade"]; 207 | 208 | Stopping the container... 209 | Waiting for the container to stop... 210 | Waiting for the container to stop... 211 | Waiting for the container to stop... 212 | Stopped. 213 | Removing the container... 214 | Waiting for the container to be removed... 215 | Removed. 216 | Adding the container... 217 | Waiting for the container to be added... 218 | Waiting for the container to be added... 219 | Waiting for the container to be added... 220 | Waiting for the container to be added... 221 | Waiting for the container to be added... 222 | Waiting for the container to be added... 223 | Added. 224 | Starting the container. 225 | ``` 226 | 227 | Note the script will continue to run if you are connecting over the tailnet. When completed, check the router is authenticated and enable the subnet routes in the Tailscale console. 228 | 229 | ## Contributing 230 | 231 | We welcome suggestions and feedback from people interested in integrating Tailscale on the RouterOS platform. Please send a PR or create an issue if you're having any problems. -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | # Copyright (c) 2024 Fluent Networks Pty Ltd & AUTHORS All rights reserved. 3 | # Use of this source code is governed by a BSD-style 4 | # license that can be found in the LICENSE file. 5 | # 6 | # Updates tailscale respository and runs `docker build` with flags configured for 7 | # docker distribution. 8 | # 9 | ############################################################################ 10 | # 11 | # WARNING: Tailscale is not yet officially supported in Docker, 12 | # Kubernetes, etc. 13 | # 14 | # It might work, but we don't regularly test it, and it's not as polished as 15 | # our currently supported platforms. This is provided for people who know 16 | # how Tailscale works and what they're doing. 17 | # 18 | # Our tracking bug for officially support container use cases is: 19 | # https://github.com/tailscale/tailscale/issues/504 20 | # 21 | # Also, see the various bugs tagged "containers": 22 | # https://github.com/tailscale/tailscale/labels/containers 23 | # 24 | ############################################################################ 25 | # 26 | # Set PLATFORM as required for your router model. See: 27 | # https://mikrotik.com/products/matrix 28 | # 29 | PLATFORM="linux/amd64" 30 | TAILSCALE_VERSION=1.78.1 31 | VERSION=0.1.35 32 | 33 | set -eu 34 | 35 | rm -f tailscale.tar 36 | 37 | if [ ! -d ./tailscale/.git ] 38 | then 39 | git -c advice.detachedHead=false clone https://github.com/tailscale/tailscale.git --branch v$TAILSCALE_VERSION 40 | fi 41 | 42 | TS_USE_TOOLCHAIN="Y" 43 | cd tailscale && eval $(./build_dist.sh shellvars) && cd .. 44 | 45 | docker buildx build \ 46 | --no-cache \ 47 | --build-arg TAILSCALE_VERSION=$TAILSCALE_VERSION \ 48 | --build-arg VERSION_LONG=$VERSION_LONG \ 49 | --build-arg VERSION_SHORT=$VERSION_SHORT \ 50 | --build-arg VERSION_GIT_HASH=$VERSION_GIT_HASH \ 51 | --platform $PLATFORM \ 52 | --load -t ghcr.io/fluent-networks/tailscale-mikrotik:$VERSION . 53 | 54 | docker save -o tailscale.tar ghcr.io/fluent-networks/tailscale-mikrotik:$VERSION 55 | -------------------------------------------------------------------------------- /sshd_config: -------------------------------------------------------------------------------- 1 | # $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $ 2 | 3 | # This is the sshd server system-wide configuration file. See 4 | # sshd_config(5) for more information. 5 | 6 | # This sshd was compiled with PATH=/bin:/usr/bin:/sbin:/usr/sbin 7 | 8 | # The strategy used for options in the default sshd_config shipped with 9 | # OpenSSH is to specify options with their default value where 10 | # possible, but leave them commented. Uncommented options override the 11 | # default value. 12 | 13 | #Port 22 14 | #AddressFamily any 15 | #ListenAddress 0.0.0.0 16 | #ListenAddress :: 17 | 18 | #HostKey /etc/ssh/ssh_host_rsa_key 19 | #HostKey /etc/ssh/ssh_host_ecdsa_key 20 | #HostKey /etc/ssh/ssh_host_ed25519_key 21 | 22 | # Ciphers and keying 23 | #RekeyLimit default none 24 | 25 | # Logging 26 | #SyslogFacility AUTH 27 | #LogLevel INFO 28 | 29 | # Authentication: 30 | 31 | #LoginGraceTime 2m 32 | PermitRootLogin yes 33 | #StrictModes yes 34 | #MaxAuthTries 6 35 | #MaxSessions 10 36 | 37 | #PubkeyAuthentication yes 38 | 39 | # The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2 40 | # but this is overridden so installations will only check .ssh/authorized_keys 41 | AuthorizedKeysFile .ssh/authorized_keys 42 | 43 | #AuthorizedPrincipalsFile none 44 | 45 | #AuthorizedKeysCommand none 46 | #AuthorizedKeysCommandUser nobody 47 | 48 | # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts 49 | #HostbasedAuthentication no 50 | # Change to yes if you don't trust ~/.ssh/known_hosts for 51 | # HostbasedAuthentication 52 | #IgnoreUserKnownHosts no 53 | # Don't read the user's ~/.rhosts and ~/.shosts files 54 | #IgnoreRhosts yes 55 | 56 | # To disable tunneled clear text passwords, change to no here! 57 | #PasswordAuthentication yes 58 | #PermitEmptyPasswords no 59 | 60 | # Change to no to disable s/key passwords 61 | #ChallengeResponseAuthentication yes 62 | 63 | # Kerberos options 64 | #KerberosAuthentication no 65 | #KerberosOrLocalPasswd yes 66 | #KerberosTicketCleanup yes 67 | #KerberosGetAFSToken no 68 | 69 | # GSSAPI options 70 | #GSSAPIAuthentication no 71 | #GSSAPICleanupCredentials yes 72 | 73 | # Set this to 'yes' to enable PAM authentication, account processing, 74 | # and session processing. If this is enabled, PAM authentication will 75 | # be allowed through the ChallengeResponseAuthentication and 76 | # PasswordAuthentication. Depending on your PAM configuration, 77 | # PAM authentication via ChallengeResponseAuthentication may bypass 78 | # the setting of "PermitRootLogin without-password". 79 | # If you just want the PAM account and session checks to run without 80 | # PAM authentication, then enable this but set PasswordAuthentication 81 | # and ChallengeResponseAuthentication to 'no'. 82 | #UsePAM no 83 | 84 | #AllowAgentForwarding yes 85 | # Feel free to re-enable these if your use case requires them. 86 | AllowTcpForwarding no 87 | GatewayPorts no 88 | X11Forwarding no 89 | #X11DisplayOffset 10 90 | #X11UseLocalhost yes 91 | #PermitTTY yes 92 | #PrintMotd yes 93 | #PrintLastLog yes 94 | #TCPKeepAlive yes 95 | #PermitUserEnvironment no 96 | #Compression delayed 97 | #ClientAliveInterval 0 98 | #ClientAliveCountMax 3 99 | #UseDNS no 100 | #PidFile /run/sshd.pid 101 | #MaxStartups 10:30:100 102 | #PermitTunnel no 103 | #ChrootDirectory none 104 | #VersionAddendum none 105 | 106 | # no default banner path 107 | #Banner none 108 | 109 | # override default of no subsystems 110 | Subsystem sftp /usr/lib/ssh/sftp-server 111 | 112 | # Example of overriding settings on a per-user basis 113 | #Match User anoncvs 114 | # X11Forwarding no 115 | # AllowTcpForwarding no 116 | # PermitTTY no 117 | # ForceCommand cvs server 118 | -------------------------------------------------------------------------------- /tailscale.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) 2024 Fluent Networks Pty Ltd & AUTHORS All rights reserved. 3 | # Use of this source code is governed by a BSD-style 4 | # license that can be found in the LICENSE file. 5 | 6 | set -m 7 | 8 | # Enable IP forwarding 9 | echo 'net.ipv4.ip_forward = 1' | tee -a /etc/sysctl.conf 10 | echo 'net.ipv6.conf.all.forwarding = 1' | tee -a /etc/sysctl.conf 11 | sysctl -p /etc/sysctl.conf 12 | 13 | # Prepare run dirs 14 | if [ ! -d "/var/run/sshd" ]; then 15 | mkdir -p /var/run/sshd 16 | fi 17 | 18 | # Set root password 19 | echo "root:${PASSWORD}" | chpasswd 20 | 21 | # Install routes 22 | IFS=',' read -ra SUBNETS <<< "${ADVERTISE_ROUTES}" 23 | for s in "${SUBNETS[@]}"; do 24 | ip route add "$s" via "${CONTAINER_GATEWAY}" 25 | done 26 | 27 | # Perform an update if set 28 | if [[ ! -z "${UPDATE_TAILSCALE+x}" ]]; then 29 | /usr/local/bin/tailscale update --yes 30 | fi 31 | 32 | # Set login server for tailscale 33 | if [[ -z "$LOGIN_SERVER" ]]; then 34 | LOGIN_SERVER=https://controlplane.tailscale.com 35 | fi 36 | 37 | if [[ -n "$STARTUP_SCRIPT" ]]; then 38 | bash "$STARTUP_SCRIPT" || exit $? 39 | fi 40 | 41 | # Start tailscaled and bring tailscale up 42 | /usr/local/bin/tailscaled ${TAILSCALED_ARGS} & 43 | until /usr/local/bin/tailscale up \ 44 | --reset --authkey="${AUTH_KEY}" \ 45 | --login-server "${LOGIN_SERVER}" \ 46 | --advertise-routes="${ADVERTISE_ROUTES}" \ 47 | ${TAILSCALE_ARGS} 48 | do 49 | sleep 0.1 50 | done 51 | echo Tailscale started 52 | 53 | # Start SSH 54 | /usr/sbin/sshd -D 55 | 56 | fg %1 57 | -------------------------------------------------------------------------------- /upgrade.rsc: -------------------------------------------------------------------------------- 1 | # Container identifier 2 | :local hostname "mikrotik-west-1"; 3 | 4 | /container 5 | :local id [find where hostname=$hostname]; 6 | :local rootdir [get $id root-dir]; 7 | :local dns [get $id dns]; 8 | :local logging [get $id logging]; 9 | :local status [get $id status]; 10 | :local mounts [get $id mounts]; 11 | :local envlist [get $id envlist]; 12 | :local interface [get $id interface]; 13 | :local startonboot [get $id start-on-boot]; 14 | :global LogPrefix "Tailscale"; 15 | 16 | :local logI do={ 17 | :global LogPrefix; 18 | :put ($LogPrefix . ": " . $1); 19 | :log info ($LogPrefix . ": " . $1); 20 | } 21 | 22 | # Stop the container 23 | $logI "Stopping the container..."; 24 | stop $id 25 | :while ($status != "stopped") do={ 26 | $logI "Waiting for the container to stop..."; 27 | :delay 5; 28 | :set status [get $id status]; 29 | } 30 | $logI "Stopped."; 31 | 32 | # Remove the container 33 | remove $id 34 | $logI "Removing the container..."; 35 | :while ($status = "stopped") do={ 36 | $logI "Waiting for the container to be removed..."; 37 | :delay 5; 38 | :set status [get $id status]; 39 | } 40 | $logI "Removed."; 41 | 42 | # Add the container 43 | :delay 5; 44 | $logI "Adding the container..."; 45 | add remote-image=fluent-networks/tailscale-mikrotik:latest \ 46 | interface=$interface envlist=$envlist root-dir=$rootdir mounts=$mounts\ 47 | start-on-boot=$startonboot hostname=$hostname dns=$dns logging=$logging 48 | :do { 49 | :set status [get [find where hostname=$hostname] status]; 50 | :if ($status != "stopped") do={ 51 | $logI "Waiting for the container to be added..."; 52 | :delay 5; 53 | } 54 | } while ($status != "stopped") 55 | $logI "Added." 56 | 57 | # Start the container 58 | $logI "Starting the container."; 59 | :set id [find where hostname=$hostname]; 60 | start $id 61 | --------------------------------------------------------------------------------