Installing SimpleLink VPN in OpenWRT Router

This tutorial will guide through the process of installing Simplelink VPN, utilizing the compatible Clash VPN daemon on a router device powered by OpenWRT. This configuration allows the router to transparently proxy all managed connections, significantly reducing the need for individual configuration and maintenance of Clash and Simplelink on each device within a home network.

The advantage of this setup is the need for only a one-time configuration on the router. The daemon will automatically keep the Simplelink configuration up to date, relying on a URL rather than a static file for updates.

Participants in this tutorial should have access to a modern networking device capable of running OpenWRT, such as a router, 4G Wi-Fi gateway, or Raspberry Pi. It is crucial that the chosen device has adequate storage capacity to accommodate the necessary software packages. For instance, an older TP-Link WiFi router with a mere 8MB of Flash memory would not suffice. To verify the suitability of your device, consult the “Overview” page under the “Storage” section on your OpenWRT device’s interface to determine the available storage space:

The tutorial begins with the assumption that participants possess a foundational understanding of Linux and networking principles. Such knowledge is deemed sufficient given the prior installation of OpenWRT on a device.

For the purposes of this tutorial, it is assumed that the device in question has been assigned the IP address 192.168.100.1. The initial step involves ensuring SSH access is enabled on the device. Should there be any uncertainties regarding this process, participants are encouraged to consult the following guide for assistance: https://openwrt.org/docs/guide-quick-start/sshadministration.

Upon verifying or enabling SSH access, the next step is to establish an SSH connection to the device:

$ ssh root@192.168.100.1
The authenticity of host '192.168.100.1 (192.168.100.1)' can't be established.
ED25519 key fingerprint is SHA256:4yGw06TIzYUZX3AZOhmAIHDgA0+PMXWRtY5YwKrAir0.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.100.1' (ED25519) to the list of known hosts.
root@192.168.100.1's password:


BusyBox v1.36.1 (2023-11-14 13:38:11 UTC) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt 23.05.2, r23630-842932a63d
 -----------------------------------------------------
root@OpenWrt:~#

The initial step in the process involves updating the package list. This ensures that all necessary dependencies can be installed and that the system has access to the latest versions of software packages.

root@OpenWrt:~# opkg update
Downloading https://downloads.openwrt.org/releases/23.05.2/targets/x86/generic/packages/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_core
Downloading https://downloads.openwrt.org/releases/23.05.2/targets/x86/generic/packages/Packages.sig
Signature check passed.
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/base/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_base
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/base/Packages.sig
Signature check passed.
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/luci/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_luci
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/luci/Packages.sig
Signature check passed.
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/packages/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_packages
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/packages/Packages.sig
Signature check passed.
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/routing/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_routing
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/routing/Packages.sig
Signature check passed.
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/telephony/Packages.gz
Updated list of available packages in /var/opkg-lists/openwrt_telephony
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/telephony/Packages.sig
Signature check passed.

The first dependency to be installed is the luci-lib-json library, as demonstrated in the following snippet:

root@OpenWrt:~# opkg install luci-lib-json
Installing luci-lib-json (git-18.184.37844-cde13dc) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/luci/luci-lib-json_git-18.184.37844-cde13dc_all.ipk
Installing luci-lib-nixio (git-24.034.54875-21210dc) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/luci/luci-lib-nixio_git-24.034.54875-21210dc_i386_pentium4.ipk
Installing luci-lib-ip (git-23.311.79290-c2a887e) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/luci/luci-lib-ip_git-23.311.79290-c2a887e_i386_pentium4.ipk
Installing luci-lib-jsonc (git-23.298.74571-62eb535) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/luci/luci-lib-jsonc_git-23.298.74571-62eb535_i386_pentium4.ipk
Installing liblucihttp-lua (2023-03-15-9b5b683f-1) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/luci/liblucihttp-lua_2023-03-15-9b5b683f-1_i386_pentium4.ipk
Installing luci-lib-base (git-22.308.54612-9118452) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/luci/luci-lib-base_git-22.308.54612-9118452_all.ipk
Installing libubus-lua (2023-06-05-f787c97b-1) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/base/libubus-lua_2023-06-05-f787c97b-1_i386_pentium4.ipk
Installing ucode-mod-lua (1) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/luci/ucode-mod-lua_1_i386_pentium4.ipk
Installing luci-lua-runtime (git-23.233.52805-dae2684) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/luci/luci-lua-runtime_git-23.233.52805-dae2684_i386_pentium4.ipk
Configuring luci-lib-nixio.
Configuring luci-lib-ip.
Configuring luci-lib-jsonc.
Configuring liblucihttp-lua.
Configuring luci-lib-base.
Configuring libubus-lua.
Configuring ucode-mod-lua.
Configuring luci-lua-runtime.
Configuring luci-lib-json.

