An office laptop should open the same CiviCRM bookmark at its desk and again from home over the VPN. The design that survives contact with users is one canonical address, say https://crm.example.org/, with an approved network path from each location, and a certificate that is valid for that name. The VPN changes how a remote client reaches the server. It should never change the application's identity, because the moment it does, every generated link, redirect and integration callback becomes a second problem to solve.

Pick the URL before you pick the route

Write the intended address down first, including any path component the CMS needs, and treat it as the fixed point. Everything else in this runbook is an implementation detail that can change without touching it: which DNS answer each group receives, which firewall rule permits the listener, and whether the traffic arrives over a tunnel or a local switch port.

Record four values together in the access plan, because they only work as a set. The canonical URL. The answer each client group should receive for that name. The route and access rule for that answer. The hostname the web server and certificate are configured to serve. When something breaks later, the broken element is one of those four, and you will know which one you changed.

Step 1: make the name resolve correctly for both groups

Both groups should get a private answer they can actually reach, and it is legitimate for the answers to differ as long as the name does not. LAN clients resolve through the internal resolver; VPN clients need a resolver policy that hands them the same zone rather than leaking the query to a public resolver and getting a public answer they cannot use.

Test the name from each context instead of assuming, and test the path independently of DNS with curl's resolve option, which pins the address for one request:

dig +short crm.example.org
curl -sSI --resolve crm.example.org:443:10.10.5.20 https://crm.example.org/ | head -5

If the first test returns an address the client cannot reach, the tunnel routing or the split-tunnel list is the problem. If the second test returns a redirect to a hostname you did not expect, stop and read the Location header, because that is an application issue and no route change will fix it.

Step 2: align the web server, certificate and CMS base URL

The listener must be configured to serve the canonical name, and the certificate must cover it. Browsing by raw address is not a workaround: it produces a name mismatch, it can break cookie scope, and it teaches users to click through warnings that you will later have to explain to an auditor.

Behind a reverse proxy, make sure the application knows the request arrived over HTTPS. Most CMS platforms will generate absolute links from the detected scheme, and a proxy that terminates TLS without forwarding the original scheme produces a page full of http:// resources that a browser may block. Configure the trusted proxy and forwarded headers explicitly rather than letting the application guess.

Then align the CMS and CiviCRM base URL. CiviCRM keeps its determined base URL and exposes a supported way to recalculate it: the administrative Cleanup Caches and Update Paths action, documented in the CiviCRM installation troubleshooting guide. Run it after the canonical name and CMS setting agree, not before, or you will simply cache a value you are about to change.

cv flush
# then Administer > System Settings > Cleanup Caches and Update Paths

Step 3: check the addresses CiviCRM generates

Reaching the front page proves very little. CiviCRM runs inside a CMS, and the pages that matter are the ones that build their own URLs: the login redirect, the administration menu, extension resources, uploaded file links and any external callback registered by an integration.

Load the dashboard, open a contact record, and view the page source for absolute links. If they point at a hostname that only one client group can reach, the base URL is still wrong even though the page rendered. If they point at the right name but the wrong scheme, the proxy configuration is the thing to fix.

Where the address genuinely has to change, treat it as an application migration rather than a DNS edit. Review resource URLs, caches, published links and every external integration that stores the old address, then update them in one window so nobody is holding a half-migrated bookmark.

A request hostname is not a trust decision

Do not select a privileged base URL because a request header contains a particular string. PHP documents Apache configurations in which the server-name value can reflect a client-supplied host, and the server address variable describes the server, not the visitor's location. Neither of those is an access-control mechanism, and building one out of them is how a private service ends up serving the wrong content to the wrong host.

If multiple hostnames are genuinely required, configure an explicit allowlist at the web server, the CMS and the application layer, and let the request hostname select among approved entries only. Arbitrary input should never become the source of absolute links or a trusted redirect destination.

Finish with the same bookmark in each approved context: a login, an ordinary internal navigation, and one resource request. Compare the hostnames in the responses, not just whether the page loaded. That three-request check separates a path problem from an application that is still generating the wrong address, and it takes about a minute per client group.

ХӀокхунах тера йаззамаш