Can Mercurial be configured to bind hg serve to localhost by default?
0 reputation · 03 Jun 2020, 13:50 UTC
0 reputation · 03 Jun 2020, 13:50 UTC
The goal is to prevent Mercurial’s built‑in web server from unintentionally serving repositories on non‑loopback interfaces. By default, `hg serve` listens on 0.0.0.0:8000, making the repository reachable to any host on the network without emitting a warning when the bind address is not localhost.
Although the documentation highlights this exposure risk, the default bind address has not been altered, and the `-a/--address` flag must be supplied each time the server is started. Ongoing debate in the Mercurial community about switching the default to localhost‑only has not produced a consensus in the 6.x series, leaving the behavior uncertain for users who want a safer out‑of‑the‑box experience.
Can a global configuration option be added to make `hg serve` bind to localhost by default? Would changing the default address affect existing workflows that rely on public access via the built‑in server?
35275 reputation · 03 Jun 2020, 14:06 UTC
No – Mercurial does not provide a configuration option (e.g., in [web] of hgrc) that changes the default bind address for hg serve. The server always binds to 0.0.0.0:8000 unless you explicitly give -a/--address (or --port) on the command line.
The built‑in web server is designed as a quick, ad‑hoc sharing tool. Keeping the permissive 0.0.0.0 bind lets users share a repository on a LAN without extra flags. Changing the default to localhost‑only would break that common workflow, so the upstream project has left the address as an explicit flag.
hg serve listen on localhost onlyalias hgserve='hg serve -a 127.0.0.1'$PATH):#!/usr/bin/env sh
hg serve -a 127.0.0.1 "$@"
[alias] in hgrc but it cannot override the built‑in serve command name; it only creates a new subcommand (e.g., hg localserve). Therefore a shell‑level alias or wrapper is the reliable method.After starting the server with your alias or wrapper, check what address it is bound to:
# start the server (alias or wrapper)
hgserve & # or ./hgserve-wrapper &
# find the PID and ports
ss -tlnp | grep :8000
# or netstat -tlnp | grep :8000
You should see a line showing 127.0.0.1:8000 (or [::1]:8000) and not 0.0.0.0:8000. To confirm it is not reachable from another host, try curl http://<other‑host>:8000 from a different machine; the connection should be refused or time‑out.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.