The second dependency to be installed is curl. This utility is essential for keeping the Simplelink configuration current.

root@OpenWrt:~# opkg install curl
Installing curl (8.6.0-1) to root…
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/packages/curl_8.6.0-1_i386_pentium4.ipk
Installing libnghttp2-14 (1.57.0-1) to root…
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/packages/libnghttp2-14_1.57.0-1_i386_pentium4.ipk
Installing libcurl4 (8.6.0-1) to root…
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/packages/libcurl4_8.6.0-1_i386_pentium4.ipk
Configuring libnghttp2-14.
Configuring libcurl4.
Configuring curl.

Having installed the necessary dependencies, the next step involves preparing for the installation of Clash-related software, which is compatible with Simplelink VPN. Prior to this installation, it is imperative to determine a critical detail of the system: the CPU architecture. The simplest method to ascertain this information is by executing the command outlined below:

root@OpenWrt:~# uname -m
i686

Upon execution of the command, the output i686 indicates the device used in this tutorial is based on a classical 32-bit PC architecture. In your case, the output might be aarch64, signifying a modern ARM64-based device, among various other architectures supported by OpenWRT.

For those seeking additional clarity regarding their device’s architecture, the subsequent command can provide more detailed information:

root@OpenWrt:~# uname -a
Linux OpenWrt 5.15.137 #0 SMP Tue Nov 14 13:38:11 2023 i686 GNU/Linux

For individuals whose devices fall within the ARM Cortex category but are uncertain of the specific model, executing the following command can yield more detailed information about the architecture:

root@ZhuAP:~# cat /proc/cpuinfo
system type             : Qualcomm Atheros QCA9558 ver 1 rev 0
machine                 : TP-Link TL-WR1043ND v3
processor               : 0
cpu model               : MIPS 74Kc V5.0
BogoMIPS                : 358.80
wait instruction        : yes
microsecond timers      : yes
tlb_entries             : 32
extra interrupt vector  : yes
hardware watchpoint     : yes, count: 4, address/irw mask: [0x0ffc, 0x0ffc, 0x0ffb, 0x0ffb]
isa                     : mips1 mips2 mips32r1 mips32r2
ASEs implemented        : mips16 dsp dsp2
Options implemented     : tlb 4kex 4k_cache prefetch mcheck ejtag llsc dc_aliases perf_cntr_intr_bit cdmm contextconfig perf mm_full
shadow register sets    : 1
kscratch registers      : 0
package                 : 0
core                    : 0
VCED exceptions         : not available
VCEI exceptions         : not available

The output shown above indicates that for another OpenWRT device on hand, the “cpu model” is identified as “MIPS 74Kc”. Such information proves useful in differentiating between specific ARM models, while the “isa” parameter can offer additional clues regarding the architecture.

With the architecture identified, the next step involves visiting the Clash OpenWRT plugin downloads page to select the appropriate download link for the identified architecture. The page can be accessed via the following URL: https://github.com/chandelures/openwrt-clash/releases/tag/v1.17.0-1.

A helpful, though informal, reference table may assist in selecting the correct download link based on the determined architecture:

uname -m OutputDownload Link
aarch64 (Cortex-A53)clash_1.17.0-1_aarch64_cortex-a53.ipk
aarch64 (Cortex-A72)clash_1.17.0-1_aarch64_cortex-a72.ipk
aarch64 (Generic)clash_1.17.0-1_aarch64_generic.ipk
armv6l (ARM1176JZF-S)clash_1.17.0-1_arm_arm1176jzf-s_vfp.ipk
armv7l (Cortex-A15 Neon-VFPv4)clash_1.17.0-1_arm_cortex-a15_neon-vfpv4.ipk
armv5tel (Cortex-A5 VFPv4)clash_1.17.0-1_arm_cortex-a5_vfpv4.ipk
armv7l (Cortex-A7 Neon-VFPv4)clash_1.17.0-1_arm_cortex-a7_neon-vfpv4.ipk
armv7l (Cortex-A8 VFPv3)clash_1.17.0-1_arm_cortex-a8_vfpv3.ipk
armv7l (Cortex-A9)clash_1.17.0-1_arm_cortex-a9.ipk
armv7l (Cortex-A9 VFPv3-D16)clash_1.17.0-1_arm_cortex-a9_vfpv3-d16.ipk
armv4l (FA526)clash_1.17.0-1_arm_fa526.ipk
armv6l (MPCore)clash_1.17.0-1_arm_mpcore.ipk
armv5tel (XScale)clash_1.17.0-1_arm_xscale.ipk
i686 (Pentium4)clash_1.17.0-1_i386_pentium4.ipk
mips64 (OcteonPlus)clash_1.17.0-1_mips64_octeonplus.ipk
mipsel (24KC)clash_1.17.0-1_mipsel_24kc.ipk
mipsel (MIPS32)clash_1.17.0-1_mipsel_mips32.ipk
mips (MIPS32)clash_1.17.0-1_mips_mips32.ipk
x86_64clash_1.17.0-1_x86_64.ipk

