mirror of
https://github.com/unifi-utilities/unifios-utilities.git
synced 2024-08-30 18:32:21 +00:00
ipt-enable-logs (#267)
* Add some more on_boot..d examples * Add ipt-enable-logs
This commit is contained in:
parent
cb6ff86d30
commit
9967161b80
67
ipt-enable-logs/README.md
Normal file
67
ipt-enable-logs/README.md
Normal file
@ -0,0 +1,67 @@
|
||||
# Enable log tags on your UDM
|
||||
|
||||
## Features
|
||||
|
||||
If you're used to the Unifi Security Gateway, you may miss the USG log prefixes that allow you to know which rule blocked certain traffic.
|
||||
|
||||
This mod adds logging prefixes to messages from `/var/log/messages` allowing you to trace a particular log message to the respective iptable rule (which is generated from the firewall rules you configure on the Network application, among other things)
|
||||
|
||||
## Requirements
|
||||
|
||||
1. You have successfully setup the on boot script described [here](https://github.com/boostchicken/udm-utilities/tree/master/on-boot-script)
|
||||
|
||||
## General idea
|
||||
|
||||
This mod builds a small Go program that modifies the existing iptables to add `--log-prefix` to entries that are defined as loggable through the `-j LOG` directive. The Go program is built in a Docker container local to the UDM.
|
||||
|
||||
Here's an example snippet of an iptable modified by this program:
|
||||
|
||||
```
|
||||
-A UBIOS_PREROUTING_USER_HOOK -p tcp -m set --match-set UBIOS_ADDRv4_eth8 dst -m tcp --dport 15060 -j LOG --log-prefix "[DNAT-PRER_U_HK-4294967310] "
|
||||
-A UBIOS_PREROUTING_USER_HOOK -p tcp -m set --match-set UBIOS_ADDRv4_eth8 dst -m tcp --dport 15060 -m comment --comment 00000000004294967310 -j DNAT --to-destination 192.168.36.10:15060
|
||||
```
|
||||
|
||||
## Steps
|
||||
|
||||
1. Copy [on_boot.d/30-ipt-enable-logs-launch.sh](./on_boot.d/30-ipt-enable-logs-launch.sh) to /mnt/data/on_boot.d
|
||||
1. Copy the [scripts/ipt-enable-logs](./scripts/ipt-enable-logs) folder to /mnt/data/scripts
|
||||
1. Copy [scripts/ipt-enable-logs.sh](./scripts/ipt-enable-logs.sh) to /mnt/data/scripts
|
||||
1. Execute /mnt/data/on_boot.d/30-ipt-enable-logs-launch.sh
|
||||
1. Copy [scripts/refresh-iptables.sh](./scripts/refresh-iptables.sh) to /mnt/data/scripts
|
||||
|
||||
## Refreshing iptables
|
||||
|
||||
Whenever you update the firewall rules on the Network application, the iptables will be reprovisioned and will need to be reprocessed
|
||||
by calling /mnt/data/scripts/refresh-iptables.sh.
|
||||
|
||||
## Looking at logs
|
||||
|
||||
Logs can be followed easily from another machine through SSH by using the following bash functions:
|
||||
|
||||
```shell
|
||||
function logunifijson() {
|
||||
ssh unifi "tail -f /var/log/messages" | \
|
||||
rg "kernel:" | \
|
||||
sed "s/]IN/] IN/" | \
|
||||
jq --unbuffered -R '. | rtrimstr(" ") | split(": ") | {date: (.[0] | split(" ") | .[0:3] | join(" "))} + (.[1] | capture("\\[.+\\] \\[(?<rule>.*)\\].*")) + ((.[1] | capture("\\[.+\\] (?<rest>.*)") | .rest | split(" ") | map(select(startswith("[") == false) | split("=") | {(.[0]): .[1]})) | (reduce .[] as $item ({}; . + $item)))'
|
||||
}
|
||||
|
||||
function logunifi() {
|
||||
logunifijson | jq --unbuffered -r '"\(.date) - \(.rule)\tIN=\(.IN) \t\(.PROTO)\tSRC=\(.SRC)@\(.SPT)\tDST=\(.DST)@\(.DPT)\tLEN=\(.LEN)\t"'
|
||||
}
|
||||
```
|
||||
|
||||
Here's what the output of `logunifi` looks like:
|
||||
|
||||
```
|
||||
Nov 14 10:58:31 - A-LAN_LOCAL_U-1097364144127 IN=br0 TCP SRC=192.168.16.10@55804 DST=192.168.16.1@443 LEN=52
|
||||
Nov 14 10:58:31 - A-LAN_LOCAL_U-1097364144127 IN=br0 TCP SRC=192.168.16.10@55804 DST=192.168.16.1@443 LEN=52
|
||||
Nov 14 10:58:31 - A-LAN_LOCAL_U-1097364144127 IN=br0 TCP SRC=192.168.16.10@55804 DST=192.168.16.1@443 LEN=52
|
||||
Nov 14 10:58:31 - A-LAN_LOCAL_U-1097364144127 IN=br0 TCP SRC=192.168.16.10@55804 DST=192.168.16.1@443 LEN=52
|
||||
Nov 14 10:58:31 - A-LAN_LOCAL_U-1097364144127 IN=br0 TCP SRC=192.168.16.10@55804 DST=192.168.16.1@443 LEN=52
|
||||
Nov 14 10:58:31 - A-LAN_LOCAL_U-1097364144127 IN=br0 TCP SRC=192.168.16.10@55804 DST=192.168.16.1@443 LEN=52
|
||||
```
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Thanks a lot to [@opustecnica](https://github.com/opustecnica) for the [initial implementation](https://github.com/opustecnica/public/wiki/UDM-&-UDM-PRO-NOTES) and idea (based on a bash script)!
|
9
ipt-enable-logs/on_boot.d/30-ipt-enable-logs-launch.sh
Executable file
9
ipt-enable-logs/on_boot.d/30-ipt-enable-logs-launch.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if ! iptables-save | grep -e '\-A UBIOS_.* \--log-prefix "\[' > /dev/null; then
|
||||
/mnt/data/scripts/ipt-enable-logs.sh | iptables-restore -c
|
||||
else
|
||||
echo "iptables already contains USER log prefixes, ignoring."
|
||||
fi
|
7
ipt-enable-logs/scripts/ipt-enable-logs.sh
Executable file
7
ipt-enable-logs/scripts/ipt-enable-logs.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
docker run -it --rm -v /mnt/data/scripts/ipt-enable-logs:/src -w /src --network=none golang:1.17.3 go build -v -o /src/ipt-enable-logs /src >&2
|
||||
|
||||
/mnt/data/scripts/ipt-enable-logs/ipt-enable-logs
|
3
ipt-enable-logs/scripts/ipt-enable-logs/go.mod
Normal file
3
ipt-enable-logs/scripts/ipt-enable-logs/go.mod
Normal file
@ -0,0 +1,3 @@
|
||||
module pedropombeiro.com/ipt-enable-logs
|
||||
|
||||
go 1.17
|
62
ipt-enable-logs/scripts/ipt-enable-logs/main.go
Normal file
62
ipt-enable-logs/scripts/ipt-enable-logs/main.go
Normal file
@ -0,0 +1,62 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cmd := exec.Command("iptables-save")
|
||||
outputBytes, err := cmd.Output()
|
||||
if err != nil {
|
||||
_ = fmt.Errorf("Failed to run iptables-save: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
str := string(outputBytes)
|
||||
lines := strings.Split(str, "\n")
|
||||
re := regexp.MustCompile(`-A UBIOS_([A-Z_]+) .* --comment (\d+) -j ([A-Z]+)`)
|
||||
|
||||
for i, line := range lines {
|
||||
if i != 0 {
|
||||
fmt.Println()
|
||||
}
|
||||
if !strings.HasSuffix(line, "-j LOG") {
|
||||
fmt.Print(line)
|
||||
continue
|
||||
}
|
||||
|
||||
matches := re.FindSubmatch([]byte(lines[i+1]))
|
||||
commentNr, err := strconv.Atoi(string(matches[2]))
|
||||
if err != nil {
|
||||
commentNr = 0
|
||||
}
|
||||
actionName := getActionName(string(matches[3]))
|
||||
ruleName := getRuleName(string(matches[1]), commentNr)
|
||||
fmt.Printf(`%s --log-prefix "[%s-%s] "`, line, actionName, ruleName)
|
||||
}
|
||||
}
|
||||
|
||||
func getActionName(action string) string {
|
||||
action = strings.Replace(action, "RETURN", "A", 1)
|
||||
action = strings.Replace(action, "REJECT", "R", 1)
|
||||
action = strings.Replace(action, "DROP", "D", 1)
|
||||
action = strings.Replace(action, "MASQUERADE", "M", 1)
|
||||
|
||||
return action
|
||||
}
|
||||
|
||||
func getRuleName(rule string, commentNr int) string {
|
||||
rule = strings.Replace(rule, "PREROUTING", "PRER", 1)
|
||||
rule = strings.Replace(rule, "POSTROUTING", "POSTR", 1)
|
||||
rule = strings.Replace(rule, "HOOK", "HK", 1)
|
||||
rule = strings.Replace(rule, "USER", "U", 1)
|
||||
if commentNr != 0 {
|
||||
rule = fmt.Sprintf("%s-%d", rule, commentNr)
|
||||
}
|
||||
return rule
|
||||
}
|
13
ipt-enable-logs/scripts/refresh-iptables.sh
Executable file
13
ipt-enable-logs/scripts/refresh-iptables.sh
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if [ -f /mnt/data/on_boot.d/10-dns.sh ]; then
|
||||
if ! iptables-save | grep -e '\-A PREROUTING.* \--log-prefix "\[' > /dev/null; then
|
||||
/mnt/data/on_boot.d/10-dns.sh
|
||||
else
|
||||
echo "iptables already contains DNAT log prefixes, ignoring."
|
||||
fi
|
||||
fi
|
||||
|
||||
/mnt/data/on_boot.d/30-ipt-enable-logs-launch.sh
|
Loading…
Reference in New Issue
Block a user