惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Visual Studio Blog
博客园 - 司徒正美
博客园_首页
Jina AI
Jina AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
月光博客
月光博客
I
InfoQ
M
MIT News - Artificial intelligence
T
Tailwind CSS Blog
L
LangChain Blog
Last Week in AI
Last Week in AI
A
About on SuperTechFans
B
Blog
博客园 - 叶小钗
雷峰网
雷峰网
H
Help Net Security
WordPress大学
WordPress大学
大猫的无限游戏
大猫的无限游戏
博客园 - 【当耐特】
云风的 BLOG
云风的 BLOG
Microsoft Azure Blog
Microsoft Azure Blog
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻

OhYee 博客

小鹏辅助驾驶测评|OhYee 博客 小鹏非支持手机开启自动解锁|OhYee 博客 使用函数计算实现 301 重定向|OhYee 博客 针对 HTML 内容使用 Ant Design 图片弹框|OhYee 博客 博客进程泄露及僵尸进程解决|OhYee 博客 蓝易云服务器体验|OhYee 博客 SSH 调起本地 VSCode|OhYee 博客 【2022 秋招内推】阿里云后端研发工程师|OhYee 博客 使用函数计算获取 IP 地址信息|OhYee 博客 正确获取客户端 IP/HTTP Header 也可能重复|OhYee 博客 评测 Oculus Quest2 及 BigScreen|OhYee 博客 NextJS 热重载保留状态|OhYee 博客 如何优雅地贴 gist 代码|OhYee 博客 Linux 精细化文件权限|OhYee 博客 VSCode 容器开发环境|OhYee 博客 Clash 的不兼容更新排查|OhYee 博客 Zeek 导出 PCAP|OhYee 博客 记一次 ssh 配置问题|OhYee 博客 Git Commit 规范化工具|OhYee 博客 谈谈《星之卡比-探索发现》|OhYee 博客 VSCode 快捷键绑定 Shell 命令|OhYee 博客 ASN.1 语法及 X.509 证书格式解析解析|OhYee 博客 腾讯企业邮箱忽略 MX 记录发信|OhYee 博客 Chrome/Edge 标签组插件|OhYee 博客 【应届内推】阿里云后端研发工程师|OhYee 博客 损坏的 Typecho 备份处理为 JSON|OhYee 博客 VS Code VIM 插件高效使用|OhYee 博客 SSH 正反向代理|OhYee 博客 Let's Encrypt 根证书过期引发的问题|OhYee 博客 OpenWRT 忽略内核依赖|OhYee 博客
Snort 安装及使用|OhYee 博客
2020-07-08 · via OhYee 博客

Snort 安装及使用

安装

在 Arch 上,大概是由于没有及时更新,目前官方库中的 Snort 已经过时,无法拉取源码,会报404
因此需要去官网拉取最新的源码手动编译

wget https://www.snort.org/downloads/snort/daq-2.0.7.tar.gz
tar xvzf daq-2.0.7.tar.gz
cd daq-2.0.7
./configure && make && sudo make install
cd ..

wget https://www.snort.org/downloads/snort/snort-2.9.16.tar.gz
tar xvzf snort-2.9.16.tar.gz
cd snort-2.9.16
./configure --enable-sourcefire && make && sudo make install
cd ..

在这里,daq本身还需要依赖flexbisonrpc-compat,好在这两个可以直接使用包管理安装

DAQ

DAQ(Data Acquisition) 是数据采集模块,使用--daq-list可以看到已安装到 Snort 的数据采集模块

$ snort --daq-list
Available DAQ modules:
pcap(v3): readback live multi unpriv
nfq(v7): live inline multi
ipfw(v3): live inline multi unpriv
dump(v3): readback live inline multi unpriv
afpacket(v5): live inline multi unpriv

默认情况下,Snort 使用的是 pcap。

联动防火墙

