Posts Tagged ‘honeypot’

How to Build a Linux Port Scan Honeypot with iptables and test with nmap

Wednesday, October 8th, 2025

buiild-own-honeypot-with-iptables-and-test-with-nmap-linux-howto

Let’s build a simple, practical Linux port‑scan honeypot that uses iptables to capture/redirect incoming connection attempts and simple listeners that log interaction, and use nmap to test it. I’ll give runnable commands, a small Python honeypot listener, iptables rules (with rate‑limited logging), how to test with nmap, and notes on analysis, hardening, and safety.

Important safety notes (read first)

  • Only deploy this on machines/networks you own or are explicitly authorized to test. Scanning other people’s systems or letting an exposed honeypot be used to attack others is illegal and unethical.
  • Run the honeypot inside an isolated VM or protected network segment (use separate host or VLAN), and don't forward traffic from other networks unless you understand the risks.
  • Keep logs rotated and watch disk usage — honeypots can attract high traffic.

Overview

  1. Prepare an isolated Linux VM.
  2. Add iptables rules to log and optionally redirect connection attempts to local listeners.
  3. Run simple service emulators (Python) to accept connections and log data.
  4. Use nmap to test and validate behavior.
  5. Collect, parse, and analyze logs; optionally integrate with syslog/ELK.

Setup assumptions

  • Ubuntu/Debian or similar Linux.
  • Root (sudo) access.
  • iptables, python3, nmap, and socat/netcat available (I’ll show alternatives).

1) Create a safe environment

  • Use a VM (VirtualBox/QEMU/KVM) or container with no sensitive data.
  • Give it a fixed private IP on an isolated network.
  • Optionally place the VM behind another firewall (so you can control exposure).

2) Simple iptables logging rules (filter table)

We want to log connection attempts but avoid log flooding by using limit. Put these commands in a root shell:

# create a honeypot chain

# iptables -N HONEY

# rate-limited LOG then return so traffic continues to normal behavior

# iptables -A HONEY -m limit –limit 5/min –limit-burst 10 -j LOG \
–log-prefix "HPOT_CONN: " –log-level 4

# record raw packets to kernel log (optional NFLOG/ulogd is better for high volume)

# allow the packet to continue (or drop if you want it to appear closed)

# iptables -A HONEY -j ACCEPT

 

# Apply HONEY chain to incoming TCP attempts to all ports (or a subset)

# iptables -A INPUT -p tcp -j HONEY

Notes:

  • This logs packets hitting INPUT. If your VM is behind NAT or you want to catch forwarded packets, apply to FORWARD too.
  • Using -j LOG writes to kernel log, often /var/log/kern.log or via rsyslog to /var/log/messages.
  • Use NFLOG (-j NFLOG) with ulogd if you want structured logging and higher throughput.

If you prefer to log only SYNs (new connection attempts) to reduce noise:

# iptables -A HONEY -p tcp –syn -m limit –limit 5/min –limit-burst 10 \
-j LOG –log-prefix "HPOT_SYN: " –log-level 4

If you want to redirect certain destination ports into local port listeners (so local fake services can accept connections), use the nat table PREROUTING:

# Example redirect incoming port 80 to local port 8080

# iptables -t nat -A PREROUTING -p tcp –dport 80 -j REDIRECT –to-ports 8080

# For ports other than 80/443, add other rules

# iptables -t nat -A PREROUTING -p tcp –dport 22 -j REDIRECT –to-ports 2222

Notes:

  • -t nat -A PREROUTING catches traffic before routing. Use OUTPUT if traffic originates on host itself.
  • REDIRECT only works for local listeners.

3) Simple Python multi‑port honeypot listener

This script will bind multiple ports and log incoming connections and first bytes (banner or payload). Save as simple_honeypot.py:

#!/usr/bin/env python3

# simple_honeypot.py

import socket, threading, logging, time

 

LISTEN_PORTS = [22, 80, 443, 8080, 2222]   # customize

BANNER = b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK"

 

logging.basicConfig(

    filename="/var/log/honeypot.log",

    level=logging.INFO,

    format="%(asctime)s %(message)s"

)

 

def handle_client(conn, addr, port):

    try:

        conn.settimeout(5.0)

        data = conn.recv(4096)

        logged = data[:100].decode('utf-8', errors='replace')

        logging.info("CONNECT %s:%s -> port=%d first=%s", addr[0], addr[1], port, logged)

        # Send a small believable banner depending on port

        if port in (80, 8080):

            conn.sendall(BANNER)

        elif port in (22, 2222):

            conn.sendall(b"SSH-2.0-OpenSSH_7.4p1\r\n")

        else:

            conn.sendall(b"220 smtp.example.com ESMTP\r\n")

    except Exception as e:

        logging.info("ERROR %s", e)

    finally:

        try:

            conn.close()

        except:

            pass

 

