Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
3a2aafd
feat(admin): implement admin panel with user management and traffic t…
ryanbekhen Mar 25, 2026
f49210a
fix(httpproxy): validate and normalize proxy target URLs
ryanbekhen Mar 25, 2026
5a4bae9
feat(httpproxy): enhance proxy target URL resolution to prevent SSRF …
ryanbekhen Mar 25, 2026
85236f8
chore: update comments and minor code improvements
ryanbekhen Mar 25, 2026
e363fcd
feat(httpproxy): refactor HTTP proxy to use low-level connection hand…
ryanbekhen Mar 26, 2026
36324a9
feat(docker): add volume for persistent data storage in Dockerfiles
ryanbekhen Mar 26, 2026
8779751
fix(docker): set executable permissions and remove redundant mkdir
ryanbekhen Mar 26, 2026
7e4ac9d
feat(docker): move user data store to /var/lib/nanoproxy
ryanbekhen Mar 26, 2026
340e342
feat(admin): replace static admin credentials with first-run setup
ryanbekhen Mar 26, 2026
86f0a1b
feat(admin): add comprehensive setup flow validation and tests
ryanbekhen Mar 26, 2026
33c2206
feat(proxy): reduce log noise for common connection errors
ryanbekhen Mar 26, 2026
5c62ce7
feat(config): add LOG_LEVEL environment variable support
ryanbekhen Mar 26, 2026
5b4208a
fix(deps): remove redundant coverpkg flag from test coverage
ryanbekhen Mar 26, 2026
cbec0a4
feat(auth): enhance proxy authentication error handling and logging
ryanbekhen Mar 26, 2026
b70113d
feat(admin): update configuration management and remove legacy creden…
ryanbekhen Mar 26, 2026
faf717a
feat(docs): update README features list with completed authentication…
ryanbekhen Mar 26, 2026
36d77c0
feat(proxy): add detailed structured logging for proxy operations
ryanbekhen Mar 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/skills/configuration-management/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ Validate configuration values after parsing.
type Config struct {
SOCKS5Addr string `env:"SOCKS5_ADDR" envDefault:"0.0.0.0:1080"`
HTTPProxyAddr string `env:"HTTP_PROXY_ADDR" envDefault:"0.0.0.0:8080"`
Credentials []string `env:"CREDENTIALS"`
TOREnabled bool `env:"TOR_ENABLED" envDefault:"false"`
TORControlAddr string `env:"TOR_CONTROLLER_ADDR" envDefault:"127.0.0.1:9051"`
Timezone string `env:"TIMEZONE" envDefault:"UTC"`
Expand Down Expand Up @@ -136,7 +135,7 @@ logger.Fatal().Err(err).Msg("failed to start SOCKS5 server")

## Related skills

- Credential Management - Handling credentials in config
- Credential Management - Handling persisted proxy users and admin-auth flows
- Docker Deployment - Passing config via environment
- SOCKS5 Protocol - Using config in SOCKS5 setup
- HTTP Proxy - Using config in HTTP proxy setup
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:

- uses: actions/setup-go@v2
with:
go-version: 1.25
go-version: 1.26

- run: go mod download

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
unset GOCOVERDIR
go version
go tool -n covdata || true
go test ./... -coverprofile=./cover.out -covermode=atomic -coverpkg=./...
go test ./... -coverprofile=./cover.out -covermode=atomic

- name: Check Test Coverage
id: coverage
Expand Down
4 changes: 1 addition & 3 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ archives:
- zip
files:
- README.md
- docs/CONFIG.md
- LICENSE


Expand Down Expand Up @@ -185,9 +186,6 @@ nfpms:
- src: systemd/nanoproxy.service
dst: /etc/systemd/system/nanoproxy.service
type: "config|noreplace"
- src: config/nanoproxy
dst: /etc/nanoproxy/nanoproxy
type: "config|noreplace"
formats:
- deb
- rpm
Expand Down
8 changes: 4 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
## Key architecture and data flow

- Config is env-driven via struct tags in `pkg/config/config.go` (`caarlos0/env/v10`), not via JSON/YAML files.
- Credentials are loaded from `CREDENTIALS` (`username:bcryptHash` list), stored in `pkg/credential/credentials.go`, and
validated with bcrypt.
- User credentials are managed through the Admin Console and stored in `USER_STORE_PATH` (BoltDB). Credentials are
validated with bcrypt in `pkg/credential/credentials.go`.
- SOCKS5 flow (`pkg/socks5/socks5.go`): handshake -> auth negotiation -> request parse (`pkg/socks5/request.go`) ->
optional DNS resolve -> relay.
- HTTP flow (`pkg/httpproxy/httpproxy.go`): `ServeHTTP` dispatches `CONNECT` vs normal HTTP; hop-by-hop headers are
Expand All @@ -28,8 +28,8 @@
`pkg/tor/controller.go`).
- `Dockerfile-tor` + `supervisord.conf` run both Tor and NanoProxy in one container; this is the intended Tor deployment
path.
- System package/service deployment uses `systemd/nanoproxy.service` and env file `config/nanoproxy` (
`/etc/nanoproxy/nanoproxy`).
- System package/service deployment uses `systemd/nanoproxy.service` with inline `Environment=` values and optional
systemd drop-ins for overrides.