Snort 本身只是一个入侵检测软件,但可以使用 inline 模式来实现丢弃警告的包。但 inline 模式对设备网卡有所要求,另一个可行的思路是使用程序监控 Snort 日志,并自动插入到防火墙(不局限于 iptables,也可以使用 PowerShell 插入到 Windows 防火墙)

比较常见的思路是使用 Guardian 来实现 Snort 和 iptables 的联动1,但不幸的是 Guardian 已经年久失修,需要修改代码或安装libperl4-corelibs-perl才能运行。

当然,更省事的办法是自己来实现类似的程序。
大概思路是监听日志文件的改动,发现改动后使用正则表达式提取出对端 IP,使用 Shell 命令将其插入至 iptables2 3 中。

下面是一个可行的 Go 程序(需要sudo运行),如果加以修改,也可用于插入至 Windows 防火墙

package main

import (
    "bytes"
    "fmt"
    "log"
    "os"
    "os/exec"
    "regexp"
    "strings"

    "github.com/fsnotify/fsnotify"
)

const filename = "/home/ohyee/projects/network_security/snort/log/alert"

var f *os.File

// var reader *bufio.Reader
var regex *regexp.Regexp
var iptables string
var buffer = make([]byte, 1024)
var offset int64 = 0

type Alert struct {
    srcip    string
    srcport  string
    dstip    string
    dstport  string
    protocol string
}

func alert() {
    for {
        buf := bytes.NewBuffer([]byte{})
        for {
            length, err := f.ReadAt(buffer, offset)
            fmt.Println(offset, err)
            if length == 0 {
                    break
            }
            offset += int64(length)
            buf.Write(buffer)
        }
        if buf.Len() == 0 {
            break
        }

        line := buf.String()
        fmt.Println(line)

        res := regex.FindAllStringSubmatch(line, -1)
        for _, item := range res {
            alerts := Alert{
                srcip:    item[1],
                srcport:  item[2],
                dstip:    item[3],
                dstport:  item[4],
                protocol: item[5],
            }

            fmt.Printf("%+v", alerts)
            ban(alerts)
        }
    }

}

func ban(a Alert) {
    args := []string{"-I", "INPUT", "-s", a.srcip, "-d", a.dstip, "-p", strings.ToLower(a.protocol), "-j", "REJECT"}
    if a.dstport != "" {
        args = append(args, "--dport", a.dstport[1:])
    }
    cmd := exec.Command(iptables, args...)

    if b, err := cmd.CombinedOutput(); err != nil {
        fmt.Printf("Error %s %+v\n", b, err)
    } else {
        fmt.Printf("Ban %s -> %s (%s)\n", a.srcip, a.dstip, a.protocol)
    }
}

func main() {
    var err error
    if f, err = os.Open(filename); err != nil {
        return
    }
    defer f.Close()

    if regex, err = regexp.Compile("([\\d.]+)([:\\d]*) -> ([\\d.]+)([:\\d]*)[\\n\\s]*([a-zA-Z]+)"); err != nil {
        panic(err)
    }

    if iptables, err = exec.LookPath("iptables"); err != nil {
        panic(err)
    }

    watcher, err := fsnotify.NewWatcher()
    if err != nil {
        log.Fatal(err)
    }
    defer watcher.Close()

    alert()

    done := make(chan bool)
    go func() {
        for {
            select {
            case event := <-watcher.Events:
                if event.Op&fsnotify.Write == fsnotify.Write {
                    fmt.Println("modified file:", event.Name)
                    alert()
                }
            case err := <-watcher.Errors:
                fmt.Println("error:", err)
            }
        }
    }()

    err = watcher.Add(filename)
    if err != nil {
        log.Fatal(err)
    }

    <-done
}

参考资料


  1. Snort联动式入侵防御系统的折腾之路(1):Snort&Guardian安装与部署 ↩︎

  2. iptables使用笔记 ↩︎

  3. iptables 使用方式整理 ↩︎