Add an rm confirmation guard article and a ufw guide
This commit is contained in:
@@ -153,8 +153,8 @@ Three silent commands, and `ls` showing the result: the copy sits next to the or
|
|||||||
|
|
||||||
Deletes. There is no recycle bin, no undo, no confirmation dialog. `-r` deletes a folder and its contents, `-f` forces without asking.
|
Deletes. There is no recycle bin, no undo, no confirmation dialog. `-r` deletes a folder and its contents, `-f` forces without asking.
|
||||||
|
|
||||||
::warning
|
::warning{to="/nonsense/bash/rm-confirmation"}
|
||||||
`rm -rf` is the command that wipes homelabs. It doesn't check, doesn't warn, and doesn't stop. Read the path twice before pressing :kbd{value="Enter"}, especially when the line starts with `sudo` and contains a `/` or a `*`.
|
`rm -rf` is the command that wipes homelabs. It doesn't check, doesn't warn, and doesn't stop. Read the path twice before pressing :kbd{value="Enter"}, especially when the line starts with `sudo` and contains a `/` or a `*`. You can also prevent this by wrapping `sudo` in a small Bash function that asks **"are you sure?"** before it lets an `rm` through, covered in **rm confirmation guard**.
|
||||||
::
|
::
|
||||||
|
|
||||||
### cat and nano, read and edit
|
### cat and nano, read and edit
|
||||||
|
|||||||
@@ -198,3 +198,63 @@ Being outside `apt` also means it won't be updated by `apt full-upgrade`. Repeat
|
|||||||
|
|
||||||
#### Done !
|
#### Done !
|
||||||
::
|
::
|
||||||
|
|
||||||
|
## ufw, a firewall you can actually read
|
||||||
|
|
||||||
|
Debian's firewall (`iptables`/`nftables` under the hood) is powerful and unreadable directly. `ufw`, *uncomplicated firewall*, is a thin layer on top that turns it into short, plain-English rules, block everything by default and open only what you actually expose.
|
||||||
|
|
||||||
|
::steps{level="4"}
|
||||||
|
#### Install it
|
||||||
|
|
||||||
|
```bash [Terminal]
|
||||||
|
sudo apt install ufw
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Set the default policy
|
||||||
|
|
||||||
|
```bash [Terminal]
|
||||||
|
sudo ufw default deny incoming
|
||||||
|
sudo ufw default allow outgoing
|
||||||
|
```
|
||||||
|
|
||||||
|
Nothing gets in unless a rule says so, everything the server itself initiates still goes out normally.
|
||||||
|
|
||||||
|
#### Allow what you actually need
|
||||||
|
|
||||||
|
```bash [Terminal]
|
||||||
|
sudo ufw allow OpenSSH
|
||||||
|
sudo ufw allow 443/tcp
|
||||||
|
```
|
||||||
|
|
||||||
|
`OpenSSH` is a built-in profile that matches the SSH port, no need to remember which one. Add one `allow` per port you expose, [SWAG](/serveex/core/swag) on `443` for instance.
|
||||||
|
|
||||||
|
::warning
|
||||||
|
Allow SSH **before** enabling the firewall, in the next step. Enable it first and the very connection you're typing in gets cut, with no screen left plugged in to fix it.
|
||||||
|
::
|
||||||
|
|
||||||
|
#### Enable it
|
||||||
|
|
||||||
|
```bash [Terminal]
|
||||||
|
sudo ufw enable
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Check the rules
|
||||||
|
|
||||||
|
```bash [Terminal]
|
||||||
|
sudo ufw status verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
```console [Output]
|
||||||
|
Status: active
|
||||||
|
Logging: on (low)
|
||||||
|
Default: deny (incoming), allow (outgoing), disabled (routed)
|
||||||
|
|
||||||
|
To Action From
|
||||||
|
-- ------ ----
|
||||||
|
22/tcp (OpenSSH) ALLOW IN Anywhere
|
||||||
|
443/tcp ALLOW IN Anywhere
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Done !
|
||||||
|
::
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,10 @@ Finish with *Finish partitioning and write changes to disk*, then confirm with *
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
::tip{icon="" to="/general/linux/filesystem"}
|
||||||
|
✨ __Tip:__ what actually lives on that one partition, and why `/srv/docker` is where this guide puts every stack, is covered in **folders and partitions**.
|
||||||
|
::
|
||||||
|
|
||||||
#### Mirror and surveys
|
#### Mirror and surveys
|
||||||
|
|
||||||
Answer *No* to *Scan another installation medium?*, everything else comes from the network. For the mirror, pick any one in your country, or `deb.debian.org` which routes to a nearby one automatically, and leave the HTTP proxy field empty unless you actually have one. The popularity contest (anonymous package statistics) is yes or no, no consequence either way.
|
Answer *No* to *Scan another installation medium?*, everything else comes from the network. For the mirror, pick any one in your country, or `deb.debian.org` which routes to a nearby one automatically, and leave the HTTP proxy field empty unless you actually have one. The popularity contest (anonymous package statistics) is yes or no, no consequence either way.
|
||||||
@@ -337,34 +341,6 @@ For security patches without having to think about it, `sudo apt install unatten
|
|||||||
- [Everything About Remote Console Access (SSH)](https://www.digitalocean.com/community/tutorials/ssh-essentials-working-with-ssh-servers-clients-and-keys)
|
- [Everything About Remote Console Access (SSH)](https://www.digitalocean.com/community/tutorials/ssh-essentials-working-with-ssh-servers-clients-and-keys)
|
||||||
- Optional - [UPS Client in Case of Power Outage](https://www.sindastra.de/p/2078/how-to-connect-linux-server-to-synology-ups-server) / [also here](https://www.reddit.com/r/synology/comments/gtkjam/use_synology_nas_as_ups_server_to_safely_power/)
|
- Optional - [UPS Client in Case of Power Outage](https://www.sindastra.de/p/2078/how-to-connect-linux-server-to-synology-ups-server) / [also here](https://www.reddit.com/r/synology/comments/gtkjam/use_synology_nas_as_ups_server_to_safely_power/)
|
||||||
|
|
||||||
## Must-Have CLI Apps
|
::tip{icon="" to="/general/linux/handy-tools"}
|
||||||
Some essential apps you’ll likely need at some point, so might as well install them early:
|
✨ __Tip:__ a handful of terminal tools worth adding on top of a minimal install, `btop`, `duf`, `ufw` and a few more, are covered in **handy CLI tools**.
|
||||||
```bash [Terminal]
|
|
||||||
sudo apt update
|
|
||||||
sudo apt upgrade
|
|
||||||
sudo apt install nano btop ranger git duf samba cifs-utils tree unzip
|
|
||||||
```
|
|
||||||
|
|
||||||
::note{to="/general/linux/handy-tools"}
|
|
||||||
What each of these does, plus a few more worth adding like `ncdu` and `lazydocker`, is detailed in **handy CLI tools**.
|
|
||||||
::
|
|
||||||
|
|
||||||
## Useful Features
|
|
||||||
### Firewall
|
|
||||||
|
|
||||||
- [ufw](https://www.zenarmor.com/docs/network-security-tutorials/how-to-set-up-a-firewall-with-ufw-on-debian)
|
|
||||||
- [Firewalld](https://linuxcapable.com/how-to-install-firewalld-on-debian-linux/)
|
|
||||||
|
|
||||||
### Samba Sharing (Access a Remote Network Disk)
|
|
||||||
|
|
||||||
- [Create and Access a Samba Share](/general/networking/samba)
|
|
||||||
|
|
||||||
### File Transfer via rsync
|
|
||||||
|
|
||||||
```bash [Terminal]
|
|
||||||
sudo rsync -avhHSP /source /destination
|
|
||||||
```
|
|
||||||
::note
|
|
||||||
|
|
||||||
Add ` --exclude @eaDir`{lang=shell} if the source is a Synology NAS
|
|
||||||
::
|
::
|
||||||
|
|||||||
@@ -75,4 +75,8 @@ Shut down the server if disks overheat
|
|||||||
::card{icon="i-lucide-database-backup" title="Backrest Docker Stop" to="/nonsense/bash/backrest-docker-stop"}
|
::card{icon="i-lucide-database-backup" title="Backrest Docker Stop" to="/nonsense/bash/backrest-docker-stop"}
|
||||||
Stop containers safely around a Backrest backup
|
Stop containers safely around a Backrest backup
|
||||||
::
|
::
|
||||||
|
|
||||||
|
::card{icon="i-lucide-shield-alert" title="rm Confirmation Guard" to="/nonsense/bash/rm-confirmation"}
|
||||||
|
A sudo wrapper that asks before it lets rm run
|
||||||
|
::
|
||||||
::
|
::
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
---
|
||||||
|
title: rm Confirmation Guard
|
||||||
|
description: A small Bash function that wraps sudo and asks for confirmation before running rm, so a typo doesn't delete files owned by root.
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
|
||||||
|
|
||||||
|
`rm` doesn't ask twice. No recycle bin, no "are you sure", especially not with `sudo` in front of it, where a stray space or the wrong variable can wipe something you own no permission to double-check. It's the single most destructive habit a terminal builds into you, and the fix doesn't need a new tool, just a few lines in `.bashrc`.
|
||||||
|
|
||||||
|
The idea is to shadow the `sudo` command with a Bash function of the same name. Every other use of `sudo` still goes straight through, but the moment the first argument is `rm`, it stops and asks first.
|
||||||
|
|
||||||
|
```bash [.bashrc]
|
||||||
|
# rm confirmation
|
||||||
|
sudo() {
|
||||||
|
if [ "$1" = "rm" ]; then
|
||||||
|
echo -n "Are you sure you want to delete files/folders with sudo? (y/n) "
|
||||||
|
read ans
|
||||||
|
if [[ $ans == [Yy]* ]]; then
|
||||||
|
command sudo rm "${@:2}"
|
||||||
|
else
|
||||||
|
echo "Deletion cancelled."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
command sudo "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
- `sudo() { ... }` defines a function named `sudo`. Bash looks up functions before it looks up commands on the `PATH`, so typing `sudo` in a terminal now runs this instead of `/usr/bin/sudo`, no alias trickery involved.
|
||||||
|
- `if [ "$1" = "rm" ]` only looks at the very first word after `sudo`. `sudo rm -rf /srv/docker/old-stack` matches, `sudo apt update` doesn't.
|
||||||
|
- On a match, it prints the question, reads the answer into `$ans`, and `[[ $ans == [Yy]* ]]` accepts `y`, `Y`, `yes`, anything starting with either case of Y.
|
||||||
|
- `command sudo rm "${@:2}"` is the part that actually deletes. `command` steps around the function so it doesn't call itself, and `${@:2}` is every argument after `rm`, so `-rf /srv/docker/old-stack` is passed through untouched.
|
||||||
|
- Anything that isn't `rm` falls into the `else` and runs exactly as if the function didn't exist: `command sudo "$@"`.
|
||||||
|
|
||||||
|
## Installing it
|
||||||
|
|
||||||
|
::steps{level="3"}
|
||||||
|
### Open your shell config
|
||||||
|
|
||||||
|
```bash [Terminal]
|
||||||
|
nano ~/.bashrc
|
||||||
|
```
|
||||||
|
|
||||||
|
### Paste the function
|
||||||
|
|
||||||
|
Add the block above at the end of the file, then save and exit.
|
||||||
|
|
||||||
|
### Reload it
|
||||||
|
|
||||||
|
```bash [Terminal]
|
||||||
|
source ~/.bashrc
|
||||||
|
```
|
||||||
|
|
||||||
|
### Try it
|
||||||
|
|
||||||
|
```console [Terminal]
|
||||||
|
$ sudo rm -rf /tmp/test
|
||||||
|
Are you sure you want to delete files/folders with sudo? (y/n) n
|
||||||
|
Deletion cancelled.
|
||||||
|
```
|
||||||
|
|
||||||
|
Answer `y` and it runs for real. Anything that isn't `rm`, `sudo apt update`, `sudo systemctl restart docker`, goes through without a prompt.
|
||||||
|
|
||||||
|
### Done !
|
||||||
|
::
|
||||||
|
|
||||||
|
::note
|
||||||
|
This lives in `~/.bashrc`, so it only applies to your interactive shell, not to scripts, cron jobs, or another user's session. That's the point: it catches you, typing, not a program calling `sudo rm` on purpose.
|
||||||
|
::
|
||||||
|
|
||||||
|
## What it won't catch
|
||||||
|
|
||||||
|
This is a habit-breaker, not a sandbox. It only fires when `rm` is the literal first word after `sudo`, so anything that reaches `rm` a different way skips it entirely:
|
||||||
|
|
||||||
|
- `sudo -i rm -rf /` or `sudo su -c "rm -rf /"`, the first argument is `-i` or `su`, not `rm`
|
||||||
|
- `sudo bash -c "rm -rf /srv/docker"`, same reason, `rm` is buried inside the string bash runs
|
||||||
|
- `sudo find /srv/docker -delete`, deletes just as permanently, and never calls `rm` at all
|
||||||
|
- `rm` without `sudo` on files you already own
|
||||||
|
|
||||||
|
Real protection against the last category is a proper backup, [Backrest](https://github.com/garethgeorge/backrest) and the [Docker stop script](/nonsense/bash/backrest-docker-stop) covered elsewhere in this section, or otherwise. This function is worth having anyway: the accidents it does catch are the ones that actually happen, a hurried `sudo rm -rf` with a typo in the path, not a deliberate attempt to work around it.
|
||||||
Reference in New Issue
Block a user