After identifying the correct download link for the device, the next step involves copying this link and returning to the SSH session. Within this session, the wget command is utilized to download the selected file directly onto the device:

root@OpenWrt:~# wget https://github.com/chandelures/openwrt-clash/releases/download/v1.17.0-1/clash_1.17.0-1_i386_pentium4.ipk -O clash.ipk
Downloading 'https://github.com/chandelures/openwrt-clash/releases/download/v1.17.0-1/clash_1.17.0-1_i386_pentium4.ipk'
Connecting to 140.82.121.4:443
Redirected to /github-production-release-asset-2e65be/416734361/2b5423bb-836b-4de9-9afa-de61d4ec957d?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAVCODYLSA53PQK4ZA%2F20240301%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240301T183110Z&X-Amz-Expires=300&X-Amz-Signature=acc065099d76d6e1936fcfd0a2ec5fab4db19c61f5054b4600c10450691920a8&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=416734361&response-content-disposition=attachment%3B%20filename%3Dclash_1.17.0-1_i386_pentium4.ipk&response-content-type=application%2Foctet-stream on objects.githubusercontent.com
Writing to 'clash.ipk'
clash.ipk            100% |*******************************|  6392k  0:00:00 ETA
Download completed (6545431 bytes)

Following the download, the next step is to attempt the installation of the downloaded file:

root@OpenWrt:~# opkg install clash.ipk
Installing clash (1.17.0-1) to root...
Installing kmod-nf-ipt (5.15.137-1) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/targets/x86/generic/packages/kmod-nf-ipt_5.15.137-1_i386_pentium4.ipk
Installing kmod-ipt-core (5.15.137-1) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/targets/x86/generic/packages/kmod-ipt-core_5.15.137-1_i386_pentium4.ipk
Installing libip4tc2 (1.8.8-2) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/targets/x86/generic/packages/libip4tc2_1.8.8-2_i386_pentium4.ipk
Installing libip6tc2 (1.8.8-2) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/targets/x86/generic/packages/libip6tc2_1.8.8-2_i386_pentium4.ipk
Installing libxtables12 (1.8.8-2) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/targets/x86/generic/packages/libxtables12_1.8.8-2_i386_pentium4.ipk
Installing libiptext0 (1.8.8-2) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/targets/x86/generic/packages/libiptext0_1.8.8-2_i386_pentium4.ipk
Installing libiptext6-0 (1.8.8-2) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/targets/x86/generic/packages/libiptext6-0_1.8.8-2_i386_pentium4.ipk
Installing xtables-legacy (1.8.8-2) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/targets/x86/generic/packages/xtables-legacy_1.8.8-2_i386_pentium4.ipk
Installing iptables-zz-legacy (1.8.8-2) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/targets/x86/generic/packages/iptables-zz-legacy_1.8.8-2_i386_pentium4.ipk
Installing kmod-nf-tproxy (5.15.137-1) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/targets/x86/generic/packages/kmod-nf-tproxy_5.15.137-1_i386_pentium4.ipk
Installing kmod-ipt-tproxy (5.15.137-1) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/targets/x86/generic/packages/kmod-ipt-tproxy_5.15.137-1_i386_pentium4.ipk
Installing iptables-mod-tproxy (1.8.8-2) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/targets/x86/generic/packages/iptables-mod-tproxy_1.8.8-2_i386_pentium4.ipk
Installing liblua5.1.5 (5.1.5-10) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/base/liblua5.1.5_5.1.5-10_i386_pentium4.ipk
Installing libuci-lua (2023-08-10-5781664d-1) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/base/libuci-lua_2023-08-10-5781664d-1_i386_pentium4.ipk
Installing lua (5.1.5-10) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/base/lua_5.1.5-10_i386_pentium4.ipk
Installing libyaml (0.2.5-1) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/packages/libyaml_0.2.5-1_i386_pentium4.ipk
Installing lyaml (6.2.7-2) to root...
Downloading https://downloads.openwrt.org/releases/23.05.2/packages/i386_pentium4/packages/lyaml_6.2.7-2_i386_pentium4.ipk
Configuring liblua5.1.5.
Configuring libuci-lua.
Configuring kmod-nf-tproxy.
Configuring kmod-nf-ipt.
Configuring kmod-ipt-core.
Configuring kmod-ipt-tproxy.
Configuring libxtables12.
Configuring libiptext0.
Configuring lua.
Configuring libip4tc2.
Configuring libip6tc2.
Configuring libiptext6-0.
Configuring xtables-legacy.
Configuring iptables-mod-tproxy.
Configuring iptables-zz-legacy.
Configuring libyaml.
Configuring lyaml.
Configuring clash.
clash[4759]: Instance is disabled

