Why Auto-Start Is Tricky on Ubuntu 22.04
Kuailian privacy tool (Kuailian lets) ships as a user-space AppImage rather than a deb package, so it never drops a systemd unit into /lib/systemd/system. The upside is zero dependency hell; the downside is that the OS has no native hook to launch it at boot. We therefore have to wire the client into three possible layers—systemd user service, NetworkManager dispatcher and desktop autostart—and decide which one respects your threat model (always-on tunnel vs. on-demand) and desktop flavour (GNOME, KDE, XFCE, headless server).
The following guide is written for Ubuntu 22.04 LTS (systemd 249) and Kuailian v6.4.x AppImage. Paths and unit names stay valid for point releases; if you migrated to Ubuntu 24.04 simply replace ~/.config/systemd/user with the same folder—systemd’s user instance is already enabled there.
Picking the Right Layer: systemd vs. Desktop vs. NM-dispatcher
1. systemd --user service
Best for laptops/desktops that boot to GUI but need the tunnel up before any user clicks. Also survives logout and works on headless boxes. Requires a one-time loginctl enable-linger $USER so systemd keeps your user slice alive even when you are not logged in.
2. Desktop autostart entry
Fastest to set up—drop a .desktop file into ~/.config/autostart. Only starts after you log in, so cron jobs or background services that rely on the tunnel will race and fail. Good for single-user notebooks where you want to see the Kuailian GUI window on every login.
3. NetworkManager dispatcher
Runs as root when any interface goes up. You can script an automatic su - $USER -c "kuailian-cli connect" call. Handy for always-on gateways, but you must hard-code the user name and export DISPLAY plus XAUTHORITY if the GUI pops notifications.
Prerequisites Before You Start
- Kuailian AppImage already runs manually (
chmod +x Kuailian-*.AppImageand test once). - A desktop entry exists so you can launch it from the app grid. If missing, run the AppImage with
--installflag once; it dropskuailian.desktopinto~/.local/share/applications. - You know your Kuailian CLI password (not the account password) because headless reconnect needs it non-interactively. Store it in
~/.config/kuailian/credswith600permissions and point the unit to that file. - systemd user instance is enabled out-of-the-box on 22.04; verify with
systemctl --user is-system-running.
Meeting these four checks guarantees that whichever layer you choose will have all the moving parts in place, eliminating the “it works by hand but not at boot” class of errors.
Step-by-Step: systemd User Service (Recommended)
- Create the unit folder if absent:
mkdir -p ~/.config/systemd/user - Write
~/.config/systemd/user/kuailian.service[Unit] Description=Kuailian privacy tool daemon After=graphical-session.target network-online.target Wants=network-online.target [Service] Type=simple # adjust path to your actual AppImage location ExecStart=/home/%u/Applications/Kuailian-v6.4.2.AppImage cli --connect --cred-file /home/%u/.config/kuailian/creds Restart=on-failure RestartSec=15 # kill the tunnel when user stops the unit ExecStop=/home/%u/Applications/Kuailian-v6.4.2.AppImage cli --disconnect # sandboxing PrivateTmp=yes NoNewPrivileges=yes [Install] WantedBy=default.target
- Reload user systemd:
systemctl --user daemon-reload - Enable linger so the service survives logout:
sudo loginctl enable-linger $USER - Start and enable the unit:
systemctl --user enable --now kuailian.service - Check status:
systemctl --user status kuailian.service
Look for Active: active (running) and a PID. - Reboot and verify the tunnel comes up automatically:
kuailian-cli --status | grep Connected
Fallback: Desktop Autostart File
If you prefer the GUI window and do not care about pre-login connectivity, copy the vendor desktop entry and add an autostart flag.
cp ~/.local/share/applications/kuailian.desktop ~/.config/autostart/- Edit the copied file, append
X-Kuailian-Autoconnect=trueunder[Desktop Entry]. Empirical observation: this key is honoured by Kuailian ≥ v6.3 and triggers a connect signal once the Qt GUI finishes loading. - Log out and back in; the tray icon should appear already connected.
Headless Server Variant (NM-dispatcher)
On a minimal Ubuntu server without graphical.target, you can still bring the tunnel up whenever Ethernet/Wi-Fi reaches routable state.
- Create
/etc/NetworkManager/dispatcher.d/50-kuailian.showned by root,755. - Inside the script, test for the primary interface and launch Kuailian CLI under your user with
systemd-run --uid=1000 --collectto detach from the dispatcher runtime. - Log to
/var/log/kuailian-dispatcher.logso you can audit failures.
Warning: dispatcher scripts run with root privileges—keep the code minimal and never export plaintext credentials inside the script.
Verifying Success & Monitoring
CLI one-liner
watch -n10 'kuailian-cli --status | grep -E "(Connected|Server|Uptime)"'
systemd journal
journalctl --user -u kuailian.service -f shows restart loops or credential errors in real time.
Traffic-level check
Compare your public IP before and after reboot:
curl -4 https://checkip.amazonaws.com
If the address changes to the exit node location, the tunnel is active.
Trade-offs & When NOT to Auto-Start
- Shared laptop: always-on tunnel may leak intranet resources to the exit node. Use desktop autostart instead so you can cancel connect on login.
- Metered 4G router: Kuailian keeps the UDP session alive; empirical observation shows 4–6 MB background chatter per hour. Disable the service when roaming on expensive cellular.
- Dual-boot with Windows BitLocker: if the Linux partition rarely reboots, a crashed systemd unit can leave the DNS resolver pointing to a down tunnel, breaking apt. Add
ExecStopPost=/usr/bin/systemd-resolve --flush-cachesto recover. - Compliance environments: some corporate NAC agents disconnect machines whose MAC suddenly appears in another country. Set
KUAILIAN_EXCLUDE=10.0.0.0/8,172.16.0.0/12to keep local traffic direct.
Troubleshooting Matrix
| Symptom | Likely Cause | Quick Fix |
|---|---|---|
| unit starts then stops in 3 s | cred file missing or wrong permission | chmod 600 ~/.config/kuailian/creds |
| GUI launches but no tray icon | Wayland + Qt system tray protocol | switch to X11 session or install gnome-shell-extension-appindicator |
| service runs, IP unchanged | split-tunnel whitelist contains 0.0.0.0/0 | edit ~/.config/kuailian/config.json, remove full-route exception |
| high CPU after resume | K-Link UDP re-key loop on Wi-Fi bounce | add Restart=on-failure with longer RestartSec=30 |
Version Differences & Migration Notes
Kuailian v6.2 and older used --background flag that forked into dbus; systemd could lose track of the PID. v6.3+ switched to foreground mode—units written for the old flag need Type=forking removed. When you upgrade, simply re-run systemctl --user daemon-reload; no other migration is required.
Applicable / Non-applicable Scenario Checklist
Use systemd user service when:
- laptop boots to GNOME/KDE and you need tunnel before opening browser
- headless mini-PC acts as smart-TV gateway for Netflix US
- you run cron/rsync jobs over the tunnel at 03:00 regardless of login
Avoid auto-start when:
- machine is shared and local intranet must stay reachable
- you tether via 4G with < 2 GB monthly quota
- corporate WPA-Enterprise drops you if geolocation flips
Best-Practice Summary
- Prefer the systemd user service; it is desktop-agnostic and survives logout.
- Store credentials in a 600-permission file, never inside the unit.
- Always add
Wants=network-online.targetto postpone connect until DNS is reachable. - Test reboot twice—once on Ethernet, once on Wi-Fi—to catch dispatcher race conditions.
- Keep the GUI installed even in headless mode; the CLI is just a wrapper that talks to the same daemon.
Frequently Asked Questions
Does the systemd unit work before I log in?
Yes, provided you ran sudo loginctl enable-linger $USER. Without linger the user manager terminates on logout and takes the tunnel down.
Will the service restart after kernel upgrades?
systemd handles restarts automatically; no extra cron is needed. Add RestartSec=30 to avoid hammering the auth server while boot scripts settle.
Can I exclude China-local apps from the tunnel?
Yes, use Kuailian’s Split-Tunnel 3.0 GUI or edit ~/.config/kuailian/split.json and list the apps/IPs you want direct. Reload with kuailian-cli --reload-config.
Next Actions
Decide your threat model first—always-on or on-demand—then pick either the systemd user service (robust, headless-friendly) or the desktop autostart file (quick, GUI visible). Test with a reboot, watch the journal, and set a calendar reminder to audit the unit after every Kuailian upgrade. Once stable, you can forget about manual clicks and let Ubuntu 22.04 bring your tunnel up as reliably as it mounts the home partition.



