# BitSrunLoginGo: an auto-login client for the Deepin campus network portal

> BitSrunLoginGo is a Go rewrite of the campus network login script used on Chinese universities running the srun portal, and it exists to run on places a Python script would not, including routers, Docker containers and OpenWrt firmwares. It logs in with credentials you supply, adds a guardian mode that re-authenticates on a timer, and can update a DDNS A record after a successful login. The licence is AGPL-3.0.

**Mmx233/BitSrunLoginGo** — 深澜校园网登录程序 Go 语言版，适用于Windows、Linux、路由器等。提供对 Docker、Go Module、OpenWrt 的支持

- Repository: https://github.com/Mmx233/BitSrunLoginGo
- Stars: 567 · Forks: 50
- Language: Go
- License: AGPL-3.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/mmx233-bitsrunlogingo

## What the project does and where the login logic came from

BitSrunLoginGo is the Go language version of the campus network login script used by universities in China, and it is described as applying to Windows, Linux, routers and similar systems, with support for Docker, Go modules and OpenWrt.

The reason it exists in Go rather than Python is stated plainly: Go can cross compile directly to a MIPS executable for a router, and to the mainstream platforms beyond that, which removes the need to install a runtime environment on the device. A router that has to run a campus login client does not have a Python interpreter and never will, and a compiled static binary is the only realistic answer.

The main login logic comes from the BIT-srun-login-script project by coffeehat, and the documentation credits that explicitly.

The scope is one task, done properly. The program authenticates against the srun portal using credentials you provide, and it can do it repeatedly on a schedule. The features that make it more than a one-shot script are the guardian mode, the DDNS integration, the multi-NIC support, and the per-interface override of login parameters.

The users are students and lab networks on campuses that use this portal, and the people who put the script on a router so that the connection survives a reboot without anyone opening a browser.

## Running the binary and the flags that override the config

The build output is an executable, and you either download a release or build it and run it directly.

The release file names carry the platform details, and the documentation gives a plain rule for anyone who does not know what the suffixes mean: if you do not know what the v4 in windows_amd64_v4 or the hardfloat in linux_arm_hardfloat means, choose the default version without those suffixes, since it has higher compatibility.

The first run generates the configuration file automatically, and the documentation suggests enabling debug logging on a first run, either by setting settings.log.debug_level to true in the config or by passing the --debug flag. You can point the program at a different configuration file with --config, and the default is Config.yaml in the current directory.

The configuration file supports both json and yaml, with yaml as the default:

```shell
./bitsrun --config=./another-config.yaml
./bitsrun --config=/demo/i.json
```

Beyond the config path, the flags are all overrides. --interface selects the network interface to log in with, and the documentation notes it has no effect in multi-NIC mode. --debug turns on debug mode temporarily. --auto-acid sniffs the acid value automatically and --acid overrides the configured value directly, and the same pair exists for enc with --auto-enc.

That the acid and enc can be sniffed is a response to how these portals work. The login parameters are captured from the request the original web page makes to the srun_portal endpoint, and the documentation says to enable preserve log in the browser console when doing that capture. The enc value in particular is not present in the form, so the shipped default of srun_bx1 is usually correct but not always, and the documentation points you at searching for enc in the page's JavaScript to find the real value.

## The configuration file and how to fill it in correctly

The configuration is a two-part document, a form section for the login parameters and a settings section for the behaviour, with the form carrying the values you captured from the portal and the settings holding everything else.

The form needs the domain, which is the login address as an IP or a hostname, the username, the password, and a user_type field naming the carrier. The meta object holds the parameters the portal expects, with n, type, acid, enc, os, name, info_prefix and double_stack.

The carrier type deserves a note because it trips people up. On the original web page the carrier type is appended to the account automatically, so you have to take the part after the @ symbol and put it in user_type, and if there is none you leave it empty and delete the shipped default. The shipped default is cmcc.

The settings section is where the operational behaviour lives. The basic block has https for using https when talking to the campus network API, skip_cert_verify, a network request timeout in seconds, an interfaces field that takes a regular expression for interface names, with escaping noted, an interfaces_interval that is the wait between interface switches in multi-NIC mode, and a dns_server such as 114.114.114.114 that leaves the system default when empty.

The guardian block is the background residency mode, with an enable switch, a duration in seconds for the network check cycle, and the mode is off by default.

The backoff block is an integral backoff for retries after a failed login, with enable, max_retries where zero means retry until success, initial_duration and max_duration in seconds, an exponent_factor, and inter_const_factor and outer_const_factor. The waiting time formula is documented in a separate BackoffCli project, and the dependency is a direct requirement in go.mod.

Then there is the log block for debug_level, write_file, log_path and log_name, a ddns block, a reality block, a custom_header block, and an interface_forms block that overrides the global form per interface.

## Guardian mode, DDNS and the multi-NIC problem

Three features do the real work in a real campus network.

Guardian mode is background residency, a daemon that stays logged in and re-checks the connection on the cycle you set. Combined with the backoff block, a failed login is retried with a widening wait instead of a tight loop, which matters on a portal that rate limits.

