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
+4 -4
View File
@@ -3,9 +3,9 @@
community.routeros.api_modify:
path: ip address
data:
- address: 172.17.0.1/16
interface: dockers
network: 172.17.0.0
- address: 172.20.0.1/24
interface: containers
network: 172.20.0.0
- address: 192.168.4.1/24
interface: lo
network: 192.168.4.0
@@ -44,7 +44,7 @@
from-pool: pool1
interface: vlan2
- address: 2001:470:61a3:500:ffff:ffff:ffff:ffff/64
interface: dockers
interface: containers
- address: 2001:470:61a3:100::1/64
advertise: false
interface: vlan4
+17 -5
View File
@@ -5,7 +5,7 @@
data:
- name: bridge1
vlan-filtering: true
- name: dockers
- name: containers
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
@@ -62,8 +62,8 @@
community.routeros.api_modify:
path: interface bridge port
data:
- bridge: dockers
interface: veth1
- bridge: containers
interface: veth-tailscale
comment: Tailscale container interface
- bridge: bridge1
interface: ether1
@@ -190,6 +190,18 @@
cache-size: 20480
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
community.routeros.api_find_and_modify:
ignore_dynamic: false
@@ -202,7 +214,7 @@
community.routeros.api_modify:
path: ip nat-pmp interfaces
data:
- interface: dockers
- interface: containers
type: internal
- interface: pppoe-gpon
type: external
@@ -223,7 +235,7 @@
community.routeros.api_modify:
path: ip upnp interfaces
data:
- interface: dockers
- interface: containers
type: internal
- interface: pppoe-gpon
type: external
+10 -33
View File
@@ -5,28 +5,12 @@
path: container config
find: {}
values:
registry-url: https://ghcr.io
tmpdir: /tmp1/pull
tmpdir: tmp
- name: Configure container env lists
community.routeros.api_modify:
path: container envs
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
data: []
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
@@ -35,11 +19,8 @@
path: container mounts
data:
- dst: /var/lib/tailscale
list: tailscale
src: /usb1/tailscale
- dst: /root
list: tailscale-root
src: /tmp1/tailscale-root
list: tailscale_state
src: tailscale/state
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
@@ -48,16 +29,12 @@
path: container
data:
- dns: 172.17.0.1
envlists: tailscale
hostname: mikrotik
interface: veth1
layer-dir: ""
mountlists: tailscale
name: tailscale-mikrotik:latest
remote-image: fluent-networks/tailscale-mikrotik:latest
root-dir: /usb1/containers/tailscale
interface: veth-tailscale
logging: true
mountlists: tailscale_state
name: tailscale
remote-image: gitea.lumpiasty.xyz/lumpiasty/mikrotik-tailscale:stable
root-dir: tailscale/root
start-on-boot: true
tmpfs: /tmp:67108864:01777
workdir: /
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
+16 -16
View File
@@ -65,8 +65,8 @@
out-interface-list: wan
- action: accept
chain: forward
comment: Allow from dockers to everywhere
in-interface: dockers
comment: Allow from containers to everywhere
in-interface: containers
- action: jump
chain: forward
comment: Allow port forwards
@@ -137,14 +137,14 @@
protocol: tcp
- action: accept
chain: input
comment: Allow DNS from dockers
comment: Allow DNS from containers
dst-port: 53
in-interface: dockers
in-interface: containers
protocol: udp
- action: accept
chain: input
dst-port: 53
in-interface: dockers
in-interface: containers
protocol: tcp
- action: accept
chain: input
@@ -188,9 +188,9 @@
protocol: udp
- action: accept
chain: input
comment: NAT-PMP from dockers (for tailscale)
comment: NAT-PMP from containers (for tailscale)
dst-port: 5351
in-interface: dockers
in-interface: containers
protocol: udp
- action: reject
chain: input
@@ -229,8 +229,8 @@
- action: accept
chain: allow-ports
comment: Allow anything udp to Tailscale
dst-address: 172.17.0.2
out-interface: dockers
dst-address: 172.20.0.2
out-interface: containers
protocol: udp
- action: accept
chain: allow-ports
@@ -419,14 +419,14 @@
out-interface-list: wan
- action: accept
chain: forward
comment: Allow from dockers to everywhere
in-interface: dockers
comment: Allow from containers to everywhere
in-interface: containers
- action: accept
chain: forward
comment: Allow from internet to dockers
comment: Allow from internet to containers
dst-address: 2001:470:61a3:500::/64
in-interface-list: wan
out-interface: dockers
out-interface: containers
- action: accept
chain: forward
comment: Allow tcp transmission port to LAN
@@ -485,14 +485,14 @@
protocol: tcp
- action: accept
chain: input
comment: Allow DNS from dockers
comment: Allow DNS from containers
dst-port: 53
in-interface: dockers
in-interface: containers
protocol: udp
- action: accept
chain: input
dst-port: 53
in-interface: dockers
in-interface: containers
protocol: tcp
- action: accept
chain: input
+36 -12
View File
@@ -39,19 +39,43 @@
loop_control:
label: "{{ item.default_name }}"
- name: Configure temporary disk for containers
community.routeros.api_modify:
# community.routeros.api_modify can't remove hardware disks
# 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
data:
- slot: tmp1
type: tmpfs
# This is not ideal, there's no unique identifier for usb disk,
# after reinstall it might be assigned to another slot
# Just adding disk with slot usb1 and not specifying anything else
# so ansible doesn't touch it
- slot: usb1
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
register: routeros_disks
check_mode: false
- name: Remove stale software-defined disk entries
community.routeros.api:
path: disk
remove: "{{ item['.id'] }}"
loop: >-
{{
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
community.routeros.api_find_and_modify:
+3 -3
View File
@@ -2,12 +2,12 @@
- name: Preflight checks
ansible.builtin.import_tasks: preflight.yml
- name: Base network configuration
ansible.builtin.import_tasks: base.yml
- name: WAN and tunnel interfaces
ansible.builtin.import_tasks: wan.yml
- name: Base network configuration
ansible.builtin.import_tasks: base.yml
- name: Hardware and platform tuning
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 }}"
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
distance: 1
dst-address: 100.64.0.0/10
gateway: 172.17.0.2
gateway: 172.20.0.2
routing-table: main
scope: 30
suppress-hw-offload: false
+95
View File
@@ -19,6 +19,101 @@
handle_absent_entries: ignore
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
community.routeros.api_find_and_modify:
ignore_dynamic: false
+3 -3
View File
@@ -29,13 +29,13 @@
community.routeros.api_modify:
path: interface veth
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
dhcp: false
gateway: 172.17.0.1
gateway: 172.20.0.1
gateway6: 2001:470:61a3:500:ffff:ffff:ffff:ffff
mac-address: 7E:7E:A1:B1:2A:7B
name: veth1
name: veth-tailscale
comment: Tailscale container
handle_absent_entries: remove
handle_entries_content: remove_as_much_as_possible
+1 -3
View File
@@ -14,6 +14,4 @@ openbao_fields:
path: wan_pppoe
username_key: username
password_key: password
routeros_tailscale_container:
path: router_tailscale
container_password_key: container_password