Skip to content

Commit 6d7b689

Browse files
committed
illumos/solaris support rebased onto main
1 parent 4ce4bb6 commit 6d7b689

21 files changed

+494
-7
lines changed

.github/workflows/cross-illumos.yaml

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: illumos-Cross
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- 'illumos-*'
8+
pull_request:
9+
branches:
10+
- '*'
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
16+
if: "!contains(github.event.head_commit.message, '[ci skip]')"
17+
18+
steps:
19+
- name: Check out code
20+
uses: actions/checkout@v3
21+
with:
22+
fetch-depth: 0
23+
24+
- name: Set up Go
25+
uses: actions/setup-go@v4
26+
with:
27+
go-version-file: 'go.mod'
28+
check-latest: true
29+
id: go
30+
31+
- name: SunOS build script
32+
run: bash -x build.sh
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
name: "tagged-release"
3+
4+
on:
5+
push:
6+
tags:
7+
- "v*-sunos"
8+
9+
jobs:
10+
tagged-release:
11+
name: "SunOS Tagged Release"
12+
runs-on: "ubuntu-latest"
13+
14+
steps:
15+
- name: Check out code
16+
uses: actions/checkout@v3
17+
with:
18+
fetch-depth: 0
19+
20+
- name: Set up Go
21+
uses: actions/setup-go@v4
22+
with:
23+
go-version-file: 'go.mod'
24+
check-latest: true
25+
id: go
26+
27+
- name: SunOS build script
28+
run: bash -x build.sh
29+
30+
- name: Create Release
31+
uses: "marvinpinto/action-automatic-releases@latest"
32+
with:
33+
repo_token: "${{ secrets.GITHUB_TOKEN }}"
34+
prerelease: false
35+
files: |
36+
cmd/tailscaled/tailscale.xml
37+
sha256sums
38+
tailscaled-illumos
39+
tailscaled-solaris

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@
1515
# company that owns the rights to your contribution.
1616

1717
Tailscale Inc.
18+
Nahum Shalman <[email protected]>

build.sh

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/bin/bash
2+
3+
set -o xtrace
4+
set -o errexit
5+
6+
export TS_USE_TOOLCHAIN=true
7+
# This prevents illumos libc from leaking into Solaris binaries when built on illumos
8+
export CGO_ENABLED=0
9+
10+
fix_osabi () {
11+
if [[ $(uname -s) == SunOS ]]; then
12+
/usr/bin/elfedit \
13+
-e "ehdr:ei_osabi ELFOSABI_SOLARIS" \
14+
-e "ehdr:ei_abiversion EAV_SUNW_CURRENT" \
15+
"${1?}"
16+
else
17+
elfedit --output-osabi "Solaris" --output-abiversion "1" "${1?}"
18+
fi
19+
}
20+
21+
for GOOS in illumos solaris; do
22+
export GOOS
23+
bash -x ./build_dist.sh --box ./cmd/tailscaled
24+
fix_osabi tailscaled
25+
mv tailscaled{,-${GOOS}}
26+
done
27+
28+
ln cmd/tailscaled/tailscale.xml .
29+
shasum -a 256 tailscaled-* tailscale.xml >sha256sums
30+
rm ./tailscale.xml
+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version='1.0'?>
2+
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
3+
<service_bundle type='manifest' name='export'>
4+
<service name='vpn/tailscale' type='service' version='0'>
5+
<create_default_instance enabled='true'/>
6+
<single_instance/>
7+
<dependency name='network' grouping='require_all' restart_on='error' type='service'>
8+
<service_fmri value='svc:/milestone/network:default'/>
9+
</dependency>
10+
<dependency name='filesystem' grouping='require_all' restart_on='error' type='service'>
11+
<service_fmri value='svc:/system/filesystem/local'/>
12+
</dependency>
13+
<method_context>
14+
<method_credential group='root' user='root'/>
15+
</method_context>
16+
<exec_method name='start' type='method' exec='/opt/local/sbin/tailscaled' timeout_seconds='60'>
17+
<method_context>
18+
<method_environment>
19+
<envvar name='SSL_CERT_FILE' value='/opt/tools/share/mozilla-rootcerts/cacert.pem'/>
20+
</method_environment>
21+
</method_context>
22+
</exec_method>
23+
<exec_method name='stop' type='method' exec=':kill' timeout_seconds='60'/>
24+
<property_group name='application' type='application'/>
25+
<property_group name='startd' type='framework'>
26+
<propval name='duration' type='astring' value='child'/>
27+
<propval name='ignore_error' type='astring' value='core,signal'/>
28+
</property_group>
29+
<stability value='Evolving'/>
30+
<template>
31+
<common_name>
32+
<loctext xml:lang='C'>Tailscale</loctext>
33+
</common_name>
34+
</template>
35+
</service>
36+
</service_bundle>

