A community-maintained fork of rathole.
molehill, like frp and ngrok, can help to expose the service on the device behind the NAT to the Internet, via a server with a public IP.
- High Performance Much higher throughput can be achieved than frp, and more stable when handling a large volume of connections.
- Low Resource Consumption Consumes much fewer memory than similar tools. The binary can be as small as ~500KiB to fit the constraints of devices, like embedded devices as routers.
- Security Tokens of services are mandatory and service-wise. The server and clients are responsible for their own configs. With the optional Noise Protocol, encryption can be configured at ease. No need to create a self-signed certificate! TLS is also supported.
- Hot Reload Services can be added or removed dynamically by hot-reloading the configuration file. HTTP API is WIP.
A full-powered molehill can be obtained from the release page. Or build from source for other platforms and minimizing the binary.
The usage of molehill is very similar to frp. If you have experience with the latter, then the configuration is very easy for you. The only difference is that configuration of a service is split into the client side and the server side, and a token is mandatory.
To use molehill, you need a server with a public IP, and a device behind the NAT, where some services that need to be exposed to the Internet.
Assuming you have a NAS at home behind the NAT, and want to expose its ssh service to the Internet:
- On the server which has a public IP
Create server.toml with the following content and accommodate it to your needs.
# server.toml
[server]
bind_addr = "0.0.0.0:2333" # `2333` specifies the port that molehill listens for clients
[server.services.my_nas_ssh]
token = "use_a_secret_that_only_you_know" # Token that is used to authenticate the client for the service. Change to an arbitrary value.
bind_addr = "0.0.0.0:5202" # `5202` specifies the port that exposes `my_nas_ssh` to the InternetThen run:
./molehill server.toml- On the host which is behind the NAT (your NAS)
Create client.toml with the following content and accommodate it to your needs.
# client.toml
[client]
remote_addr = "myserver.com:2333" # The address of the server. The port must be the same with the port in `server.bind_addr`
[client.services.my_nas_ssh]
token = "use_a_secret_that_only_you_know" # Must be the same with the server to pass the validation
local_addr = "127.0.0.1:22" # The address of the service that needs to be forwardedThen run:
./molehill client.toml- Now the client will try to connect to the server
myserver.comon port2333, and any traffic tomyserver.com:5202will be forwarded to the client's port22.
So you can ssh myserver.com:5202 to ssh to your NAS.
To run molehill as a background service on Linux, checkout the
systemd examples or the
container examples.
molehill determines the running mode (server/client) from the config file
automatically, or you can force it with --server / --client. The full
configuration specification, logging and tuning options are documented in
Configuration. Example configs for
various scenarios are also available.
Download a pre-built binary for your platform from the release page, or build from source for other platforms and minimal-sized binaries.
./molehill server.toml # on the public server
./molehill client.toml # on the device behind NATThe systemd examples show how to run molehill as a systemd service, both as root and rootless, including multiple instances.
Official multi-arch images (linux/amd64, linux/arm64) are published to
ghcr.io/niyueee/molehill. The image is a single static musl binary on
scratch (~8 MiB), runs as non-root UID 1000, and bundles CA certificates
for TLS verification.
docker run -v /etc/molehill/server.toml:/app/server.toml:ro \
ghcr.io/niyueee/molehill:latest server.tomlThe image contains no configuration — mount your config file and pass its
name as the argument. See the container examples
for Docker Compose (compose.yaml / compose.bridge.yaml) and Podman
Quadlet (molehill-server.container / molehill-client.container)
deployments.
- Configuration — full configuration specification, logging, tuning
- Transport — TLS and Noise Protocol setup
- Build guide — build customization, rustls support, minimal binary
- Internals — how control/data channels work
- Examples — configs for common scenarios
- HTTP APIs for configuration
- Configurable UDP receive buffer size (
udp_buffer_size) for large datagrams (e.g. games) - Per-service visitor IP allowlist (
allowed_visitors) - Configurable UDP idle timeout (
udp_idle_timeout) - Per-service connection limit (
max_connections)