blob: 93d4ed9ad1219374c1008b2fe226a3bc31fbd349 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#+date: <2022-12-07 Wed 00:00:00>
#+title: Configuring Nginx for Subdomain and URL Path Redirection Using Regular Expressions
#+description: Instructional steps for applying regex-based redirects in Nginx to manage subdomain routing and trailing path modifications effectively.
#+slug: nginx-wildcard-redirect
#+filetags: :nginx:redirect:regex:
* Problem
I recently migrated domains and replaced the old webpage with a simple
info page with instructions to users on how to edit their bookmarks and
URLs to get to the page they were seeking.
This was not ideal as it left the work up to the user and may have
caused friction for users who accessed my RSS feed.
* Solution
Instead, I finally found a solution that allows me to redirect both
subdomains AND trailing content. For example, both of these URLs now
redirect properly using the logic I'll explain below:
#+begin_src txt
# Example 1 - Simple base domain redirect with trailing content
https://domain1.com/blog/alpine-linux/ -> https://domain2.com/blog/alpine-linux/
# Example 2 - Complex redirect with both a subdomain and trailing content
https://libreddit.domain1.com/r/history/comments/7z8cbg/new_discovery_mode_turns_video_game_assassins/
->
https://libreddit.domain2.com/r/history/comments/7z8cbg/new_discovery_mode_turns_video_game_assassins/
#+end_src
Go ahead, try the URLs if you want to test them.
** Nginx Config
To make this possible. I needed to configure a proper redirect scheme in
my Nginx configuration.
#+begin_src sh
doas nano /etc/nginx/http.d/domain1.conf
#+end_src
Within this file, I had one block configured to redirect HTTP requests
to HTTPS for the base domain and all subdomains.
#+begin_src conf
server {
listen [::]:80;
listen 80;
server_name domain1.com *.domain1.com;
if ($host = domain1.com) {
return 301 https://$host$request_uri;
}
if ($host = *.domain1.com) {
return 301 https://$host$request_uri;
}
return 404;
}
#+end_src
For the base domain, I have another =server= block dedicated to
redirecting all base domain requests. You can see that the =rewrite=
line is instructing Nginx to gather all trailing content and append it
to the new =domain2.com= URL.
#+begin_src conf
server {
listen [::]:443 ssl http2;
listen 443 ssl http2;
server_name domain1.com;
rewrite ^/(.*)$ https://domain2.com/$1 permanent;
ssl_certificate /etc/letsencrypt/live/domain1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain1.com/privkey.pem;
}
#+end_src
Finally, the tricky part is figuring out how to tell Nginx to redirect
while keeping both a subdomain and trailing content intact. I found that
the easiest way to do this is to give it a =server= block of its own.
Within this block, we need to do some regex on the =server_name= line
before we can rewrite anything. This creates a variable called
=subdomain=.
Once the server gets to the =rewrite= line, it pulls the =subdomain=
variable from above and uses it on the new =domain2.com= domain before
appending the trailing content (=$request_uri=).
#+begin_src conf
server {
listen [::]:443 ssl http2;
listen 443 ssl http2;
server_name ~^(?<subdomain>\w+)\.domain1\.com$;
rewrite ^ https://$subdomain.domain2.com$request_uri permanent;
ssl_certificate /etc/letsencrypt/live/domain1.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain1.com/privkey.pem;
}
#+end_src
That's all there is to it. With this, I simply restarted Nginx and
watched the redirections work in-action.
#+begin_src sh
doas rc-service nginx restart
#+end_src
Looking back on it, I wish I had done this sooner. Who knows how many
people went looking for my sites or bookmarks and gave up when they saw
the redirect instructions page.
Oh well, it's done now. Live and learn.
|