cmd/tailscaled/tailscale.xml

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?xml version='1.0'?>
2+
<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>
3+
<service_bundle type='manifest' name='export'>
4+
<service name='vpn/tailscale' type='service' version='0'>
5+
<create_default_instance enabled='true'/>
6+
<single_instance/>
7+
<dependency name='network' grouping='require_all' restart_on='error' type='service'>
8+
<service_fmri value='svc:/milestone/network:default'/>
9+
</dependency>
10+
<dependency name='filesystem' grouping='require_all' restart_on='error' type='service'>
11+
<service_fmri value='svc:/system/filesystem/local'/>
12+
</dependency>
13+
<method_context>
14+
<method_credential group='root' user='root'/>
15+
</method_context>
16+
<exec_method name='start' type='method' exec='/usr/local/sbin/tailscaled' timeout_seconds='60'/>
17+
<exec_method name='stop' type='method' exec=':kill' timeout_seconds='60'/>
18+
<property_group name='application' type='application'/>
19+
<property_group name='startd' type='framework'>
20+
<propval name='duration' type='astring' value='child'/>
21+
<propval name='ignore_error' type='astring' value='core,signal'/>
22+
</property_group>
23+
<stability value='Evolving'/>
24+
<template>
25+
<common_name>
26+
<loctext xml:lang='C'>Tailscale</loctext>
27+
</common_name>
28+
</template>
29+
</service>
30+
</service_bundle>

