はじめに
TailscaleはWireguardベースのVPNソフトウェアで、Windows, MacOS, LinuxやAndroidに公式で対応しています。もちろんiOSにも対応していますが、最低要求バージョンは15.0となっています。当方の環境はiPhoneX iOS14.3ですので、アプリは利用できません。よってソースからビルドしようというわけです。下記の手順は自己責任でお願いします。
iOS向けにBuildは可能か
TailscaleはGo languageで書かれています。
READMEに従って
GOOS=darwin GOARCH=arm64 ./build_dist.sh tailscale.com/cmd/tailscale
GOOS=darwin GOARCH=arm64 ./build_dist.sh tailscale.com/cmd/tailscaled
ここでのポイントはMシリーズのMac向けにビルドすることです。
まず、前提としてiOSとOSXはともにdarwinカーネル上で動作します。Apple Mシリーズはarm64アーキテクチャであり、これはiPhone5s以降のシリーズと共通しています。よって理論上はMシリーズMac向けにコンパイルされたバイナリはiOSで利用可能です。
Binaryの実行
buildしたバイナリを実機に移して実行してみます。
./tailscale
dyld: Library not loaded: /usr/lib/libSystem.B.dylib
Referenced from: /private/var/mobile/tailscale_tools/./tailscale
Reason: mach-o, but not built for platform macOS
Abort trap: 6
はい、エラーです。
重要なのは4行目、iOS向けにビルドされていないことを示しています。 ということで、Mach-oバイナリのヘッダにあるロードコマンドを見ていきましょう。
otool -l tailscale
*略*
Load command 6
cmd LC_BUILD_VERSION
cmdsize 24
platform 1
minos 11.0
sdk 11.0
ntools 0
*略*
dyldはplatformの値を読み取り、適したバイナリかどうか判断しています。platformに対応する数字は、SDKのmach-o/loader.hに定義されています。iOSに対応するのは"2"ですから、バイナリを直接編集して変更します。
書き換え&実行
platformの値を01から02へ変更して保存、そしてresignして実行してみます。(*1)
ldid -S tailscale
./tailscale
dyld: Library not loaded: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
Referenced from: /private/var/mobile/tailscale_tools/./tailscale
Reason: image not found
Abort trap: 6
一筋縄ではいきません。iOSではCoreFoundationのpathは/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
ではなく、/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
となっていますので、変更します。(実体はdyld_shared_cache)
また、Security.frameworkに対しても同様の処理をしておきます。
llvm-install-name-tool -change /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation tailscale
llvm-install-name-tool -change /System/Library/Frameworks/Security.frameork/Versions/A/Security /System/Library/Frameworks/Security.frameork/Security tailscale
これでOKです。resignして実行します。
ldid -S tailscale
./tailscale version
1.51.0
track: unstable (dev); frequent updates and bugs are likely
tailscale commit: ef596aed9b9b7b27e6a1d8e15a5a5ce9abf413b5-dirty
go version: go1.21.3
見事実行できました。この一連の処理をtailscaledにも適用すれば、目標達成です。
あとはtailscaledを実行後、公式の手順通りにtailscale up
を実行してsigninすればアクセス可能になります。
まとめ
ポイントはロードコマンド内のplatformを1から2へ変更でした。また、今回はバイナリを直接編集しましたが、xcode付属のvtoolでも変更できるようです。
最後に
ご質問や訂正すべきポイント等あれば是非お知らせください。ここまで読んでいただき大変ありがとうございました。
補足
*1) unc0ver環境ではこれでresign出来ますが、他の環境(checkra1nなど)ではldid -S/usr/share/entitlements/ld64.xml tailscale
のようにentitlementの指定が必要となる可能性があります。