Robert 7 months ago
commit 4631524455
  1. 8
      AppArmor.policy
  2. 22
      LICENSE
  3. 35
      README.md
  4. BIN
      SYN-Scan-Firewall
  5. 486
      SYN-Scan-Firewall.go
  6. 66
      SYN-Scan-Firewall.service
  7. 41
      banner.service
  8. BIN
      banner_service
  9. 34
      banner_service.go
  10. 28
      config-example.yaml
  11. 8
      go.mod
  12. 17
      go.sum
  13. 72
      install.sh
  14. 9
      reBuild.sh
  15. 3
      seccomp.conf

@ -0,0 +1,8 @@
# Example AppArmor profile (/etc/apparmor.d/usr.local.bin.SYN-Scan-Firewall)
/usr/local/bin/SYN-Scan-Firewall {
include <abstractions/base>
capability net_admin,
capability net_raw,
/etc/syn-firewall/config.yaml r,
/var/lib/syn-firewall/** rw,
}

@ -0,0 +1,22 @@
The MIT License
Copyright (c) 2025 Robert Strutts
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,35 @@
# SYN-Scan-Firewall
## To block the IP from port scans...
```
./install.sh
```
## /etc/SYN-Scan-Firewall/config.yaml
```
blockDuration: 10m
maxScanAttempts: 5
device: "enp2s0" # Ethernet Device name
logging:
filePath: "/var/log/SYN-Scan-Firewall.log"
maxSizeMB: 10 # Max log size in megabytes
backups: 5 # Number of backup logs to keep
compressBackups: true # Whether to gzip old logs
timestampFormat: "2006-01-02T15:04:05" # Go time format
ignoredPorts:
- 80 # HTTP
- 443 # HTTPS
- 9980 # php -S
- 631 # CUPS (printing)
- 9100 # print server ports
- 53 # DNS
- 123 # NTP
- 68 # DHCP client
# - 22 # SSH
whitelistedIPs:
- "192.168.10.2" # own IP
- "192.168.1.100" # Example local admin
- "10.0.0.50" # Example monitoring server
- "127.0.0.1" # Localhost
```

Binary file not shown.

@ -0,0 +1,486 @@
package main
import (
"compress/gzip"
"fmt"
"io"
"log"
"os"
"os/exec"
"os/signal"
"path/filepath"
"sort"
"strings"
"sync"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"gopkg.in/yaml.v3"
)
const (
defaultConfigFile = "/etc/SYN-Scan-Firewall/config.yaml"
)
// Config structures
type LoggingConfig struct {
FilePath string `yaml:"filePath"`
MaxSizeMB int `yaml:"maxSizeMB"`
Backups int `yaml:"backups"`
CompressBackups bool `yaml:"compressBackups"`
TimestampFormat string `yaml:"timestampFormat"`
}
type Config struct {
BlockDuration string `yaml:"blockDuration"`
MaxScanAttempts int `yaml:"maxScanAttempts"`
Device string `yaml:"device"`
Logging LoggingConfig `yaml:"logging"`
IgnoredPorts []int `yaml:"ignoredPorts"`
WhitelistedIPs []string `yaml:"whitelistedIPs"`
}
type AppConfig struct {
BlockDuration time.Duration
MaxScanAttempts int
Device string
Logging LoggingConfig
IgnoredPorts map[int]bool
WhitelistedIPs map[string]bool
}
type UnblockTask struct {
IP string
UnblockAt time.Time
}
type Sniffer struct {
unblockTasks []UnblockTask
tracker *ScanTracker
handle *pcap.Handle
config *AppConfig
logger *log.Logger
}
// ScanTracker implementation
type ScanTracker struct {
sync.Mutex
entries map[string]*ScanEntry
}
type ScanEntry struct {
Count int
Timestamp time.Time
}
// NewScanTracker creates and initializes a new ScanTracker
func NewScanTracker() *ScanTracker {
return &ScanTracker{
entries: make(map[string]*ScanEntry),
}
}
// RotatingLogger implementation
type RotatingLogger struct {
config LoggingConfig
currentFile *os.File
mu sync.Mutex
}
func NewRotatingLogger(config LoggingConfig) (*RotatingLogger, error) {
rl := &RotatingLogger{config: config}
if err := rl.openFile(); err != nil {
return nil, err
}
return rl, nil
}
func (rl *RotatingLogger) openFile() error {
if err := os.MkdirAll(filepath.Dir(rl.config.FilePath), 0755); err != nil {
return fmt.Errorf("failed to create log directory: %v", err)
}
file, err := os.OpenFile(rl.config.FilePath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0640)
if err != nil {
return fmt.Errorf("failed to open log file: %v", err)
}
rl.currentFile = file
return nil
}
func (rl *RotatingLogger) rotate() error {
rl.mu.Lock()
defer rl.mu.Unlock()
if err := rl.currentFile.Close(); err != nil {
return err
}
for i := rl.config.Backups - 1; i >= 0; i-- {
src := rl.getBackupName(i)
if _, err := os.Stat(src); err == nil {
dst := rl.getBackupName(i + 1)
if i+1 >= rl.config.Backups {
os.Remove(dst)
} else {
if rl.config.CompressBackups && !strings.HasSuffix(src, ".gz") {
if err := rl.compressFile(src); err != nil {
return err
}
src += ".gz"
dst += ".gz"
}
os.Rename(src, dst)
}
}
}
if err := os.Rename(rl.config.FilePath, rl.getBackupName(0)); err != nil {
return err
}
return rl.openFile()
}
func (rl *RotatingLogger) compressFile(src string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
out, err := os.Create(src + ".gz")
if err != nil {
return err
}
defer out.Close()
gz := gzip.NewWriter(out)
defer gz.Close()
if _, err = io.Copy(gz, in); err != nil {
return err
}
return os.Remove(src)
}
func (rl *RotatingLogger) getBackupName(index int) string {
if index == 0 {
return rl.config.FilePath + ".1"
}
return fmt.Sprintf("%s.%d", rl.config.FilePath, index+1)
}
func (rl *RotatingLogger) needsRotation() (bool, error) {
info, err := rl.currentFile.Stat()
if err != nil {
return false, err
}
return info.Size() >= int64(rl.config.MaxSizeMB*1024*1024), nil
}
func (rl *RotatingLogger) Write(p []byte) (n int, err error) {
if rotate, err := rl.needsRotation(); rotate && err == nil {
if err := rl.rotate(); err != nil {
return 0, err
}
}
rl.mu.Lock()
defer rl.mu.Unlock()
return rl.currentFile.Write(p)
}
func (rl *RotatingLogger) Close() error {
rl.mu.Lock()
defer rl.mu.Unlock()
return rl.currentFile.Close()
}
// Helper functions
func loadConfig(path string) (*AppConfig, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to read config file: %v", err)
}
var cfg Config
if err := yaml.Unmarshal(data, &cfg); err != nil {
return nil, fmt.Errorf("failed to parse config: %v", err)
}
// Set defaults
if cfg.Logging.FilePath == "" {
cfg.Logging.FilePath = "/var/log/SYN-Scan-Firewall.log"
}
if cfg.Logging.MaxSizeMB == 0 {
cfg.Logging.MaxSizeMB = 10
}
if cfg.Logging.Backups == 0 {
cfg.Logging.Backups = 5
}
if cfg.Logging.TimestampFormat == "" {
cfg.Logging.TimestampFormat = "2006-01-02 15:04:05"
}
blockDuration, err := time.ParseDuration(cfg.BlockDuration)
if err != nil {
return nil, fmt.Errorf("invalid blockDuration format: %v", err)
}
ignoredPorts := make(map[int]bool)
for _, port := range cfg.IgnoredPorts {
ignoredPorts[port] = true
}
whitelistedIPs := make(map[string]bool)
for _, ip := range cfg.WhitelistedIPs {
whitelistedIPs[ip] = true
}
return &AppConfig{
BlockDuration: blockDuration,
MaxScanAttempts: cfg.MaxScanAttempts,
Device: cfg.Device,
Logging: cfg.Logging,
IgnoredPorts: ignoredPorts,
WhitelistedIPs: whitelistedIPs,
}, nil
}
func (st *ScanTracker) Add(ip string, config *AppConfig) {
st.Lock()
defer st.Unlock()
entry, exists := st.entries[ip]
if !exists {
entry = &ScanEntry{}
st.entries[ip] = entry
}
now := time.Now()
if entry.Timestamp.Add(config.BlockDuration).Before(now) {
entry.Count = 0
}
entry.Count++
entry.Timestamp = now
}
func (st *ScanTracker) GetCount(ip string) int {
st.Lock()
defer st.Unlock()
if entry, exists := st.entries[ip]; exists {
return entry.Count
}
return 0
}
func isIPBlocked(ip string) bool {
cmd := exec.Command("sudo", "iptables", "-L", "-n")
output, err := cmd.Output()
if err != nil {
return false
}
return strings.Contains(string(output), ip)
}
func blockIP(ip string, logger *log.Logger) {
if isIPBlocked(ip) {
logger.Printf("IP %s is already blocked", ip)
return
}
logger.Printf("Redirecting IP: %s to port 9999 BANNER", ip)
cmd := exec.Command("sudo", "iptables", "-t", "nat", "-A", "PREROUTING", "-s", ip, "-p", "tcp", "--dport", "1:65535", "-j", "REDIRECT", "--to-port", "9999")
if err := cmd.Run(); err != nil {
logger.Printf("Error redirecting IP %s to banner service: %v", ip, err)
}
logger.Printf("Blocking IP: %s", ip)
cmd = exec.Command("sudo", "iptables", "-A", "INPUT", "-s", ip, "-j", "DROP")
if err := cmd.Run(); err != nil {
logger.Printf("Error blocking IP %s: %v", ip, err)
}
}
func unblockIP(ip string, logger *log.Logger) {
logger.Printf("Unblocking IP: %s", ip)
cmd := exec.Command("sudo", "iptables", "-D", "INPUT", "-s", ip, "-j", "DROP")
if err := cmd.Run(); err != nil {
logger.Printf("Error unblocking IP %s: %v", ip, err)
}
}
// Sniffer methods
func (s *Sniffer) isWhitelisted(ip string) bool {
return s.config.WhitelistedIPs[ip]
}
func (s *Sniffer) handlePacket(packet gopacket.Packet) {
tcpLayer := packet.Layer(layers.LayerTypeTCP)
if tcpLayer == nil {
return
}
tcp, _ := tcpLayer.(*layers.TCP)
if tcp.SYN && !tcp.ACK {
ipLayer := packet.Layer(layers.LayerTypeIPv4)
if ipLayer == nil {
return
}
ip, _ := ipLayer.(*layers.IPv4)
srcIP := ip.SrcIP.String()
dstPort := int(tcp.DstPort)
if s.isWhitelisted(srcIP) {
return
}
if s.config.IgnoredPorts[dstPort] {
return
}
s.logger.Printf("Scan detected on port %d from %s", dstPort, srcIP)
s.tracker.Add(srcIP, s.config)
count := s.tracker.GetCount(srcIP)
if count > s.config.MaxScanAttempts {
s.logger.Printf("IP %s exceeded scan limit (%d attempts), blocking for %.0f minutes",
srcIP, s.config.MaxScanAttempts, s.config.BlockDuration.Minutes())
blockIP(srcIP, s.logger)
unblockTime := time.Now().Add(s.config.BlockDuration)
s.logger.Printf("IP %s will be unblocked at %s", srcIP, unblockTime.Format(s.config.Logging.TimestampFormat))
s.unblockTasks = append(s.unblockTasks, UnblockTask{
IP: srcIP,
UnblockAt: unblockTime,
})
}
}
}
func (s *Sniffer) unblockExpiredIPs() {
now := time.Now()
var remainingTasks []UnblockTask
for _, task := range s.unblockTasks {
if now.After(task.UnblockAt) || now.Equal(task.UnblockAt) {
unblockIP(task.IP, s.logger)
} else {
remainingTasks = append(remainingTasks, task)
}
}
s.unblockTasks = remainingTasks
}
func (s *Sniffer) StartSniffing() error {
s.logger.Printf("Starting port scan detection")
s.logger.Printf("Configuration:")
s.logger.Printf(" Device: %s", s.config.Device)
s.logger.Printf(" Ignored ports: %v", s.getSortedPorts())
s.logger.Printf(" Whitelisted IPs: %v", s.getSortedIPs())
s.logger.Printf(" Block duration: %.0f minutes", s.config.BlockDuration.Minutes())
s.logger.Printf(" Max scan attempts before blocking: %d", s.config.MaxScanAttempts)
handle, err := pcap.OpenLive(s.config.Device, 1600, false, pcap.BlockForever)
if err != nil {
return fmt.Errorf("error opening device %s: %v", s.config.Device, err)
}
s.handle = handle
err = handle.SetBPFFilter("tcp")
if err != nil {
return fmt.Errorf("error setting filter: %v", err)
}
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
s.handlePacket(packet)
}
return nil
}
func (s *Sniffer) getSortedPorts() []int {
ports := make([]int, 0, len(s.config.IgnoredPorts))
for port := range s.config.IgnoredPorts {
ports = append(ports, port)
}
sort.Ints(ports)
return ports
}
func (s *Sniffer) getSortedIPs() []string {
ips := make([]string, 0, len(s.config.WhitelistedIPs))
for ip := range s.config.WhitelistedIPs {
ips = append(ips, ip)
}
sort.Strings(ips)
return ips
}
// Main program
func main() {
if os.Geteuid() != 0 {
log.Fatal("This program must be run as root (sudo)")
}
config, err := loadConfig(defaultConfigFile)
if err != nil {
log.Fatalf("Configuration error: %v", err)
}
rl, err := NewRotatingLogger(config.Logging)
if err != nil {
log.Fatalf("Failed to initialize logger: %v", err)
}
defer rl.Close()
logger := log.New(rl, "", 0)
logger.SetPrefix(fmt.Sprintf("[%s] ", time.Now().Format(config.Logging.TimestampFormat)))
tracker := NewScanTracker()
sniffer := &Sniffer{
tracker: tracker,
config: config,
logger: logger,
}
sniffer.tracker.entries = make(map[string]*ScanEntry)
go func() {
if err := sniffer.StartSniffing(); err != nil {
logger.Fatalf("Sniffer error: %v", err)
}
}()
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt)
logger.Println("Running... Press Ctrl+C to stop")
for {
select {
case <-ticker.C:
sniffer.unblockExpiredIPs()
case <-sigChan:
logger.Println("Stopping...")
if sniffer.handle != nil {
sniffer.handle.Close()
}
return
}
}
}

@ -0,0 +1,66 @@
[Unit]
Description=SYN Scan Detection Firewall
Documentation=https://
After=network.target network-online.target
Requires=network-online.target
ConditionPathExists=/usr/local/bin/SYN-Scan-Firewall
AssertPathExists=/etc/SYN-Scan-firewall/config.yaml
AssertFileIsExecutable=/usr/local/bin/SYN-Scan-Firewall
[Service]
Type=notify
User=synfirewall
Group=synfirewall
WorkingDirectory=/var/lib/syn-firewall
# Hardened execution
ExecStart=/usr/local/bin/SYN-Scan-Firewall
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
TimeoutStopSec=30s
KillSignal=SIGTERM
KillMode=process
# Capabilities (minimal)
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW
# Security confinement
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=read-only
PrivateTmp=true
PrivateDevices=true
PrivateUsers=true
ProtectHostname=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
LockPersonality=true
RemoveIPC=true
# Memory protection
MemoryDenyWriteExecute=true
SystemCallFilter=@system-service @network-io @signal
SystemCallArchitectures=native
UMask=0077
# Network restrictions
IPAddressDeny=any
IPAddressAllow=localhost
IPAddressAllow=127.0.0.1
IPAddressAllow=::1
# Resource limits
LimitNOFILE=4096
LimitNPROC=64
LimitMEMLOCK=64K
LimitSTACK=8M
[Install]
WantedBy=multi-user.target

@ -0,0 +1,41 @@
[Unit]
Description=Portscan Firewall Banner Service
After=network.target
ConditionPathExists=/usr/local/bin/banner_service
ConditionCapability=CAP_NET_BIND_SERVICE
[Service]
Type=simple
User=bannersvc
Group=bannersvc
WorkingDirectory=/var/lib/banner-service
ExecStart=/usr/local/bin/banner_service
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictAddressFamilies=AF_INET AF_INET6
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
MemoryDenyWriteExecute=true
LockPersonality=true
SystemCallFilter=@system-service
SystemCallArchitectures=native
IPAddressDeny=any
IPAddressAllow=localhost
IPAddressAllow=127.0.0.1
IPAddressAllow=::1
# Connection rate limiting
LimitNOFILE=1024
LimitNPROC=8
[Install]
WantedBy=multi-user.target

Binary file not shown.

@ -0,0 +1,34 @@
package main
import (
"fmt"
"net"
"os"
)
const (
banner = "\n*** UNAUTHORIZED ACCESS PROHIBITED ***\n*** YOUR CONNECTION ATTEMPT HAS BEEN LOGGED ***\n\n"
port = "9999"
)
func handleConnection(conn net.Conn) {
conn.Write([]byte(banner))
conn.Close()
}
func main() {
ln, err := net.Listen("tcp", ":"+port)
if err != nil {
fmt.Println("Error starting banner service:", err)
os.Exit(1)
}
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
continue
}
go handleConnection(conn)
}
}

@ -0,0 +1,28 @@
# config.yaml
blockDuration: 10m
maxScanAttempts: 5
device: "enp2s0"
logging:
filePath: "/var/log/SYN-Scan-Firewall.log"
maxSizeMB: 10 # Max log size in megabytes
backups: 5 # Number of backup logs to keep
compressBackups: true # Whether to gzip old logs
timestampFormat: "2006-01-02T15:04:05" # Go time format
ignoredPorts:
- 80 # HTTP
- 443 # HTTPS
- 9980 # php -S
- 631 # CUPS (printing)
- 9100 # print server ports
- 53 # DNS
- 123 # NTP
- 68 # DHCP client
# - 22 # SSH
whitelistedIPs:
- "192.168.10.2" # own IP
- "192.168.1.100" # Example local admin
# - "10.0.0.50" # Example monitoring server
- "127.0.0.1" # Localhost

@ -0,0 +1,8 @@
module SYN-Scan-Firewall
go 1.24.3
require (
github.com/google/gopacket v1.1.19 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

@ -0,0 +1,17 @@
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

@ -0,0 +1,72 @@
#!/bin/bash
/usr/bin/echo "Installing libpcap-dev"
/usr/bin/sudo /usr/bin/touch /var/log/SYN-Scan-Firewall.log
/usr/bin/sudo /usr/bin/chmod 640 /var/log/SYN-Scan-Firewall.log
/usr/bin/sudo /usr/bin/apt update
/usr/bin/sudo /usr/bin/apt install -y libpcap-dev
/usr/bin/echo "Create the service account for Banner"
/usr/bin/sudo /usr/sbin/groupadd bannersvc
/usr/bin/sudo /usr/sbin/useradd -r -g bannersvc -s /usr/sbin/nologin -d /var/lib/banner-service bannersvc
/usr/bin/sudo /usr/bin/mkdir -p /var/lib/banner-service
/usr/bin/sudo /usr/bin/chown bannersvc:bannersvc /var/lib/banner-service
/usr/bin/sudo /usr/bin/chmod 750 /var/lib/banner-service
# Force rebuild of packages, Remove file system paths from executable, Reduces binary size and removes debug info, Enables ASLR (Address Space Layout Randomization), and Use Go's native DNS resolver.
/usr/bin/echo "Building Banner Service..."
/usr/local/bin/go build \
-a \
-trimpath \
-ldflags="-s -w -extldflags=-z,now,-z,relro" \
-buildmode=pie \
-tags=netgo \
-o banner_service \
banner_service.go
/usr/bin/sudo /usr/bin/cp banner_service /usr/local/bin/
/usr/bin/sudo /usr/bin/chown root:bannersvc /usr/local/bin/banner_service
/usr/bin/sudo /usr/bin/chmod 750 /usr/local/bin/banner_service
/usr/bin/echo "Set capabilities (for binding to port 9999 without root)"
/usr/bin/sudo /usr/sbin/setcap 'cap_net_bind_service=+ep' /usr/local/bin/banner_service
/usr/bin/echo "Copy over Service Files"
/usr/bin/sudo /usr/bin/cp banner.service /etc/systemd/system/banner.service
/usr/bin/sudo /usr/bin/chmod 644 /etc/systemd/system/banner.service
/usr/bin/sudo /usr/bin/mkdir -p /etc/systemd/system/banner.service.d
/usr/bin/sudo /usr/bin/cp seccomp.conf /etc/systemd/system/banner.service.d/seccomp.conf
/usr/bin/sudo /usr/bin/chmod 644 /etc/systemd/system/banner.service
/usr/bin/echo "Enable the service for Banner"
/usr/bin/sudo /usr/bin/systemctl daemon-reload
/usr/bin/sudo /usr/bin/systemctl enable --now banner.service
/usr/bin/echo "Create the service account for synfirewall"
sudo groupadd synfirewall
sudo useradd -r -g synfirewall -s /usr/sbin/nologin \
-d /var/lib/syn-firewall -c "SYN Scan Firewall" synfirewall
/usr/bin/echo "Making config.yaml"
/usr/bin/sudo /usr/bin/mkdir -p /etc/SYN-Scan-Firewall
/usr/bin/sudo /usr/bin/chown synfirewall:synfirewall /etc/SYN-Scan-Firewall
/usr/bin/sudo /usr/bin/chmod 750 /etc/SYN-Scan-Firewall
/usr/bin/sudo /usr/bin/cp config-example.yaml /etc/SYN-Scan-Firewall/config.yaml
/usr/bin/chmod 640 /etc/SYN-Scan-Firewall/config.yaml
/usr/bin/sudo /usr/bin/nano /etc/SYN-Scan-Firewall/config.yaml
/usr/bin/echo "Making lib dir..."
sudo mkdir -p /var/lib/syn-firewall
sudo chown synfirewall:synfirewall /var/lib/syn-firewall
sudo chmod 750 /var/lib/syn-firewall
./reBuild.sh
/usr/bin/echo "Copy over Service Files for SYN-Scan-Firewall"
/usr/bin/sudo /usr/bin/cp SYN-Scan-Firewall.service /etc/systemd/system/
/usr/bin/sudo /usr/bin/chmod 644 /etc/systemd/system/SYN-Scan-Firewall.service
/usr/bin/echo "Adding AppArmor policy file..."
/usr/bin/sudo /usr/bin/cp AppArmor.policy /etc/apparmor.d/usr.local.bin.SYN-Scan-Firewall
#/usr/bin/echo "Enable the service for SYN-Scan-Firewall"
#sudo systemctl daemon-reload
#sudo systemctl enable --now SYN-Scan-Firewall.service

@ -0,0 +1,9 @@
#!/bin/bash
/usr/bin/echo "Building SYN-Scan-Firewall..."
go build -buildmode=pie -ldflags="-s -w -extldflags=-z,now,-z,relro" -tags=netgo -o SYN-Scan-Firewall SYN-Scan-Firewall.go
/usr/bin/echo "Setting up local bin..."
/usr/bin/sudo /usr/bin/cp SYN-Scan-Firewall /usr/local/bin/
/usr/bin/sudo /usr/bin/chown root:synfirewall /usr/local/bin/SYN-Scan-Firewall
/usr/bin/sudo /usr/bin/chmod 750 /usr/local/bin/SYN-Scan-Firewall
/usr/bin/sudo /usr/sbin/setcap 'cap_net_admin,cap_net_raw+ep' /usr/local/bin/SYN-Scan-Firewall

@ -0,0 +1,3 @@
[Service]
SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @swap
SystemCallErrorNumber=EPERM
Loading…
Cancel
Save