Repository navigation
Releases: jialiangZ/hkuvpn
Release list
hkuvpn v1.2.1
hkuvpn v1.2.1 — the field fixes
This release is what v1.2.0 should have been. Every item below was found
by running the client against the live HKU gateway for a whole day, and
every one of them made the client behave in a way that was hard to
diagnose. If you downloaded v1.2.0, take this one instead — the
release workflow that builds the archive did not exist yet when v1.2.0 was
tagged, so that archive carries the unfixed worker.
The fixes
-
The system no longer crawls. The routing script registered the
gateway's DNS servers on the tunnel adapter even though HKU pushes no
split routes, so those resolvers were unreachable and the Windows DNS
client waited on them for every name — opening a folder included. A
resolver is now registered only when a route actually reaches it. -
Big transfers do not stall. OpenConnect sizes the tunnel adapter
from the TCP channel's MTU (1271), which is larger than what the UDP
channel carries (1246): packets in between were dropped, so a shell
answered while a file transfer hung forever. The worker now caps the
adapter at the DTLS MTU, read from the session log. -
A connect does not hang at "Connecting". The worker was losing a
quarter of what the tunnel processes printed — the "Password:" and
"Response:" prompts included — so the code dialog sometimes never
appeared. The read now copies the bytes out before the next one is
armed. -
The window stops claiming a session that is not there. A worker
waiting for the MFA code beats its heart, so the app used to call that
"connected", close the dialog and leave the session waiting forever.
Only a session that reported its tunnel up counts as connected now, and
a worker found waiting for a code is adopted with the dialog back. -
The UAC prompt can take as long as it takes. The connect attempt
gave up after 20 seconds — but that clock started when you pressed
Connect, and the UAC prompt in front of you may sit there longer. The
clock now starts when the worker actually appears, and a worker that
turns up while the app is idle is adopted rather than orphaned. -
TCP by default.
HKU_DTLSshipped with DTLS/UDP on and TCP as the
escape hatch, which is backwards for most users: cross-border links
throttle UDP into heavy loss (41 percent on the link this was measured
on), which stalls the session in confusing ways, while TCP only costs
latency. Both editions now carry their data over TCP unless you ask for
DTLS withHKU_DTLS=1— worth it where the path is clean, inside Hong
Kong for instance, where it cuts round-trips to about a quarter. -
Every setting says what it does when the pointer rests on it.
The Windows app
Same download as before: HKUVPN-windows-v1.2.1.zip — the app, the
worker it drives, the routing script and a START-HERE.md (also in
Chinese). Unpack it, run bin\get-tools.ps1 once as administrator, start
HKUVPN.exe.
Upgrade notes
Nothing to do. The Docker edition works exactly as before, and the
Windows launcher gained nothing either — the desktop app is a separate
thing that drives the same worker underneath it.
If you configured HKU_DTLS=0 by hand, it still means the same thing.
If you had no HKU_DTLS line at all, you now get TCP instead of DTLS.
hkuvpn v1.2.0 - the desktop app
hkuvpn v1.2.0 — the desktop app
This release is about making hkuvpn usable on a laptop without a
compiler, a container runtime or a terminal window.
The Windows app (new)
HKUVPN-windows-v1.2.0.zip — 5 MB, no installer.
Unpack it anywhere, run bin\get-tools.ps1 once as administrator (it
installs OpenConnect, which brings the Wintun adapter, and downloads
gost; both downloads are checked against pinned SHA-256 hashes), then
start HKUVPN.exe. Type your HKU account and Portal PIN in the window —
they are saved as you type and never leave the machine — press
Connect, approve the UAC prompt, and type the six-digit code from
Microsoft Authenticator when it asks.
START-HERE.md and START-HERE.zh-CN.md in the archive have the full
steps, in English and in Chinese.
What the window gives you that the launcher does not:
- a status card — the state, the tunnel address, the uptime, the proxy
endpoints and the learned routes, in one place - a Diagnostics panel — the same checks as
hkuvpn.ps1 --check, plus a
live test of the local proxies and the address the traffic leaves with - a Routes panel — the learned routes, added and removed by hand
- a Settings panel — the advanced options of
hku.env, and a switch
to start the app with Windows - a log window — the session log with severity tags, a level filter, a
search field, and copy / export
Closing the window hides the app in the tray and the tunnel keeps
running. Disconnect needs no UAC, and exiting the app never kills a
session.
中文
HKUVPN-windows-v1.2.0.zip 里有桌面 App:解压后以管理员身份运行一次
bin\get-tools.ps1(装 OpenConnect、下载 gost,都有固定的 SHA-256 校验),
再启动 HKUVPN.exe,在窗口里填账号和 Portal PIN,点 Connect,UAC 点允许,
要码时输入 Authenticator 上的 6 位数字。压缩包里的 START-HERE.zh-CN.md
有完整步骤。
窗口里比启动器多出来的东西:状态卡(状态、隧道地址、时长、代理、
学到的路由)、诊断面板(和 --check 相同的检查,外加本地代理的连通性
测试和出口地址)、路由面板(可手动增删)、设置面板(hku.env 的高级
选项和开机自启)、日志窗口(级别标签、级别筛选、搜索、复制、导出)。
Also in this release
- The logs have a policy now. One file per connection attempt, three
generations kept, and a session that runs long can no longer fill the
disk. - The app's own log moved to
%LOCALAPPDATA%\HKUVPN\app.log— a
place Windows does not clear behind your back. It is rolled daily and a
week is kept. - Deleting an autostart entry that is not there is no longer an
error, and the "Start with Windows" switch shows what the registry
actually says rather than what the app remembers. - The MFA dialog became a gate: the code leads on, and closing the
dialog gives the attempt up — there is no "enter the code later". - The panels got windows of their own, the window has one fixed size, and
no page has a scrollbar. - The documentation was brought back in line with the software. The
design brief describes what the app is now, the READMEs describe the
log policy and the UAC behaviour that are actually true, and the
website's links point where they say they do.
Upgrade notes
Nothing to do. The Docker edition works exactly as before, and the
Windows launcher gained nothing — the desktop app is a new, separate
thing that drives the same worker underneath it.
A note on the archive
The .sha256 file next to the archive is the hash of the archive. If it
does not match, do not run it — write an issue instead.
v1.1.4
hkuvpn v1.1.4 - migration guide and docs aligned with field results
Upgrading from v1.0.x
The Docker edition moved into docker/ in v1.1.0, and the shell wrappers
into examples/shells/. An existing shell profile silently broke: it
still sourced examples/hkuvpn.zsh, which no longer exists there.
| Was | Now |
|---|---|
docker build -t local/vpn . |
docker build -t local/vpn docker/ |
~/hkuvpn/bin/hkuvpn |
~/hkuvpn/docker/bin/hkuvpn |
~/hkuvpn/examples/hku.env.example |
~/hkuvpn/docker/examples/hku.env.example |
source ~/hkuvpn/examples/hkuvpn.zsh |
source ~/hkuvpn/examples/shells/hkuvpn.zsh |
cp ~/hkuvpn/examples/hkuvpn.fish ... |
cp ~/hkuvpn/examples/shells/hkuvpn.fish ... |
Re-run the printf line from
Install the Short hkuvpn Command
once to fix the path in your profile. ~/.vpn/ keeps your credentials, and
HKUVPN_HOME still points at the repository root.
Docs corrected against the field results
- The native Windows port is no longer described as experimental: a full
session ran against a real HKU account on Windows 11 with PowerShell 5.1
(connect, routing, licensed-resource routing, clean shutdown). - Its routing model is now described as on-demand routing - HKU's
gateway pushes no split routes - instead of speaking of campus subnets
and of a model differing only "slightly" from the container edition. - The known-differences tables state what actually goes through HKU, that
licensed resources are learned even when the first attempt fails, and
that the NRPT rule is skipped on purpose when the gateway's resolvers
are not reachable through the tunnel. - The MFA sections explain that an Authenticator code is valid for about
30 seconds and that a rejected one is simply re-prompted. - The compatibility tables list the versions the native port pins
(OpenConnect 9.21, gost 3.3.0).
No code changes in this release.
v1.1.3
hkuvpn v1.1.3 - the native Windows port, working end to end
The Windows port was driven through a complete session against the live
HKU gateway. That found five more problems, all fixed here. After this
release the port establishes a tunnel, installs routes, keeps the host's
default route untouched, and learns routes for licensed resources.
Fixed
- The worker stalled right after starting OpenConnect.
Read-AvailableChars
drained a child's stream withwhile ($Reader.Peek() -ge 0), and on a
redirected pipePeek()blocks again as soon as the buffered data is
consumed - so the call never returned. The worker never got to read
stderr, where OpenConnect prints its prompts, so the Portal PIN was
never sent. All four streams are now polled withReadAsync. - The IPv4 mask arithmetic threw. PowerShell parses
0xFFFFFFFFas
[int]-1, and casting a negative value to[uint32]throws.
Get-PrefixMaskDottedandGet-NetPrefixBasethrew for every prefix
below /32 (the first learned destination killed the session), and
Test-IpInPrefixswallowed the exception and always answered false (the
NRPT rule was never installed). All three use 64-bit arithmetic now. - gost died silently when it could not bind 1080/1088. The worker now
checks gost right after starting it and on every iteration. - A rejected MFA code was invisible. A stale Authenticator code comes
back as a second form, which looked like a first prompt. The worker now
reports the rejection (HKUVPN_MFA_RETRY) and tells the user to enter
the current code; the log is flushed while waiting, so--logsis
current. - Prompts were matched anywhere in the output. OpenConnect writes its
prompts without a trailing newline, so a real prompt ends the buffer.
The old search also matched the log line... Enter Your Microsoft verification code Response:and asked for another code after the
tunnel was already up.
Learned routes now cover failed connections
gost runs in debug mode, which logs dial <target>/tcp before the
connection is attempted - the only place a destination appears when the
connection never completes. That is exactly the case of a resource that
is only reachable through the campus exit; without it such a resource
could never work. Host names are resolved by the launcher itself (cached
per session).
What HKU's gateway actually does
Documented after measuring it: it is a full-tunnel gateway that pushes
no split routes (connect done: 0 v4 route(s) is normal) and it only
carries public destinations through the tunnel. The native port therefore
routes on demand, and the NRPT rule is skipped on purpose when the
gateway's resolvers are not reachable through the tunnel - a rule
pointing at an unreachable resolver would only black-hole the lookups.
Verified on real hardware
Tunnel up (CSTP connected, DTLS, MTU 1255), split routes applied by the
vpnc script, learned routes installed through the tunnel
(140.248.167.0/24, 203.0.113.0/24 - the latter learned from a
connection that never succeeded), the default route still on the physical
adapter, the e2e proxy check green, and the certificate pin byte-identical
to the openssl value.
v1.1.2
hkuvpn v1.1.2 - the native Windows port, fixed after field testing
The Windows port was exercised on a real machine (Windows 11 build 26300,
PowerShell 5.1). That found four bugs that no amount of static checking
would have caught. All are fixed here.
Fixed
- IPv4 mask arithmetic (
Get-PrefixMaskDotted,Get-NetPrefixBase,
Test-IpInPrefix) - PowerShell parses0xFFFFFFFFas[int]-1, and
casting a negative value to[uint32]throws. The first two threw for
every prefix below /32, so the first external destination reaching the
auto-route learner raised inside the tunnel worker and killed the
session.Test-IpInPrefixswallowed the same exception and always
answered false, so the NRPT rule for campus-only DNS was never
installed. All three now use 64-bit arithmetic. - Tools directory -
get-tools.ps1created<repo>\toolswhile
hkuvpn.ps1looked in<repo>\windows\tools, so gost was installed
where the launcher never checked. Both agree now, and the launcher also
accepts the old location. - OpenConnect installer - the URL pointed at the moving GitLab CI
masterartifacts, which expire after a week (it 404s now). The script
now downloads the official v9.21 tag build, whose artifacts never
expire, and verifies it against a pinned SHA-256 - the same version the
Docker image builds. - Pre-flight session check -
Get-Process -Id 0returns the Windows
System Idle process, and a missing pid file reads as 0, so the pre-flight
always claimed a session was running and skipped the port check.
Also
- The Windows scripts are pure ASCII now: PowerShell 5.1 and
cscript.exe
read BOM-less files as ANSI and would mangle non-ASCII characters. .gitattributesnormalises line endings (CRLF for the scripts Windows
executes, LF for everything else).windows/tools/is git-ignored (downloaded binaries).- A field validation checklist
(English / 简体中文) walks through every step with the expected output.
Verified on real hardware
Tool installation with pinned hashes, the certificate pin (byte-identical
to the openssl value), the gost proxy with both listeners, the auto-route
learner against real connection logs, the vpnc script (including its
refusal of a /0 route), the NRPT rule, and route add/delete.
v1.1.1
hkuvpn v1.1.1 — MIT License
The project is now released under the MIT License.
LICENSE— the canonical MIT text, so GitHub detects the license correctlyNOTICE— upstream attribution and third-party notices:- derived from ethack/docker-vpn
via the HKU edition by
rqhu1995/docker-vpn (both
published without an explicit license) docker/etc/vpnc-scriptis vendored verbatim from openconnect/vpnc-scripts
and stays under GPL-2.0, as its header states- OpenConnect, gost, and the other packaged dependencies keep their own
licenses - the HKU VPN server is operated by the University of Hong Kong; this is an
unofficial client
- derived from ethack/docker-vpn
- a license badge and updated footers in both READMEs, both guides, and the
project site
v1.1.0
hkuvpn v1.1.0 — repository reorganized
The repository now has two self-contained editions with the same shape,
instead of the Docker edition being scattered across the repository root.
hkuvpn/
├── docker/ # Docker edition (Linux / macOS / Windows-WSL)
│ ├── Dockerfile
│ ├── bin/hkuvpn
│ ├── etc/vpnc-script
│ ├── examples/hku.env.example
│ ├── hku-connect.exp
│ └── keys/openconnect-release-key.asc
├── windows/ # Native Windows edition (no WSL, no Docker)
│ ├── bin/hkuvpn.ps1
│ ├── bin/get-tools.ps1
│ ├── etc/vpnc-script-win.js
│ └── examples/hku.env.example
├── examples/ # Shared integration examples
│ ├── clients/ # Clash Verge Rev, Surge, SSH config
│ └── shells/ # Zsh / Bash / Fish / PowerShell wrappers
└── docs/ # Guides and diagrams
Migration (command paths changed)
| Before | Now |
|---|---|
docker build -t local/vpn . |
docker build -t local/vpn docker/ |
~/hkuvpn/bin/hkuvpn |
~/hkuvpn/docker/bin/hkuvpn |
~/hkuvpn/examples/hku.env.example |
~/hkuvpn/docker/examples/hku.env.example |
~/hkuvpn/examples/hkuvpn.zsh |
~/hkuvpn/examples/shells/hkuvpn.zsh |
Existing clones keep working: the launcher and the shell wrappers fall back
to the old layout when it is detected, and HKUVPN_HOME (legacy name
DOCKER_VPN_HOME) still points at the repository root. When the variable is
unset, the launcher now derives the root from its own location instead of
assuming ~/hkuvpn.
Also in this release
Readme.mdrenamed toREADME.md(consistent casing)poc/removed — prototype leftovers referencing a non-existent image and
hard-coding a personal account- Repository layout documented in both READMEs and both guides
v1.0.0
hkuvpn v1.0.0
HKU campus VPN client: OpenConnect + Microsoft Authenticator MFA behind local
SOCKS5/HTTP proxies, while the host default route stays untouched.
Docker edition (Linux / macOS / Windows via WSL2)
- OpenConnect 9.21 built from verified source; MFA form automation via expect
- gost proxy (SOCKS5
1080/ HTTP1088), DoH-pinned control endpoints,
certificate pin cache, layered--statuswith scriptable exit codes - Rules-client examples for Clash Verge Rev / Mihomo and Surge
Native Windows port (experimental) - windows/
- Official OpenConnect Windows CLI (Wintun) + gost: no WSL, no Docker
- PowerShell launcher: smart / foreground / detached, interactive or
--mfa <code>delivery, self-elevation, layered--status vpnc-script-win.js: split-tunnel-only routing that never touches the host
default route, plus an NRPT rule for campus-only DNS- Auto-learned routes for HKU-licensed external resources (learned from the
proxy connection log, persisted across sessions with TTL and a cap)
Credits
Derived from ethack/docker-vpn via the
HKU edition by rqhu1995/docker-vpn.