def start_listener(port):

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    s.bind(('0.0.0.0', port))

    s.listen(50)

    logging.info("Listening on %d", port)

    while True:

        conn, addr = s.accept()

        t = threading.Thread(target=handle_client, args=(conn, addr, port), daemon=True)

        t.start()

 

if __name__ == "__main__":

    for p in LISTEN_PORTS:

        t = threading.Thread(target=start_listener, args=(p,), daemon=True)

        t.start()

    # keep alive

    while True:

        time.sleep(3600)

Run it as root (or with capability binding) so it can listen on low ports:
 

# python3 simple_honeypot.py


# check logs

# tail -F /var/log/honeypot.log

Alternatives:

  • Use socat to spawn a logger for individual ports.
  • Use cowrie, glastopf, honeyd, sshpot etc. if you want full featured honeypots.

4) Using nmap to test the honeypot

Only scan your honeypot IP. Example commands:

Basic TCP port scan:

# nmap -sS -p- -T4 -oN scan_ports.txt <HONEYPOT_IP>

Service/version detection:

# nmap -sV -sC -p 22,80,443,2222 -oN scan_svcs.txt <HONEYPOT_IP>

Scan while avoiding ping (if your VM blocks ICMP):

# nmap -Pn -sS -p1-2000 <HONEYPOT_IP>

Aggressive scan + scripts (use on your own host only):

# nmap -A -T4 <HONEYPOT_IP>

Watch your honeypot logs while scanning to confirm entries.

5) Log collection & analysis

  • Kernel log: sudo tail -F /var/log/kern.log or sudo journalctl -f
  • Python listener log: /var/log/honeypot.log
  • For structured logging and higher throughput: configure ulogd (NFLOG) or forward logs to syslog/rsyslog and ELK/Graylog.
  • Example simple grep: grep HPOT_CONN /var/log/kern.log | tail -n 200

6) Hardening & operational tips

  • Isolate honeypot inside a VM and snapshot it so you can revert.
  • Use rate limits in iptables to avoid log flooding: -m limit –limit 5/min.
  • Rotate logs: configure logrotate for /var/log/honeypot.log.
  • Do not allow outbound traffic from the honeypot unless needed – attackers may use it to pivot. Use egress firewall rules to restrict outbound connections.
  • Consider running the honeypot under an unprivileged user wherever possible.
  • If expecting a lot of traffic, use NFLOG + ulogd or suricata/zeek for more scalable capture.

7) Optional: Richer visibility with NFLOG / ulogd

If you anticipate higher volume or want structured logs, use:

# example: mark packets from all TCP and send to NFLOG group 1

# iptables -I INPUT -p tcp -m limit –limit 10/min -j NFLOG –nflog-group 1

# run ulogd to write NFLOG to a file or DB (configure /etc/ulogd.conf)

8) Example scenario — bring it all together

  1. Start VM and ensure IP 192.168.56.101.
  2. Add iptables logging and redirect HTTP->8080.
  3. Run simple_honeypot.py with ports [22,80,2222,8080].
  4. From your scanner machine: nmap -sS -sV -p22,80,2222,8080 192.168.56.101
  5. Watch /var/log/honeypot.log and kernel logs for HPOT_* prefixes to see connections and payloads.

Quick reference for commands used:

  • Create honeypot chain and log SYNs:

# iptables -N HONEY

# iptables -A HONEY -p tcp –syn -m limit –limit 5/min –limit-burst 10 \
-j LOG –log-prefix "HPOT_SYN: "

# iptables -A INPUT -p tcp -j HONEY

  • Redirect port 80 -> 8080

# iptables -t nat -A PREROUTING -p tcp –dport 80 -j REDIRECT –to-ports 8080

  • Run listener:

# python3 simple_honeypot.py

  • Test with nmap:

# nmap -sS -sV -p22,80,2222,8080 -Pn <IP>

Conclusion

Building a simple Linux port‑scan honeypot with iptables and lightweight listeners gives you practical, immediate visibility into who’s probing your network and how they probe. With a few well‑scoped iptables rules you can capture and rate‑limit connection attempts, redirect selected ports to local emulators, and keep tidy, analysable logs. The small Python listener shown is enough to collect banners and initial payloads; for higher volume or more fidelity you can step up to NFLOG / ulogd, Zeek / Suricata, or production honeypots like Cowrie.

