Change Tailscale distribution
ci/woodpecker/push/flux-reconcile-source Pipeline was successful

gitea.lumpiasty.xyz/Lumpiasty/tailscale-mikrotik allows us to move tailscale to internal flash
This commit is contained in:
2026-06-02 17:29:22 +02:00
parent af4a7fee48
commit 1b66a8c230
13 changed files with 189 additions and 100 deletions
-1
View File
@@ -39,7 +39,6 @@ Secret layout expected in OpenBao (KVv2, mount `secret`):
|---|---| |---|---|
| `routeros_api` | `username`, `password` | | `routeros_api` | `username`, `password` |
| `wan_pppoe` | `username`, `password` | | `wan_pppoe` | `username`, `password` |
| `router_tailscale` | `container_password` |
## OpenWrt dlink AP ## OpenWrt dlink AP
+3 -8
View File
@@ -39,15 +39,10 @@
engine_mount_point=openbao_kv_mount engine_mount_point=openbao_kv_mount
).secret[openbao_fields.wan_pppoe.password_key] ).secret[openbao_fields.wan_pppoe.password_key]
}} }}
routeros_tailscale_container_password: >-
{{
lookup(
'community.hashi_vault.vault_kv2_get',
openbao_fields.routeros_tailscale_container.path,
engine_mount_point=openbao_kv_mount
).secret[openbao_fields.routeros_tailscale_container.container_password_key]
}}
no_log: true no_log: true
tags:
- tailscale-script
module_defaults: module_defaults:
group/community.routeros.api: group/community.routeros.api:
+4 -4
View File
@@ -3,9 +3,9 @@
community.routeros.api_modify: community.routeros.api_modify:
path: ip address path: ip address
data: data:
- address: 172.17.0.1/16 - address: 172.20.0.1/24
interface: dockers interface: containers
network: 172.17.0.0 network: 172.20.0.0
- address: 192.168.4.1/24 - address: 192.168.4.1/24
interface: lo interface: lo
network: 192.168.4.0 network: 192.168.4.0
@@ -44,7 +44,7 @@
from-pool: pool1 from-pool: pool1
interface: vlan2 interface: vlan2
- address: 2001:470:61a3:500:ffff:ffff:ffff:ffff/64 - address: 2001:470:61a3:500:ffff:ffff:ffff:ffff/64
interface: dockers interface: containers
- address: 2001:470:61a3:100::1/64 - address: 2001:470:61a3:100::1/64
advertise: false advertise: false
interface: vlan4 interface: vlan4
+17 -5
View File
@@ -5,7 +5,7 @@
data: data:
- name: bridge1 - name: bridge1
vlan-filtering: true vlan-filtering: true
- name: dockers - name: containers
handle_absent_entries: remove handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible handle_entries_content: remove_as_much_as_possible
@@ -62,8 +62,8 @@
community.routeros.api_modify: community.routeros.api_modify:
path: interface bridge port path: interface bridge port
data: data:
- bridge: dockers - bridge: containers
interface: veth1 interface: veth-tailscale
comment: Tailscale container interface comment: Tailscale container interface
- bridge: bridge1 - bridge: bridge1
interface: ether1 interface: ether1
@@ -190,6 +190,18 @@
cache-size: 20480 cache-size: 20480
servers: 1.1.1.1,1.0.0.1,2606:4700:4700::1111,2606:4700:4700::1001 servers: 1.1.1.1,1.0.0.1,2606:4700:4700::1111,2606:4700:4700::1001
- name: Configure DNS static entries
community.routeros.api_modify:
path: ip dns static
data:
- name: ts.net
type: FWD
forward-to: 100.100.100.100
match-subdomain: true
comment: Tailscale MagicDNS
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
- name: Configure NAT-PMP global settings - name: Configure NAT-PMP global settings
community.routeros.api_find_and_modify: community.routeros.api_find_and_modify:
ignore_dynamic: false ignore_dynamic: false
@@ -202,7 +214,7 @@
community.routeros.api_modify: community.routeros.api_modify:
path: ip nat-pmp interfaces path: ip nat-pmp interfaces
data: data:
- interface: dockers - interface: containers
type: internal type: internal
- interface: pppoe-gpon - interface: pppoe-gpon
type: external type: external
@@ -223,7 +235,7 @@
community.routeros.api_modify: community.routeros.api_modify:
path: ip upnp interfaces path: ip upnp interfaces
data: data:
- interface: dockers - interface: containers
type: internal type: internal
- interface: pppoe-gpon - interface: pppoe-gpon
type: external type: external
+10 -33
View File
@@ -5,28 +5,12 @@
path: container config path: container config
find: {} find: {}
values: values:
registry-url: https://ghcr.io tmpdir: tmp
tmpdir: /tmp1/pull
- name: Configure container env lists - name: Configure container env lists
community.routeros.api_modify: community.routeros.api_modify:
path: container envs path: container envs
data: data: []
- key: ADVERTISE_ROUTES
list: tailscale
value: 192.168.0.0/24,192.168.1.0/24,192.168.4.1/32,192.168.100.1/32,192.168.255.0/24,10.42.0.0/16,10.43.0.0/16,10.44.0.0/16,2001:470:61a3::/48
- key: CONTAINER_GATEWAY
list: tailscale
value: 172.17.0.1
- key: PASSWORD
list: tailscale
value: "{{ routeros_tailscale_container_password }}"
- key: TAILSCALE_ARGS
list: tailscale
value: --accept-routes --advertise-exit-node --snat-subnet-routes=false
- key: UPDATE_TAILSCALE
list: tailscale
value: y
handle_absent_entries: remove handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible handle_entries_content: remove_as_much_as_possible
@@ -35,11 +19,8 @@
path: container mounts path: container mounts
data: data:
- dst: /var/lib/tailscale - dst: /var/lib/tailscale
list: tailscale list: tailscale_state
src: /usb1/tailscale src: tailscale/state
- dst: /root
list: tailscale-root
src: /tmp1/tailscale-root
handle_absent_entries: remove handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible handle_entries_content: remove_as_much_as_possible
@@ -48,16 +29,12 @@
path: container path: container
data: data:
- dns: 172.17.0.1 - dns: 172.17.0.1
envlists: tailscale interface: veth-tailscale
hostname: mikrotik logging: true
interface: veth1 mountlists: tailscale_state
layer-dir: "" name: tailscale
mountlists: tailscale remote-image: gitea.lumpiasty.xyz/lumpiasty/mikrotik-tailscale:stable
name: tailscale-mikrotik:latest root-dir: tailscale/root
remote-image: fluent-networks/tailscale-mikrotik:latest
root-dir: /usb1/containers/tailscale
start-on-boot: true start-on-boot: true
tmpfs: /tmp:67108864:01777
workdir: /
handle_absent_entries: remove handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible handle_entries_content: remove_as_much_as_possible
+16 -16
View File
@@ -65,8 +65,8 @@
out-interface-list: wan out-interface-list: wan
- action: accept - action: accept
chain: forward chain: forward
comment: Allow from dockers to everywhere comment: Allow from containers to everywhere
in-interface: dockers in-interface: containers
- action: jump - action: jump
chain: forward chain: forward
comment: Allow port forwards comment: Allow port forwards
@@ -137,14 +137,14 @@
protocol: tcp protocol: tcp
- action: accept - action: accept
chain: input chain: input
comment: Allow DNS from dockers comment: Allow DNS from containers
dst-port: 53 dst-port: 53
in-interface: dockers in-interface: containers
protocol: udp protocol: udp
- action: accept - action: accept
chain: input chain: input
dst-port: 53 dst-port: 53
in-interface: dockers in-interface: containers
protocol: tcp protocol: tcp
- action: accept - action: accept
chain: input chain: input
@@ -188,9 +188,9 @@
protocol: udp protocol: udp
- action: accept - action: accept
chain: input chain: input
comment: NAT-PMP from dockers (for tailscale) comment: NAT-PMP from containers (for tailscale)
dst-port: 5351 dst-port: 5351
in-interface: dockers in-interface: containers
protocol: udp protocol: udp
- action: reject - action: reject
chain: input chain: input
@@ -229,8 +229,8 @@
- action: accept - action: accept
chain: allow-ports chain: allow-ports
comment: Allow anything udp to Tailscale comment: Allow anything udp to Tailscale
dst-address: 172.17.0.2 dst-address: 172.20.0.2
out-interface: dockers out-interface: containers
protocol: udp protocol: udp
- action: accept - action: accept
chain: allow-ports chain: allow-ports
@@ -419,14 +419,14 @@
out-interface-list: wan out-interface-list: wan
- action: accept - action: accept
chain: forward chain: forward
comment: Allow from dockers to everywhere comment: Allow from containers to everywhere
in-interface: dockers in-interface: containers
- action: accept - action: accept
chain: forward chain: forward
comment: Allow from internet to dockers comment: Allow from internet to containers
dst-address: 2001:470:61a3:500::/64 dst-address: 2001:470:61a3:500::/64
in-interface-list: wan in-interface-list: wan
out-interface: dockers out-interface: containers
- action: accept - action: accept
chain: forward chain: forward
comment: Allow tcp transmission port to LAN comment: Allow tcp transmission port to LAN
@@ -485,14 +485,14 @@
protocol: tcp protocol: tcp
- action: accept - action: accept
chain: input chain: input
comment: Allow DNS from dockers comment: Allow DNS from containers
dst-port: 53 dst-port: 53
in-interface: dockers in-interface: containers
protocol: udp protocol: udp
- action: accept - action: accept
chain: input chain: input
dst-port: 53 dst-port: 53
in-interface: dockers in-interface: containers
protocol: tcp protocol: tcp
- action: accept - action: accept
chain: input chain: input
+36 -12
View File
@@ -39,19 +39,43 @@
loop_control: loop_control:
label: "{{ item.default_name }}" label: "{{ item.default_name }}"
- name: Configure temporary disk for containers # community.routeros.api_modify can't remove hardware disks
community.routeros.api_modify: # but it tries to do so with handle_absent_entries: remove
# Working around by manually deleting other ones
- name: Read current disk entries
community.routeros.api_info:
path: disk path: disk
data: register: routeros_disks
- slot: tmp1 check_mode: false
type: tmpfs
# This is not ideal, there's no unique identifier for usb disk, - name: Remove stale software-defined disk entries
# after reinstall it might be assigned to another slot community.routeros.api:
# Just adding disk with slot usb1 and not specifying anything else path: disk
# so ansible doesn't touch it remove: "{{ item['.id'] }}"
- slot: usb1 loop: >-
handle_absent_entries: remove {{
handle_entries_content: remove_as_much_as_possible routeros_disks.result
| rejectattr('type', 'in', ['hardware', 'partition'])
| rejectattr('slot', 'equalto', 'tmp')
}}
loop_control:
label: "{{ item.slot }}"
- name: Create temporary disk for containers if absent
community.routeros.api:
path: disk
add: "slot=tmp type=tmpfs"
when: routeros_disks.result | selectattr('slot', 'equalto', 'tmp') | list | length == 0
- name: Configure temporary disk for containers
community.routeros.api_find_and_modify:
ignore_dynamic: false
path: disk
find:
slot: tmp
values:
type: tmpfs
- name: Configure switch settings - name: Configure switch settings
community.routeros.api_find_and_modify: community.routeros.api_find_and_modify:
+3 -3
View File
@@ -2,12 +2,12 @@
- name: Preflight checks - name: Preflight checks
ansible.builtin.import_tasks: preflight.yml ansible.builtin.import_tasks: preflight.yml
- name: Base network configuration
ansible.builtin.import_tasks: base.yml
- name: WAN and tunnel interfaces - name: WAN and tunnel interfaces
ansible.builtin.import_tasks: wan.yml ansible.builtin.import_tasks: wan.yml
- name: Base network configuration
ansible.builtin.import_tasks: base.yml
- name: Hardware and platform tuning - name: Hardware and platform tuning
ansible.builtin.import_tasks: hardware.yml ansible.builtin.import_tasks: hardware.yml
@@ -32,15 +32,4 @@
fail_msg: "RouterOS device-mode does not report container as enabled. Payload: {{ routeros_device_mode | to_nice_json }}" fail_msg: "RouterOS device-mode does not report container as enabled. Payload: {{ routeros_device_mode | to_nice_json }}"
success_msg: "RouterOS device-mode confirms container=yes" success_msg: "RouterOS device-mode confirms container=yes"
- name: Read configured disks
community.routeros.api_info:
path: disk
register: routeros_disks
check_mode: false
- name: Assert usb1 disk is present
ansible.builtin.assert:
that:
- (routeros_disks.result | selectattr('slot', 'equalto', 'usb1') | list | length) > 0
fail_msg: "Required disk slot usb1 is not present on router."
success_msg: "Required disk usb1 is present"
+1 -1
View File
@@ -7,7 +7,7 @@
disabled: false disabled: false
distance: 1 distance: 1
dst-address: 100.64.0.0/10 dst-address: 100.64.0.0/10
gateway: 172.17.0.2 gateway: 172.20.0.2
routing-table: main routing-table: main
scope: 30 scope: 30
suppress-hw-offload: false suppress-hw-offload: false
+95
View File
@@ -19,6 +19,101 @@
handle_absent_entries: ignore handle_absent_entries: ignore
handle_entries_content: remove_as_much_as_possible handle_entries_content: remove_as_much_as_possible
# The RouterOS API can neither store multi-line script source (newlines
# collapse into one line) nor evaluate the [/file/get ...] expression itself.
# So we fetch the update logic as a .rsc file onto the router's flash, then run
# a single-line bootstrap script (which the API CAN store) whose body RouterOS
# evaluates natively: it builds the real, browsable, multi-line named script
# from the file via [/file get ... contents]. The scheduler then runs that
# named script by name (the upstream-intended design). The update logic stays
# out of this repo entirely.
- name: Download tailscale auto-update script to router
community.routeros.api:
path: tool
cmd: >-
fetch
url=https://gitea.lumpiasty.xyz/Lumpiasty/mikrotik-tailscale/raw/branch/main/routeros/update-tailscale.rsc
dst-path=update-tailscale.rsc
mode=https
changed_when: true
tags:
- tailscale-script
- name: Build the named auto-update script from the fetched file
community.routeros.api:
path: system script
cmd: >-
add name=update-tailscale-bootstrap
source=":do { /system script remove update-tailscale } on-error={};
/system script add name=update-tailscale
comment=\"Check for mikrotik-tailscale image updates\"
source=[/file get update-tailscale.rsc contents]"
changed_when: true
tags:
- tailscale-script
- name: Find bootstrap script id
community.routeros.api:
path: system script
extended_query:
attributes: [.id, name]
where:
- attribute: name
is: "=="
value: update-tailscale-bootstrap
register: routeros_bootstrap
changed_when: false
tags:
- tailscale-script
- name: Run bootstrap to create the named auto-update script
community.routeros.api:
path: system script
cmd: "run .id={{ routeros_bootstrap.msg[0]['.id'] }}"
register: routeros_bootstrap_run
failed_when:
- routeros_bootstrap_run is failed
- "'interrupted' not in (routeros_bootstrap_run.msg | string)"
changed_when: true
tags:
- tailscale-script
- name: Verify named auto-update script exists
community.routeros.api:
path: system script
extended_query:
attributes: [.id, name]
where:
- attribute: name
is: "=="
value: update-tailscale
register: routeros_named_script
failed_when: (routeros_named_script.msg | length) == 0
changed_when: false
tags:
- tailscale-script
- name: Remove bootstrap script
community.routeros.api:
path: system script
remove: "{{ routeros_bootstrap.msg[0]['.id'] }}"
changed_when: true
tags:
- tailscale-script
- name: Configure tailscale auto-update scheduler
community.routeros.api_modify:
path: system scheduler
data:
- name: update-tailscale
interval: 1d
on-event: /system script run update-tailscale
comment: Check for mikrotik-tailscale image updates
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
tags:
- tailscale-script
- name: Configure service ports and service enablement - name: Configure service ports and service enablement
community.routeros.api_find_and_modify: community.routeros.api_find_and_modify:
ignore_dynamic: false ignore_dynamic: false
+3 -3
View File
@@ -29,13 +29,13 @@
community.routeros.api_modify: community.routeros.api_modify:
path: interface veth path: interface veth
data: data:
- address: 172.17.0.2/16,2001:470:61a3:500::1/64 - address: 172.20.0.2/24,2001:470:61a3:500::1/64
container-mac-address: 7E:7E:A1:B1:2A:7C container-mac-address: 7E:7E:A1:B1:2A:7C
dhcp: false dhcp: false
gateway: 172.17.0.1 gateway: 172.20.0.1
gateway6: 2001:470:61a3:500:ffff:ffff:ffff:ffff gateway6: 2001:470:61a3:500:ffff:ffff:ffff:ffff
mac-address: 7E:7E:A1:B1:2A:7B mac-address: 7E:7E:A1:B1:2A:7B
name: veth1 name: veth-tailscale
comment: Tailscale container comment: Tailscale container
handle_absent_entries: remove handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible handle_entries_content: remove_as_much_as_possible
+1 -3
View File
@@ -14,6 +14,4 @@ openbao_fields:
path: wan_pppoe path: wan_pppoe
username_key: username username_key: username
password_key: password password_key: password
routeros_tailscale_container:
path: router_tailscale
container_password_key: container_password