DDNS is the campus network feature that is easy to miss. With ddns.enable set to true, the program sets the A record for a domain you specify, both after a successful login and when guardian mode first detects that you are already online. The point is that it can do this without depending on the router, so you can update the record from anywhere on the local network. The documentation calls that out as particularly useful when you cannot change the router's system.

Three providers are supported, with a table of extra configuration for each. Cloudflare, marked as recommended, needs a zone ID and an API token. Aliyun needs access_key_id and access_key_secret. DNSPod needs secret_id and secret_key. The configuration block under config is dynamic, so the field names depend on the provider you choose.

The multi-NIC section is where the documentation is most candid. The interface binding of the login request works reliably on Linux, but on other systems the binding may fail, and for stable multi-dial on Windows the suggestion is to bind at the system level. The docs also warn that at some schools using the same account for multiple connections still shares a bandwidth limit under the same gateway, so multi-dial achieves nothing. You can point at a specific interface with settings.basic.interfaces, or leave that empty and use --interface. To give an interface different credentials, settings.interface_forms overrides the global form per interface name, and that override applies both to a single interface named with --interface and to the interfaces matched by settings.basic.interfaces, but not in single-NIC mode with no interface specified.

## Building, cross compiling and running it in Docker

The build needs a current Go installation, and the documented commands are:

```shell
git clone https://github.com/Mmx233/BitSrunLoginGo.git
cd BitSrunLoginGo
go build ./cmd/bitsrun
```

There is also an optimised variant that strips symbols and produces a static binary:

```shell
go build -trimpath -ldflags "-s -w -extldflags '-static -fpic'" ./cmd/bitsrun
```

The cross compilation recipe is the one you want on a router, and it is a shell environment change followed by the same build command. Setting CGO_ENABLED to 0 and the target GOOS and GOARCH produces a Linux binary from a Linux host or a Windows binary from a Linux host. On Windows PowerShell the same three values are set as environment variables instead, and adding the windowsgui linker flag removes the command line window from the resulting executable, which matters for a program that runs headless on a desktop.

The Docker image is published as mmx233/bitsrunlogin-go and supports a long list of architectures, including linux/amd64, linux/386, linux/arm64, linux/arm/v7, linux/arm/v6, linux/ppc64le, linux/riscv64 and linux/s390x. The documentation advises pinning a fixed tag rather than latest in a cluster so the version is locked.

The run command mounts the configuration at /data/Config.yaml:

```shell
docker run -v path_to_config:/data/Config.yaml mmx233/bitsrunlogin-go:latest
```

The Dockerfile in the tree is a two stage build on golang:alpine, with CGO disabled through go env, a static binary produced with the same linker flags, and a final alpine image with ca-certificates and the binary at /usr/bin/bitsrun, with the working directory set to /data so a mounted config is found where the program expects it. Building your own image needs the same two steps, and the documentation notes that the current alpine base does not support anything outside Linux, so other architectures or systems may need a different build layer and base image.

## Using it as a Go module and the OpenWrt route

The package is usable as a Go module, and the documentation states the licensing position in the same breath: the project uses the AGPL V3 licence, so consider it carefully before including it.

The import path is the pkg/srun package, and the example constructs a client with a configuration struct:

```go
package main

import (
	"github.com/Mmx233/BitSrunLoginGo/pkg/srun"
)
```

The configuration mirrors the file format, with a Conf holding Https, a Client and a LoginInfo that carries a LoginForm with Domain, Username, UserType and Password, and a LoginMeta with N, Type, Acid and Enc. The client exposes a LoginStatus call that returns whether the session is online along with the address and an error, and the example notes that the struct comments are the place to look for the exact usage.

The OpenWrt path is the other reason this project exists as a Go program. The documentation points to the immortalwrt packages tree, where the net/bitsrunlogin-go package holds the build configuration file, and to the immortalwrt luci tree, where applications/luci-app-bitsrunlogin-go provides the LuCI interface for the application. In other words, a router can build the client as a native package and expose it in its web interface, which is the same outcome the cross compilation achieves on a vendor firmware.

There is also a tutorials branch with community contributed walkthroughs, and a GitHub Actions build and the repository tree with cmd/, pkg/, internal/ and tools/ directories, plus a Dockerfile.ci alongside the main Dockerfile.

## Where BitSrunLoginGo is the wrong choice

The first limit is the licence, and it is the one the documentation flags itself. The project is AGPL-3.0, and the README says in bold to consider the reference carefully. AGPL is a strong copyleft licence with a network clause, so embedding this in a service you offer to others, or in a commercial product, creates obligations that a permissive licence would not. That is a decision for your legal team, and it should be made before the code goes anywhere near a product.

The second is that the login parameters are site specific, and the shipped defaults are not guaranteed to work. The acid and enc values are captured from the original portal request, and the documentation is explicit that enc is usually the default srun_bx1 but that you may need to search the page's JavaScript for the real value. On a campus whose portal has been customised, the first run is a configuration exercise rather than a download and run.