## Developer workflows that matter here

Expand Down
10 changes: 8 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
FROM alpine:3
FROM alpine:3.21
ARG TARGETPLATFORM
COPY $TARGETPLATFORM/nanoproxy /usr/bin
COPY --chmod=0755 $TARGETPLATFORM/nanoproxy /usr/bin/nanoproxy

ENV USER_STORE_PATH=/var/lib/nanoproxy/data.db

VOLUME ["/var/lib/nanoproxy"]

EXPOSE 1080
EXPOSE 8080
EXPOSE 9090

ENTRYPOINT ["nanoproxy"]
12 changes: 9 additions & 3 deletions Dockerfile-tor
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,23 @@ ARG TARGETPLATFORM
RUN apk update && \
apk add --no-cache tor supervisor

RUN mkdir -p /var/log/supervisor
RUN mkdir -p /var/log/supervisor /var/log/tor

COPY $TARGETPLATFORM/nanoproxy /usr/bin
COPY --chmod=0755 $TARGETPLATFORM/nanoproxy /usr/bin/nanoproxy
COPY supervisord.conf /etc/supervisord.conf

RUN mkdir -p /etc/tor && \
echo -e "ControlPort 9051\nCookieAuthentication 0" > /etc/tor/torrc

RUN mkdir -p /var/lib/tor
RUN mkdir -p /var/lib/tor /var/lib/nanoproxy


ENV USER_STORE_PATH=/var/lib/nanoproxy/data.db

VOLUME ["/var/lib/tor", "/var/lib/nanoproxy"]

EXPOSE 1080
EXPOSE 8080
EXPOSE 9090

ENTRYPOINT ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ install-go-test-coverage:

.PHONY: check-coverage
check-coverage: install-go-test-coverage
env -u GOCOVERDIR go test ./... -coverprofile=./cover.out -covermode=atomic -coverpkg=./...
env -u GOCOVERDIR go test ./... -coverprofile=./cover.out -covermode=atomic
env -u GOCOVERDIR ${GOBIN}/go-test-coverage --config=./.testcoverage.yml

.PHONY: coverage-only
coverage-only:
env -u GOCOVERDIR go test ./... -coverprofile=./cover.out -covermode=atomic -coverpkg=./...
env -u GOCOVERDIR go test ./... -coverprofile=./cover.out -covermode=atomic

clean:
@echo "Cleaning up dist directory..."
Expand Down
68 changes: 18 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,8 @@ NanoProxy provides the following features:
- [x] **TOR support.** NanoProxy can be run with Tor support to provide anonymized network traffic (Docker only).
- [x] **IP Rotation with Tor.** NanoProxy allows for IP rotation using the Tor network, providing enhanced anonymity and
privacy by periodically changing exit nodes.
- [ ] **Authentication Management from Dashboard.** Easily manage user authentication settings and credentials via a
- [x] **Authentication Management from Dashboard.** Easily manage user authentication settings and credentials via a
comprehensive and user-friendly web dashboard, ensuring secure access to proxy features.
- [ ] **Change IP via API.** Programmatically request IP changes through a robust API, facilitating automated and
dynamic IP management for different use cases.

## Installation

Expand Down Expand Up @@ -208,64 +206,32 @@ nanoproxy
You can also run NanoProxy using Docker. To do so, you can use the following command:

```shell
docker run -p 1080:1080 -p 8080:8080 ghcr.io/ryanbekhen/nanoproxy:latest
docker run -p 1080:1080 -p 8080:8080 -p 9090:9090 ghcr.io/ryanbekhen/nanoproxy:latest
```

