Forward incoming tailnet connections to the host's primary interface
Proposed Changes
TLDR: Without this, users have to enable subnet routing only to access the host, really different user experience compared to the general Tailscale client (and when there are multiple 192.168.1.x subnets, more trouble).
This is identical what Tailscale's docker image does (here). Though compared to Tailscale's docker image, this PR is using only -A append, that is less intrusive than -I insert.
When userspace networking is enabled, tailscaled automatically forwards incoming tailnet connections to localhost. Not in TS docs, only an issue comment (here), but tested and true. Without this, there would be no way to access anything on the host.
When userspace networking is disabled, tailscaled doesn't do anything, but in a container, services not running on all interfaces will not be accessible on tailscale0 interface, and by default they are running only on the HA managed interfaces.
I've added a config switch to be able to disable this forwarding in case it interferes with some complex networking setup.
UPDATE: Tested with real subnet routing, rPI3, rPI4, HA OS VM, userspace_networking enabled/disabled, snat_subnet_routes enabled/disables, stateful_filtering enabled/disabled, it didn't interfere with these settings.
Related Issues
Summary by CodeRabbit
- New Features
- Introduced enhanced network forwarding for Tailscale integration, supporting both IPv4 and IPv6.
- Added dynamic management of forwarding rules with improved logging for better connectivity.
- Enabled a streamlined, one-time execution mode for the forwarding service.
- Integrated conditional logic to disable network forwarding based on specific configuration settings.
Walkthrough
Adds an s6 service "forwarding" with oneshot type and scripts to set up iptables/ip6tables DNAT forwarding at startup and remove those rules at shutdown; stage2_hook now disables this service when userspace networking is enabled or not configured.
Changes
| Cohort / File(s) | Change Summary |
|---|---|
Forwarding service scriptstailscale/rootfs/etc/s6-overlay/s6-rc.d/forwarding/* |
Added service files: run (sets up IPv4/IPv6 DNAT forwarding using iptables/ip6tables), finish (removes DNAT rules on shutdown), up (service up marker), and type (contains oneshot). |
Stage2 hook updatetailscale/rootfs/etc/s6-overlay/scripts/stage2_hook.sh |
Inserted conditional block to disable the forwarding service when userspace-networking is enabled or unset by removing its s6 contents link. |
Sequence Diagram(s)
sequenceDiagram
participant S6 as "s6 service manager"
participant Run as "forwarding/run"
participant IPGet as "tailscale IP lookup"
participant HostGet as "host IP lookup"
participant IPT as "iptables / ip6tables"
S6->>Run: start forwarding (oneshot)
Run->>IPGet: get Tailscale IPv4/IPv6
IPGet-->>Run: return addresses
Run->>HostGet: get host IPv4/IPv6
HostGet-->>Run: return host addresses
Run->>IPT: check existing rules
Run->>IPT: append DNAT rules for IPv4/IPv6
IPT-->>Run: ack rules appended
Run->>S6: exit (oneshot complete)
sequenceDiagram
participant S6 as "s6 service manager"
participant Finish as "forwarding/finish"
participant IPT as "iptables / ip6tables"
S6->>Finish: run finish on shutdown
Finish->>IPT: find DNAT rules matching Tailscale src
Finish->>IPT: delete matched DNAT rules
IPT-->>Finish: ack deletion
Finish->>S6: finish complete
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
- hassio-addons/addon-tailscale#507 — modifies
stage2_hook.shand affects forwarding/local-network startup behavior; likely related changes to service enabling/disabling.
Suggested labels
new-feature
Poem
I'm a rabbit in the networking glen,
Hopping rules where packets wend.
I set the paths and clear the tracks,
Forwarding in, cleaning up the backs.
Carrots for routes and code for friends 🐇✨
✨ Finishing Touches
- [ ] 📝 Generate Docstrings
🧪 Generate unit tests
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
🪧 Tips
Chat
There are 3 ways to chat with CodeRabbit:
- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
I pushed a fix in commit <commit_id>, please review it.Open a follow-up GitHub issue for this discussion.
- Files and specific lines of code (under the "Files changed" tab): Tag
@coderabbitaiin a new review comment at the desired location with your query. - PR comments: Tag
@coderabbitaiin a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
Support
Need help? Create a ticket on our support page for assistance with any issues or questions.
CodeRabbit Commands (Invoked using PR/Issue comments)
Type @coderabbitai help to get the list of available commands.
Other keywords and placeholders
- Add
@coderabbitai ignoreor@coderabbit ignoreanywhere in the PR description to prevent this PR from being reviewed. - Add
@coderabbitai summaryto generate the high-level summary at a specific location in the PR description. - Add
@coderabbitaianywhere in the PR title to generate the title automatically.
CodeRabbit Configuration File (.coderabbit.yaml)
- You can programmatically configure CodeRabbit by adding a
.coderabbit.yamlfile to the root of your repository. - Please see the configuration documentation for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation:
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
Status, Documentation and Community
- Visit our Status Page to check the current availability of CodeRabbit.
- Visit our Documentation for detailed information on how to use CodeRabbit.
- Join our Discord Community to get help, request features, and share feedback.
- Follow us on X/Twitter for updates and announcements.
:white_check_mark: Actions performed
Review triggered.
Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.
TLDR: Without this, users have to enable subnet routing only to access the host
yes! Great, right? They decide?
eally different user experience compared to the general Tailscale client
Yup, tailscale was never designed to run from the container.
Without this, there would be no way to access anything on the host.
I'm not really sure if that is an disadvantage?
Removed the option and the docs, now this is always enabled when userspace_networking is disabled.
There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days. Thank you for your contributions.
not stale
There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days. Thank you for your contributions.
still not stale
Nothing to add, but I am keen on having this change included too. Thanks @lmagyar.
There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days. Thank you for your contributions.