Remember the two rules that keep a honeypot useful and safe: isolate it (VMs, VLANs, strict egress rules) and log thoughtfully (rate limits, rotation, structured formats). That protects your environment and makes the data you collect far more valuable. Over time, turn raw logs into indicators (IP reputations, patterns of ports/probes, common payloads) and feed them into alerts or dashboards to turn passive observation into active defense.

How to keep track of All User accounts executed commands, highest CPU consumers and user times on Linux

Tuesday, February 5th, 2013

Linux accounting keeping an eye on all user run commands time accounting find cpu eaters

For people interested into statistics of how Linux existing users are spending, there log in times and what kind of commands each of users is executing, take a look at acct
acct is existing on all mainstream Linux distributions is a great sysadmin tool. acct is a great tool whether you have a system where a multitude of users you don't trust has to be monitored. It is an absolutely must have for anyone willing to run, lets say  experimental honeypot or  free shell host. acct is useful for paranoid sysadmins who like to always knows what there users are running as well as in situation where some of users is suspected to be a potential cracker trying to root the host.

Below is description of acct package on Debian:

# apt-cache show acct| grep -i description -A 8
Description: The GNU Accounting utilities for process and login accounting
 GNU Accounting Utilities is a set of utilities which reports and summarizes
 data about user connect times and process execution statistics.
 .
 "Login accounting" provides summaries of system resource usage based on connect
 time, and "process accounting" provides summaries based on the commands
 executed on the system.
 .
 The 'last' command is provided by the sysvinit package and not included here.

To start using acct, just install it with usual:

# apt-get install --yes acct

(Whether on Debian / Ubuntu Linux);

On Fedora, CentOS and RHEL and other RPM based Linuxes issue;

yum --y install psacct

On deb based Linux distributions, whether acct collects statistics is controlled via:

/etc/default/acct

# cat /etc/default/acct
# Defaults for acct

# If you want to keep acct installed, but not started automatically, set this
# variable to 0. Because /etc/cron.daily/acct calls the initscript daily, it is
# not sufficient to stop acct once after booting if your machine remains up.
ACCT_ENABLE="1"

# Amount of days that the logs are kept.
ACCT_LOGGING="30"

After installed to start collecting user "process accounting" data run acct via init script;

# /etc/init.d/acct start
Turning on process accounting, file set to '/var/log/account/pacct'.
Done..

The file gathering info on system usage, CPU load, user ran commands /var/log/account/psacct is a binary and unreadable tailing it with tail -f .

On CentOS / Fedora Linux to Enable acct account statistics gathering in future boot and from present moment on do;

# chkconfig psacct on
# /etc/init.d/psacct start

1. Find out all commands executed by Linux user account (lastcomm)

Once user accounting is running to get information of every command ever executed on user shell use lastcomm cmd. For example:

# lastcomm hipo

bash              F    hipo     pts/1      0.00 secs Tue Feb  5 00:20
bash              F    hipo     pts/1      0.03 secs Tue Feb  5 00:20
sed                    hipo     pts/1      0.00 secs Tue Feb  5 00:20
bash              F    hipo     pts/1      0.00 secs Tue Feb  5 00:20
uname                  hipo     pts/1      0.00 secs Tue Feb  5 00:20
bash              F    hipo     pts/1      0.00 secs Tue Feb  5 00:20
dircolors              hipo     pts/1      0.00 secs Tue Feb  5 00:20
bash              F    hipo     pts/1      0.00 secs Tue Feb  5 00:20
bash              F    hipo     pts/1      0.00 secs Tue Feb  5 00:20
bash              F    hipo     pts/1      0.00 secs Tue Feb  5 00:20
uname                  hipo     pts/1      0.00 secs Tue Feb  5 00:20
bash              F    hipo     pts/1      0.00 secs Tue Feb  5 00:20
bash              F    hipo     pts/1      0.00 secs Tue Feb  5 00:20
ls                     hipo     pts/1      0.00 secs Tue Feb  5 00:20
bash              F    hipo     pts/1      0.00 secs Tue Feb  5 00:20
bash              F    hipo     pts/1      0.03 secs Tue Feb  5 00:20
sed                    hipo     pts/1      0.00 secs Tue Feb  5 00:20
bash              F    hipo     pts/1      0.00 secs Tue Feb  5 00:20
uname                  hipo     pts/1      0.00 secs Tue Feb  5 00:20
bash              F    hipo     pts/1      0.00 secs Tue Feb  5 00:20
id                     hipo     pts/1      0.00 secs Tue Feb  5 00:20
mesg                   hipo     pts/1      0.00 secs Tue Feb  5 00:20
verse                  hipo     pts/1      0.00 secs Tue Feb  5 00:20
cowrand                hipo     pts/1      0.00 secs Tue Feb  5 00:20
cowsay                 hipo     pts/1      0.03 secs Tue Feb  5 00:20
cowrand           F    hipo     pts/1      0.00 secs Tue Feb  5 00:20
head                   hipo     pts/1      0.00 secs Tue Feb  5 00:20
tail                   hipo     pts/1      0.00 secs Tue Feb  5 00:20
head                   hipo     pts/1      0.00 secs Tue Feb  5 00:20
ls                     hipo     pts/1      0.00 secs Tue Feb  5 00:20
cowrand           F    hipo     pts/1      0.00 secs Tue Feb  5 00:20
awk                    hipo     pts/1      0.00 secs Tue Feb  5 00:20
wc                     hipo     pts/1      0.00 secs Tue Feb  5 00:20
ls                     hipo     pts/1      0.00 secs Tue Feb  5 00:20