You can also run NanoProxy behind Tor using the following command:

```shell
docker run --rm -e TOR_ENABLED=true -d --privileged --cap-add=NET_ADMIN --sysctl net.ipv6.conf.all.disable_ipv6=0 --sysctl net.ipv4.conf.all.src_valid_mark=1 -p 1080:1080 -p 8080:8080 ghcr.io/ryanbekhen/nanoproxy-tor:latest
docker run --rm -e TOR_ENABLED=true -d --privileged --cap-add=NET_ADMIN --sysctl net.ipv6.conf.all.disable_ipv6=0 --sysctl net.ipv4.conf.all.src_valid_mark=1 -p 1080:1080 -p 8080:8080 -p 9090:9090 ghcr.io/ryanbekhen/nanoproxy-tor:latest
```

## Configuration

You can also set the configuration using environment variables. Create a file at `/etc/nanoproxy/nanoproxy` and add the
desired values:

```text
ADDR=:1080
ADDR_HTTP=:8080
NETWORK=tcp
TZ=Asia/Jakarta
CLIENT_TIMEOUT=10s
DNS_TIMEOUT=10s
CREDENTIALS=username:passwordHash
```

For the creation of the password hash, you can use the `htpasswd -nB username` command, but you need to install the
`apache2-utils` package first. To install the package, run the following command:

```shell
sudo apt install apache2-utils
```
NanoProxy is configured entirely through environment variables. For detailed information about all available
configuration options, environment variable reference, and examples, see [docs/CONFIG.md](docs/CONFIG.md).

Then, you can use the `htpasswd` command to generate the password hash:
### Quick Start Configuration

```shell
htpasswd -nB username
export ADDR=:1080
export ADDR_HTTP=:8080
export ADDR_ADMIN=:9090
export LOG_LEVEL=info
export USER_STORE_PATH=./nanoproxy-data.db
```

This will prompt you to enter the password. After entering the password, the command will output the username and the
password hash. You can then use the output to set the `CREDENTIALS` environment variable.

The following table lists the available configuration options:

| Name | Description | Default Value |
|-----------------------|-----------------------------------------------------------------|---------------|
| ADDR | The address to listen on. | `:1080` |
| ADDR_HTTP | The address to listen on for HTTP requests. | `:8080` |
| NETWORK | The network to listen on. (tcp, tcp4, tcp6) | `tcp` |
| TZ | The timezone to use. | `Local` |
| CLIENT_TIMEOUT | The timeout for connecting to the destination Server. | `10s` |
| DNS_TIMEOUT | The timeout for DNS resolution. | `10s` |
| CREDENTIALS | The credentials to use for authentication. | `""` |
| TOR_ENABLED | Enable Tor support. (works only on Docker) | `false` |
| TOR_IDENTITY_INTERVAL | The interval to change the Tor identity. (works only on Docker) | `10m` |

- **ADDR_HTTP**: By default, NanoProxy listens for HTTP proxy traffic on `:8080`. You can set this address to any host:
port combination for custom setups.
- **CREDENTIALS**: When enabled, both SOCKS5 and HTTP Proxy requests are authenticated using the credentials provided in
this field. This supports `username:password` pairs.
Then access the admin panel at `http://localhost:9090/admin/setup` to create your initial admin account and add proxy
users.

## Logging

Expand Down Expand Up @@ -293,7 +259,8 @@ curl -x socks5://localhost:1080 https://google.com
curl -x localhost:8080 https://google.com
```

If credentials are enabled for HTTP Proxy, use the `-U` flag to supply the username and password:
If the HTTP proxy requires authentication, use the `-U` flag to supply the username and password for a proxy user
created in the Admin Console:

```shell
curl -x http://localhost:8080 -U username:password https://example.com
Expand All @@ -303,8 +270,9 @@ In both cases, replace `localhost:8080` with the actual address and port where y

## Authentication for HTTP Proxy

If authentication is enabled (via the `CREDENTIALS` configuration), the HTTP Proxy requires clients to include the
`Proxy-Authorization` header in their requests. The header must use the following format:
Proxy users are managed through the Admin Console. After setting up an admin account, you can create and manage proxy
users through the web interface. The HTTP Proxy requires clients to include the `Proxy-Authorization` header in their
requests with the correct format:

```http
Proxy-Authorization: Basic <base64_encoded("username:password")>
Expand Down
3 changes: 0 additions & 3 deletions config/nanoproxy

This file was deleted.

Loading
Loading