The third is the security model, and the documentation says it in one sentence: campus network internal traffic is not secure, and the school often imposes monitoring on it. This program puts your campus credentials in a configuration file, sends them over the campus network, and in DDNS mode publishes an address for that network. On an untrusted network that is a credential at rest and in flight, and that is the trade for the convenience of automatic reconnection.

The fourth is the multi-NIC feature, which the documentation itself qualifies with the warning that the same account on multiple devices under one gateway may share a bandwidth limit, so multi-dial achieves nothing at some schools. The feature is real, and its benefit is site dependent.

Compare that with a browser based login or a router plugin that does the same job. The difference in approach is that those keep the credential handling inside a maintained component, while this gives you a small, readable, cross-compilable binary that you control and that can live on a device with nothing else on it. For a campus that lets it, that is worth the operational ownership.

## Project state, dependencies and what to check first

The project is released under the AGPL-3.0 licence, with the text in the LICENSE file at the repository root, and the release history shows a steady patch line: v1.6.6 on 2026-01-15, v1.6.7 on 2026-06-23 and v1.6.8 on 2026-09-20. The repository is not archived, and the last push was on 2026-09-20, the same day as the newest release, so the tree is about a month old relative to today.

The dependency list in go.mod is small and tells you what the program actually does. The Mmx233 BackoffCli backoff package handles the retry backoff, Mmx233/tool provides general helpers, sirupsen/logrus does the logging with a nested-logrus-formatter for the output style, cloudflare-go covers the Cloudflare DDNS provider, and the Tencent Cloud SDK covers the DNSPod provider through its dnspod package. gopkg.in/yaml.v3 handles the configuration format.

The tencentcloud SDK dependency is a good sign about the DDNS work, since it means the DNSPod path is a real API client rather than a scripted HTTP call.

What to check before you set it running is a short list. First, capture the real login parameters as the documentation describes, with preserve log enabled in the browser console, and fill in the acid and enc values rather than trusting the defaults. Then run it once in the foreground with debug logging on and read what it reports, because a failed login in guardian mode with backoff disabled will look like a hang.

Then decide the retention of your own credentials. The configuration file holds a password in clear text, it is mounted into a container in the Docker path, and the file is written by the program on first run, so it needs restrictive permissions in whatever directory you run it from. And if you are putting it on a router, confirm the firmware build actually runs the client as a service rather than as something you start by hand, since the OpenWrt route exists precisely to have the package manager start it for you.

## Conclusion

BitSrunLoginGo fits a student or a lab assistant whose campus network drops the connection and who wants the login re-established without a browser, and it fits anyone who needs the same script on a router or in a container, which is where a compiled Go binary earns its keep over a Python script. It does not fit an institution that blocks the portal, and the documentation itself notes that campus internal traffic is not secure and is often monitored. Before you deploy it, capture the real login parameters from the portal request as the documentation describes, because the default acid and enc values are placeholders, and read the AGPL-3.0 terms before you ship it inside a commercial product.

## FAQ

### What does BitSrunLoginGo do?

It is the Go version of the campus network login script for the srun portal, and it authenticates with credentials you supply. The main login logic comes from the BIT-srun-login-script project, and the Go port exists so the same program runs on Windows, Linux, routers and Docker.

### How do I build BitSrunLoginGo?

Install a current Go, clone the repository, and run go build ./cmd/bitsrun, or use the optimised form go build -trimpath -ldflags "-s -w -extldflags '-static -fpic'" ./cmd/bitsrun. For a MIPS router you set CGO_ENABLED to 0 and the target GOOS and GOARCH before the same build command.

### Where does BitSrunLoginGo store its configuration?

The configuration file is generated automatically on the first run and defaults to Config.yaml in the current directory, and the format can be json or yaml with yaml as the default. You can point at a different file with the --config flag, for example ./bitsrun --config=./another-config.yaml.

### What are the guardian mode and the DDNS feature for?

Guardian mode keeps the program resident in the background and re-checks the connection on a cycle you set, with an optional backoff on failed logins. DDNS sets the A record of a domain you specify after a successful login, or when guardian mode first finds you already online, and it supports Cloudflare, Aliyun and DNSPod with provider specific configuration keys.

### Can I use BitSrunLoginGo on OpenWrt?

Yes. The documentation points at the immortalwrt packages tree where net/bitsrunlogin-go holds the build configuration file, and at the luci tree for the applications/luci-app-bitsrunlogin-go interface, so a router can build the client as a native package and expose it in its web interface.

### What licence does BitSrunLoginGo use?

The project uses the AGPL V3 licence, with the text in the LICENSE file at the repository root, and the README asks you to consider the reference carefully before using it. The newest release is v1.6.8 from 2026-09-20.

## Sources

- [Issues](https://github.com/Mmx233/BitSrunLoginGo/issues)
- [License: AGPL-3.0](https://github.com/Mmx233/BitSrunLoginGo/blob/main/LICENSE)
- [Mmx233/BitSrunLoginGo on GitHub](https://github.com/Mmx233/BitSrunLoginGo)
- [README](https://github.com/Mmx233/BitSrunLoginGo/blob/main/README.md)
- [Releases](https://github.com/Mmx233/BitSrunLoginGo/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mmx233-bitsrunlogingo