A lot of the initial commands shown to run on pts/1 is not actual commands, by the user but are just stuff run on user login time via /etc/bash.bashrc, /etc/profile, ~/.bashrc. ~/.bash_profile.

lastcomm displayed output from 2nd column is a special flag giving more information on how and for what purpose command was executed. In above output
F
– indicates the command run after a fork.
X – is returned if a command exit with SIGTERM (kill signal)
D – in case of generated command core dump (D is good one to look for whether checking a suspicious user profile, as it is so common exploits use core dumping to get root superuser access)
S – means the command is run with superuser privileges (this one you will see usually whether inspecting user profile of a cracker who run exploit using core dump – a lot of Ds followed by some shell code to run as superuser)

2. Get statistics on CPU use time of services (daemons) and user accounts

psacct is very handy, whether you have CPU server overloads and you have difficulty finding out what are the "CPU hungry processes". To get those use summarized accounting information tool;

# sa -m
                                     2619      31.06re       0.54cp         0avio      2907k
root                                 2448      30.19re       0.52cp         0avio      2817k
www-data                               33       0.06re       0.02cp         0avio      3687k
hipo                                   72       0.15re       0.01cp         0avio      6217k
qscand                                 11       0.36re       0.00cp         0avio      5326k
vpopmail                               48       0.25re       0.00cp         0avio      1486k
qmails                                  6       0.00re       0.00cp         0avio       968k
sshd                                    1       0.04re       0.00cp         0avio     12632k

-m (prints user summary).

3. Find all system users running certain commands

Another good use of lastcomm command is to grep over all users executed command for precise commands of interest. One very good use case is if you catch a system abuser running certain exploit or DoS tool on the host and you want to make sure no-one else on the system doesn't try running it.

# lastcomm ls
ls                     www-data __         0.00 secs Tue Feb  5 00:40
ls                     www-data __         0.00 secs Tue Feb  5 00:30
ls                     hipo     pts/7      0.00 secs Tue Feb  5 00:20
ls                     hipo     pts/1      0.00 secs Tue Feb  5 00:20
ls                     hipo     pts/1      0.00 secs Tue Feb  5 00:20
ls                     hipo     pts/1      0.00 secs Tue Feb  5 00:20
ls                     hipo     pts/1      0.00 secs Tue Feb  5 00:20
ls                     hipo     pts/1      0.00 secs Tue Feb  5 00:20
ls                     www-data __         0.00 secs Tue Feb  5 00:20
ls                     root     pts/0      0.00 secs Tue Feb  5 00:10
ls                     root     pts/0      0.00 secs Tue Feb  5 00:10
ls                     www-data __         0.00 secs Tue Feb  5 00:10
 

4. Get statistics of most active system users in hours

There is one tool called ac, which is similar in what it does to last command, just like last it uses /var/log/wtmp binary log file to get its user login times stats . The difference is ac provides more and better structured user login time length info.

Its very useful if you want to have idea, which user spends most time connected to host.

$ ac -p
    sic                                  4.86
    hipo                                 4.80
    root                                25.80
    play                                 0.02

To get general info on how much overall hours all existing users spend doing stuff on node;

$ ac total 35.61

To know which days from the month users were most active:

$ ac -d
Feb 1 total 14.54
Feb 2 total 0.97
Feb 3 total 12.47
Feb 4 total 5.96
Today total 1.73