content/blog/2022-03-24-server-hardening.org

e8577d98faff1bed72ba6f2d204b8b44c6827c23
cleberg.net/content/blog/2022-03-24-server-hardening.org rendered · source · history · blame · raw

342 lines · 13659 bytes

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