Commit b8bc597ac6

b8bc597ac698530b6011c74ec67e2a9b1a87dba6

parent: f2e7d8ca6e

Unsigned

cmc <hello@cleberg.net> · 2024-08-20 01:47 UTC

remove temp file

Layout: unified · split

content/blog/#2022-03-24-server-hardening.org# deleted −293
@@ -1,293 +0,0 @@
1#+date: <2022-03-24>
2#+title: Hardening a Public-Facing Home Server
3#+description:
4
5
6* Post Updates
7
8#+begin_quote
9After reviewing this post today (2022-10-04), I noticed quite a few gaps in my
10write-up and wanted to add a few things, even though this blog is really just a
11retrospective and knowledge dump for myself. I left things intact and simply
12crossed them out (+like this+) for posterity.
13#+end_quote
14
15* Planning Data Flows & Security
16
17** My Personal Data Flow
18
19#+begin_src
20 ┌───────┐ ┌─────────────────┐
21 ┌──► VLAN1 ├───► Private Devices │
22 │ └───────┘ └─────────────────┘
23┌──────────┐ ┌────────┐ ┌──────────┐ ┌────────┐ │
24│ Internet ├───► Router ├───► Firewall ├───► Switch ├──┤
25└──────────┘ └────────┘ └──────────┘ └────────┘ │
26 │ ┌───────┐ ┌───────────────┐
27 └──► VLAN2 ├───► Public Server │
28 └───────┘ └───────────────┘
29#+end_src
30
31** Thought Process
32
33To serve content from your home server and harden your security posture, you
34have to think about the transport of data from =server= to =client=.
35
36Let's start with the actual server itself. Think about the following:
37
38- Do I have a firewall enabled? Do I need to update this to allow new ports or
39 IPs?
40- Do I have an IPS/IDS that may prevent outside traffic?
41- Do I have any other security software installed?
42- Are the services hosted inside Docker containers, behind a reverse proxy, or
43 virtualized? If so, are they configured to allow outside traffic?
44
45Once the data leaves the server, where does it go? In my case, it goes to a
46managed switch. In this case, I asked the following:
47
48- What configurations is the switch using?
49- Am I using VLANs?
50 - Yes, I am using 802.1Q VLANs.
51- Are the VLANs configured properly?
52 - Yes, as shown in the Switch section below, I have a separate VLAN to allow
53 outside traffic to and from the server alone. No other devices, except for a
54 service port, and in that VLAN.
55
56At this point, the data has been processed through the switch. Where does it go
57next? In my case, it's pretty simple: it goes to the router/modem device.
58
59- Does my ISP block any ports that I need?
60 - This is an important step that a lot of people run into when self-hosting at
61 home. Use an online port-checker tool for your IP or call your ISP if you
62 think ports are blocked.
63- Is there a router firewall?
64 - Yes, I checked that it's configured to allow the ports I need to run my
65 services publicly. Common web servers and reverse proxies require ports 80
66 and 443, but other services like media servers or games can require unique
67 ports, so be sure to check the documentation for your service(s).
68- Are there any other settings affecting inbound/outbound traffic?
69 - Schedules or access blocks
70 - Static Routing
71 - QoS
72 - Port Forwarding
73 - DMZ Hosting
74 - Remote Management (this can sometimes mess with services that also require
75 the use of ports 80 and 443)
76
77Once the data leaves my router, it goes to the upstream ISP and can be accessed
78publicly.
79
80*** Server
81
82The services I run on my server are installed straight into the OS, without any
83use of Docker or VMs, so I don't need any extra application configuration to
84make them accessible to the outside world.+
85
86As of 2022-10-04, the paragraph above is no longer true as I now run a reverse
87proxy with Nginx and host many services inside Docker. However, it doesn't
88change anything regarding this post as I still just need to open ports 80 & 443
89and create the necessary website configuration files.
90
91When creating new services - either installed directly on bare metal or within
92something like Docker - I ensure that I read through the documentation
93thoroughly to understand a few key things: - What network activities should this
94app perform (if any)? Using which ports and protocols? - Does this app require
95any commands/services to be run as =root=? - Does this app log errors,
96authentication failures/successes, or anything else that would be useful for an
97investigation?
98
99For extra security, I use limit all incoming connections to SSH connections
100through my server firewall (=ufw=) and disable common SSH settings. After all of
101that, I use =fail2ban= as a preventative measure against brute-force login
102attempts.
103
104As another piece of security, you can randomize your SSH port to ensure that
105random scanners or attackers can't easily try to force their way into your
106network. For example, you can edit the port rules in your server to block all
107connection requests to port =22= but forward all remote connections from port
108=12345= to your server's port =22=. Then you just need to SSH to your network
109via your randomized port.
110
111** =ufw=
112
113To see how to configure =ufw=, see my other post: [[/blog/ufw.html][Secure Your
114Network with the Uncomplicated Firewall]].
115
116The general notion with an on-device firewall is that you want to deny all
117incoming connections by default and then selectively open certain ports for
118services or users that you know need access.
119
120If you know that you will only be logging into this server from a certain set or
121list of IPs, you can always set the firewall to only allow connections to port
12222 from those IPs.
123
124For a quick start to only allow SSH connections to the server, use this:
125
126#+begin_src sh
127sudo ufw default deny incoming
128sudo ufw default allow outgoing
129sudo ufw allow 22
130sudo ufw enable
131#+end_src
132
133** =ssh=
134
1351. Using SSH Keys
136
137 First, make sure you have an SSH keypair generated on the device(s) that
138 you'll be using to log in to the server. If you don't have an SSH key, run
139 this command:
140
141 #+begin_src sh
142 ssh-keygen
143 #+end_src
144
145 Now that we have an SSH key, copy it to the server with the following
146 command, which will ask for the user's password before accepting the key:
147
148 #+begin_src sh
149 ssh-copy-id my_user@my_server
150 #+end_src
151
152 If you have multiple keys, you'll need to specify which to use. After it's
153 complete, =ssh= back into the server as that user and make sure it doesn't
154 ask for a password.
155
1562. Disable Password & Root Authentication
157
158 Now that we can access the server without a password, we will disable
159 password authentication and disable anyone from using =ssh= to login as
160 =root=.
161
162 To do this, open the =sshd_config= file:
163
164 #+begin_src sh
165 sudo nano /etc/ssh/sshd_config
166 #+end_src
167
168 You'll need to update the parameters to the values below. If one of these
169 rules is commented-out or doesn't exist, create the rule at the bottom of the
170 file.
171
172 #+begin_src config
173 PermitRootLogin no
174 PasswordAuthentication no
175 PubkeyAuthentication yes
176 #+end_src
177
178 Finally, restart the =ssh= service:
179
180 #+begin_src sh
181 sudo systemctl restart sshd.service
182 #+end_src
183
184 To test that everything's working so far, open ANOTHER terminal and try
185 logging in as =root= over SSH. It is very important that you keep your
186 current SSH session open and test with an additional session, or you will
187 lock yourself out at some point and will need to use a recovery method (e.g.,
188 hooking monitor up to home server) to get yourself back in.
189
1903. Enable MFA for =ssh=
191
192 This part is optional, but I highly recommend it. So far, we've ensured that
193 no one can log into our user on the server without using our secret key, and
194 we've ensured that no one can log in remotely as =root=. Next, you can enable
195 MFA authentication for =ssh= connections.
196
197 This process involves editing a couple files and installing an MFA package,
198 so I will not include all the details in this post. To see how to configure
199 MFA for =ssh=, see my other post: [[/blog/ssh-mfa.html][Enabling MFA for
200 SSH]].
201
202** =fail2ban=
203
204I haven't written a post on how I use =fail2ban=, but it's quite simple. I use
205the default =sshd= jail, but you can always create new jails for respective
206applications or ports. For example, if you use Nginx as your web server, you can
207use the =nginx-http-auth= jail.
208
209In order to get it up and running, use the following commands:
210
211#+begin_src sh
212sudo apt install fail2ban
213sudo fail2ban-client start sshd
214sudo fail2ban-client status sshd
215#+end_src
216
217This should be used as a last-resort defense and shouldn't be a replacement for
218the security measures mentioned above.
219
220* Switch
221
222Between the router and any local devices is my managed switch, which is used to
223create VLANs. The example below shows how I would isolate the VLANs if I were
224starting to host a single service at home.
225
226** 802.1Q VLAN Configuration
227
228In this configuration, port 8 is the public server that needs to be accessed
229from the outside. Port 23 is my 'dedicated service port' for this server. In
230order to SSH to this server, I need to plug my laptop into port 23 or else I
231cannot SSH. Otherwise, I'd need to hook up a monitor and keyboard directly to
232the server to manage it.
233
234#+begin_verse
235#+end_verse
236
237| VLAN ID | VLAN Name | Member Ports | Tagged Ports | Untagged Ports |
238|---------+-----------+--------------+--------------+----------------|
239| 1 | Default | 1-24 | 1-24 | |
240| 2 | Server | 1,8,23 | 1,8,23 | |
241
242** 802.1Q VLAN PVID Setting
243
244Once the VLAN is created, I simply add the =VLAN ID= of =2= as the =PVID= for
245any related ports (in this case, see that ports =8= and =23= have a PVID of
246=2=).
247
248| Port | PVID |
249|------+------|
250| 1 | 1 |
251| 2 | 1 |
252| 3 | 1 |
253| 4 | 1 |
254| 5 | 1 |
255| 6 | 1 |
256| 7 | 1 |
257| 8 | 2 |
258| 9 | 1 |
259| 10 | 1 |
260| 11 | 1 |
261| 12 | 1 |
262| 13 | 1 |
263| 14 | 1 |
264| 15 | 1 |
265| 16 | 1 |
266| 17 | 1 |
267| 18 | 1 |
268| 19 | 1 |
269| 20 | 1 |
270| 21 | 1 |
271| 22 | 1 |
272| 23 | 2 |
273| 24 | 1 |
274
275* Router
276
277On my router, the configuration was as easy as opening the firewall settings and
278unblocking the ports I needed for my services (e.g., HTTP/S, Plex, SSH, MySQL,
279etc.).
280
281Since I'm relying on an ISP-provided modem/router combo for now (not by
282choice), I do not use any other advanced settings on my router that would
283inhibit any valid traffic to these services.
284
285The paragraph above regarding the ISP-owned router is no longer accurate as I
286now use the Ubiquiti Unifi Dream Machine Pro as my router. Within this router, I
287enabled port forwarding/firewall rules, segregate the network based on the
288device, and enable traffic restrictions (e.g., silently drop traffic from
289certain countries and threat categories).
290
291If you have the option with your ISP, I recommend using a personal router with
292software that you are familiar with so that you can explore all the options
293available to you.