cmd/tailscaled/tailscaled.go

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ import (
6969
// defaultTunName returns the default tun device name for the platform.
7070
func defaultTunName() string {
7171
switch runtime.GOOS {
72+
case "illumos", "solaris":
73+
return "tun"
7274
case "openbsd":
7375
return "tun"
7476
case "windows":

derper

10.5 MB
Binary file not shown.

go.mod

+2
Original file line numberDiff line numberDiff line change
@@ -365,3 +365,5 @@ require (
365365
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
366366
sigs.k8s.io/structured-merge-diff/v4 v4.3.0 // indirect
367367
)
368+
369+
replace github.com/tailscale/wireguard-go => github.com/nshalman/wireguard-go v0.0.20200321-0.20230423150539-55df1b6c04ac

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,8 @@ github.com/nishanths/exhaustive v0.10.0 h1:BMznKAcVa9WOoLq/kTGp4NJOJSMwEpcpjFNAV
696696
github.com/nishanths/exhaustive v0.10.0/go.mod h1:IbwrGdVMizvDcIxPYGVdQn5BqWJaOwpCvg4RGb8r/TA=
697697
github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk=
698698
github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
699+
github.com/nshalman/wireguard-go v0.0.20200321-0.20230423150539-55df1b6c04ac h1:wEG2xJ+7q062tBEU8gkJvN2hC5RpZWhEIWAug5LUC0k=
700+
github.com/nshalman/wireguard-go v0.0.20200321-0.20230423150539-55df1b6c04ac/go.mod h1:J62uaH3KrbhKtrKXQJ6/Z+kcs0r4CdA7qd5AXQtl0/s=
699701
github.com/nunnatsa/ginkgolinter v0.11.2 h1:xzQpAsEyZe5F1RMy2Z5kn8UFCGiWfKqJOUd2ZzBXA4M=
700702
github.com/nunnatsa/ginkgolinter v0.11.2/go.mod h1:dJIGXYXbkBswqa/pIzG0QlVTTDSBMxDoCFwhsl4Uras=
701703
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
@@ -884,8 +886,6 @@ github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85 h1:zrsUcqrG2uQ
884886
github.com/tailscale/netlink v1.1.1-0.20211101221916-cabfb018fe85/go.mod h1:NzVQi3Mleb+qzq8VmcWpSkcSYxXIg0DkI6XDzpVkhJ0=
885887
github.com/tailscale/web-client-prebuilt v0.0.0-20230919211114-7bcd7bca7bc5 h1:wKUtQPRpjhZZvAuwYRMcjMZnpWSUEJWIbNJmLtDbR0k=
886888
github.com/tailscale/web-client-prebuilt v0.0.0-20230919211114-7bcd7bca7bc5/go.mod h1:agQPE6y6ldqCOui2gkIh7ZMztTkIQKH049tv8siLuNQ=
887-
github.com/tailscale/wireguard-go v0.0.0-20231101022006-db7604d1aa90 h1:lMGYrokOq9NKDw1UMBH7AsS4boZ41jcduvYaRIdedhE=
888-
github.com/tailscale/wireguard-go v0.0.0-20231101022006-db7604d1aa90/go.mod h1:BOm5fXUBFM+m9woLNBoxI9TaBXXhGNP50LX/TGIvGb4=
889889
github.com/tc-hib/winres v0.2.1 h1:YDE0FiP0VmtRaDn7+aaChp1KiF4owBiJa5l964l5ujA=
890890
github.com/tc-hib/winres v0.2.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk=
891891
github.com/tcnksm/go-httpstat v0.2.0 h1:rP7T5e5U2HfmOBmZzGgGZjBQ5/GluWUylujl0tJ04I0=

ipn/ipnlocal/local.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -3156,7 +3156,7 @@ func (b *LocalBackend) peerAPIServicesLocked() (ret []tailcfg.Service) {
31563156
})
31573157
}
31583158
switch runtime.GOOS {
3159-
case "linux", "freebsd", "openbsd", "illumos", "darwin", "windows", "android", "ios":
3159+
case "linux", "freebsd", "openbsd", "illumos", "solaris", "darwin", "windows", "android", "ios":
31603160
// These are the platforms currently supported by
31613161
// net/dns/resolver/tsdns.go:Resolver.HandleExitNodeDNSQuery.
31623162
ret = append(ret, tailcfg.Service{

ipn/ipnstate/ipnstate.go

+2
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,8 @@ func osEmoji(os string) string {
617617
return "🐡"
618618
case "illumos":
619619
return "☀️"
620+
case "solaris":
621+
return "🌤️"
620622
}
621623
return "👽"
622624
}

net/dns/manager_default.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Tailscale Inc & AUTHORS
22
// SPDX-License-Identifier: BSD-3-Clause
33

4-
//go:build !linux && !freebsd && !openbsd && !windows && !darwin
4+
//go:build !linux && !freebsd && !openbsd && !windows && !darwin && !illumos && !solaris
55

66
package dns
77

net/dns/manager_solaris.go

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) Tailscale Inc & AUTHORS
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
4+
package dns
5+
6+
import (
7+
"tailscale.com/types/logger"
8+
)
9+
10+
func NewOSConfigurator(logf logger.Logf, _ string) (OSConfigurator, error) {
11+
return newDirectManager(logf), nil
12+
}

net/dns/resolver/tsdns.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ func (r *Resolver) HandlePeerDNSQuery(ctx context.Context, q []byte, from netip.
350350
// but for now that's probably good enough. Later we'll
351351
// want to blend in everything from scutil --dns.
352352
fallthrough
353-
case "linux", "freebsd", "openbsd", "illumos", "ios":
353+
case "linux", "freebsd", "openbsd", "illumos", "solaris", "ios":
354354
nameserver, err := stubResolverForOS()
355355
if err != nil {
356356
r.logf("stubResolverForOS: %v", err)

net/netutil/ip_forward.go

+27
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"fmt"
1010
"net/netip"
1111
"os"
12+
"os/exec"
1213
"path/filepath"
1314
"runtime"
1415
"strconv"
@@ -62,6 +63,11 @@ func CheckIPForwarding(routes []netip.Prefix, state *interfaces.State) (warn, er
6263
switch runtime.GOOS {
6364
case "dragonfly", "freebsd", "netbsd", "openbsd":
6465
return fmt.Errorf("Subnet routing and exit nodes only work with additional manual configuration on %v, and is not currently officially supported.", runtime.GOOS), nil
66+
case "illumos", "solaris":
67+
_, err := ipForwardingEnabledSunOS(ipv4, "")
68+
if err != nil {
69+
return nil, fmt.Errorf("Couldn't check system's IP forwarding configuration, subnet routing/exit nodes may not work: %w%s", err, "")
70+
}
6571
}
6672
return nil, nil
6773
}
@@ -221,3 +227,24 @@ func ipForwardingEnabledLinux(p protocol, iface string) (bool, error) {
221227
on := val == 1 || val == 2
222228
return on, nil
223229
}
230+
231+
func ipForwardingEnabledSunOS(p protocol, iface string) (bool, error) {
232+
var proto string
233+
if p == ipv4 {
234+
proto = "ipv4"
235+
} else if p == ipv6 {
236+
proto = "ipv6"
237+
} else {
238+
return false, fmt.Errorf("unknown protocol")
239+
}
240+
241+
ipadmCmd := "\"ipadm show-prop " + proto + " -p forwarding -o CURRENT -c\""
242+
bs, err := exec.Command("ipadm", "show-prop", proto, "-p", "forwarding", "-o", "CURRENT", "-c").Output()
243+
if err != nil {
244+
return false, fmt.Errorf("couldn't check %s (%v).\nSubnet routes won't work without IP forwarding.", ipadmCmd, err)
245+
}
246+
if string(bs) != "on\n" {
247+
return false, fmt.Errorf("IP forwarding is set to off. Subnet routes won't work. Try 'routeadm -u -e " + proto + "-forwarding'")
248+
}
249+
return true, nil
250+
}

paths/paths_unix.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func init() {
2222

2323
func statePath() string {
2424
switch runtime.GOOS {
25-
case "linux":
25+
case "linux", "illumos", "solaris":
2626
return "/var/lib/tailscale/tailscaled.state"
2727
case "freebsd", "openbsd":
2828
return "/var/db/tailscale/tailscaled.state"

tool/go

+6
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,10 @@
44
# currently-desired version from https://github.com/tailscale/go,
55
# downloading it first if necessary.
66

7+
case $(uname -s) in
8+
SunOS)
9+
exec go "$@"
10+
;;
11+
esac
12+
713
exec "$(dirname "$0")/../tool/gocross/gocross-wrapper.sh" "$@"

wgengine/router/router_default.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Tailscale Inc & AUTHORS
22
// SPDX-License-Identifier: BSD-3-Clause
33

4-
//go:build !windows && !linux && !darwin && !openbsd && !freebsd
4+
//go:build !windows && !linux && !darwin && !openbsd && !freebsd && !illumos && !solaris
55

66
package router
77

wgengine/router/router_solaris.go

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (c) Tailscale Inc & AUTHORS
2+
// SPDX-License-Identifier: BSD-3-Clause
3+
4+
package router
5+
6+
import (
7+
"strings"
8+
9+
"github.com/tailscale/wireguard-go/tun"
10+
"tailscale.com/types/logger"
11+
"tailscale.com/net/netmon"
12+
)
13+
14+
// For now this router only supports the userspace WireGuard implementations.
15+
16+
func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *netmon.Monitor) (Router, error) {
17+
return newUserspaceSunosRouter(logf, tundev, linkMon)
18+
}
19+
20+
func cleanup(logf logger.Logf, interfaceName string) {
21+
ipadm := []string{"ipadm", "show-addr", "-p", "-o", "addrobj"}
22+
out, err := cmd(ipadm...).Output()
23+
if err != nil {
24+
logf("ipadm show-addr: %v\n%s", err, out)
25+
}
26+
for _, a := range strings.Fields(string(out)) {
27+
s := strings.Split(a, "/")
28+
if len(s) > 1 && strings.Contains(s[1], "tailscale") {
29+
ipadm = []string{"ipadm", "down-addr", "-t", a}
30+
cmdVerbose(logf, ipadm)
31+
ipadm = []string{"ipadm", "delete-addr", a}
32+
cmdVerbose(logf, ipadm)
33+
ipadm = []string{"ipadm", "delete-if", s[0]}
34+
cmdVerbose(logf, ipadm)
35+
}
36+
}
37+
ifcfg := []string{"ifconfig", interfaceName, "unplumb"}
38+
if out, err := cmd(ifcfg...).CombinedOutput(); err != nil {
39+
logf("ifconfig unplumb: %v\n%s", err, out)
40+
}
41+
ifcfg = []string{"ifconfig", interfaceName, "inet6", "unplumb"}
42+
if out, err := cmd(ifcfg...).CombinedOutput(); err != nil {
43+
logf("ifconfig inet6 unplumb: %v\n%s", err, out)
44+
}
45+
}

0 commit comments

Comments
 (0)