How do you make a 301 redirect from one domain to another on Linux?

Use a 301 redirect only after checking the server context

A 301 status means the resource has moved permanently; the HTTP definition is in RFC 9110 section 15.4.2. On Linux, the exact code depends on whether the old domain is served by Nginx, Apache virtual-host config, or a root .htaccess file.

Nginx server block

Nginx can return a redirect with the return directive. $request_uri keeps the old path and query string.

server {
    listen 80;
    server_name www.abc.cn abc.cn;
    return 301 https://efg.com$request_uri;
}

Before reloading Nginx, run a syntax check such as nginx -t; Nginx documents command-line switches in its switches reference.

Apache virtual host

In server or virtual-host context, the URL path can begin with /. Apache’s rewrite examples are covered in mod_rewrite remapping.

<VirtualHost *:80>
    ServerName www.abc.cn
    ServerAlias abc.cn
    RewriteEngine On
    RewriteRule ^/(.*)$ https://efg.com/$1 [R=301,L]
</VirtualHost>

Root .htaccess: choose one pattern, not both

For a root .htaccess file, Apache uses per-directory matching, so a RewriteRule pattern beginning with ^/ will not match. Apache documents this in its per-directory rewrite guide. If the file is in the site root, use one of the following two approaches; do not paste both into the same file.

Option A: simple root .htaccess redirect.

RewriteEngine On
RewriteRule ^(.*)$ https://efg.com/$1 [R=301,L]

Option B: use REQUEST_URI when you must preserve the original request URI explicitly.

RewriteEngine On
RewriteCond %{REQUEST_URI} ^/(.*)$
RewriteRule ^ https://efg.com%{REQUEST_URI} [R=301,L]

HTTPS and testing

  • The destination URL, such as https://efg.com/, should return 200 before the migration.
  • If visitors may request https://www.abc.cn/, the old domain still needs a valid certificate and a matching 443 host. The TLS handshake happens before the browser can receive any HTTP 301 response; TLS 1.3 is specified in RFC 8446.
  • Run apachectl configtest or the equivalent before reloading Apache; the apachectl documentation describes the command.
  • Test old HTTP and HTTPS URLs with paths and queries, for example curl -I 'http://www.abc.cn/a?x=1' and curl -I 'https://www.abc.cn/a?x=1'. Confirm the Location keeps /a?x=1 and points to https://efg.com/a?x=1.
  • A normal 301 is fine for most page moves, but some clients can change a POST request to GET after a 301. If an API or form endpoint must preserve the method, evaluate 308 for that interface instead of a blanket page migration.
All Insights