Subsequently, it is necessary to download and install the user interface:

root@OpenWrt:~# wget https://github.com/chandelures/luci-app-simple-clash/releases/download/v0.1.4/luci-app-simple-clash_0.1.4_all.ipk -O clash_luci.ipk
Downloading 'https://github.com/chandelures/luci-app-simple-clash/releases/download/v0.1.4/luci-app-simple-clash_0.1.4_all.ipk'
Connecting to 140.82.121.4:443
Redirected to /github-production-release-asset-2e65be/435750849/a516e490-2cc9-4185-a308-974f7ea67402?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAVCODYLSA53PQK4ZA%2F20240301%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20240301T183300Z&X-Amz-Expires=300&X-Amz-Signature=9b71aeb1c08584690f9ea011696967629ded8dfa57daa84b3c006dbd5c44086d&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=435750849&response-content-disposition=attachment%3B%20filename%3Dluci-app-simple-clash_0.1.4_all.ipk&response-content-type=application%2Foctet-stream on objects.githubusercontent.com
Writing to 'clash_luci.ipk'
clash_luci.ipk       100% |*******************************|  6300   0:00:00 ETA
Download completed (6300 bytes)
root@OpenWrt:~# opkg install clash_luci.ipk
Installing luci-app-simple-clash (0.1.4) to root...
Configuring luci-app-simple-clash.

Following the installation, it is essential to address a minor bug within the plugin by preemptively creating the profiles folder:

root@OpenWrt:~# mkdir /etc/clash/profiles

Subsequently, initiate a reboot of the device and navigate to the web UI of the OpenWRT device. In this instance, the address is http://192.168.100.1. Within the UI, a “Simple Clash” tab should be present under the “Services” dropdown menu:

Proceed to the “Profiles” section and remove all existing profiles by selecting the red “Delete” button:

Next, click on the “Add new profiles…” button, which is highlighted in green:

In the ensuing popup, choose the “URL” type, as shown in the screenshot below:

The subsequent step involves acquiring the Simplelink Clash subscription link. To do this, visit the Simplelink dashboard at https://anywhere.simplelink.site and log in using your credentials.

Upon logging in, navigate to the “Third party apps” section and click on the “Clash Subscribe” > “Copy Clash URL” button, as illustrated in the screenshot:

A confirmation popup will appear, indicating that the URL has been copied to the clipboard. Return to the web UI of the OpenWRT device.

Paste the URL into the designated field, as depicted in the screenshot and click “Create Profile”:

Ensure all configurations are saved by clicking the “Save and Apply” button at the bottom:

Click the “Update” button for the newly added profile. This action activates the update mechanism, keeping the Simplelink configuration synchronized with Clash.

Verify that the “Last Update” date reflects the recent update:

Select the newly added profile in the “Profile” field under the “Settings” section and check the “Enabled” box to activate the VPN.

Wait approximately five seconds, then refresh the page. The top section should now indicate that Clash has started, and the VPN is connected.

At this point, if the internet connection is routed through the OpenWRT device, the IP address and location should appear altered. This change can also be verified on the OpenWRT device itself by executing the specified command in the SSH session, if it remains open.

root@OpenWrt:~# curl http://icanhazip.com
89.223.94.43

Congratulations! You have successfully set up Simplelink on your OpenWRT-based network device.