Created
September 8, 2025 12:13
-
-
Save fuzzbuster/9c85e3037c7afdc33396e18291b8412c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Purpose: Send port knocking sequences to open/close SSH access (with pre-checks) | |
| # Usage: ./knock_ssh_client.sh <server_ip> <action> | |
| # Actions: "open" (allow SSH), "close" (block SSH after use) | |
| # Match these with the server's OPEN_PORTS and CLOSE_PORTS | |
| OPEN_SEQ="10001 10002 10003" | |
| CLOSE_SEQ="10003 10002 10001" | |
| # Check arguments | |
| if [ $# -ne 2 ]; then | |
| echo "Usage: $0 <server_ip> <action>" | |
| echo "Example: $0 192.168.1.100 open" | |
| echo "Actions: 'open' (allow SSH), 'close' (block SSH)" | |
| exit 1 | |
| fi | |
| SERVER_IP="$1" | |
| ACTION="$2" | |
| # Install knock client only if missing | |
| echo "=== Checking for knock client ===" | |
| if command -v knock &> /dev/null; then | |
| echo "knock client is already installed. Proceeding." | |
| else | |
| echo "knock client not found. Installing..." | |
| if ! sudo apt-get install knockd -y > /dev/null; then | |
| echo "Error: Failed to install knock client. Exiting." | |
| exit 1 | |
| fi | |
| echo "knock client installed successfully." | |
| fi | |
| # Send sequence based on action | |
| case $ACTION in | |
| open) | |
| echo "Sending open sequence to $SERVER_IP: $OPEN_SEQ" | |
| knock -v "$SERVER_IP" $OPEN_SEQ | |
| echo "Sequence sent. You can now SSH to $SERVER_IP (e.g., ssh user@$SERVER_IP)" | |
| ;; | |
| close) | |
| echo "Sending close sequence to $SERVER_IP: $CLOSE_SEQ" | |
| knock -v "$SERVER_IP" $CLOSE_SEQ | |
| echo "Sequence sent. SSH access to $SERVER_IP is now blocked." | |
| ;; | |
| *) | |
| echo "Error: Invalid action. Use 'open' or 'close'." | |
| exit 1 | |
| ;; | |
| esac |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Purpose: Setup port knocking with knockd and ufw on Debian/Ubuntu (with pre-checks) | |
| # Usage: Run with root privileges: sudo ./setup_knockd_ufw.sh | |
| # Features: Skips existing installations, checks ufw status, avoids redundant operations | |
| # Customizable settings | |
| OPEN_PORTS="10001,10002,10003" # Port sequence to open SSH | |
| CLOSE_PORTS="10003,10002,10001" # Port sequence to close SSH | |
| SEQ_TIMEOUT=5 # Timeout for port sequence (seconds) | |
| # Check if run as root | |
| if [ "$(id -u)" -ne 0 ]; then | |
| echo "Error: Must run as root. Use 'sudo ./setup_knockd_ufw.sh'" | |
| exit 1 | |
| fi | |
| # Pre-check: Ensure ufw is enabled | |
| echo "=== Checking ufw status ===" | |
| if ! ufw status | grep -q "Status: active"; then | |
| echo "Warning: ufw is not enabled. Rules won't take effect. Enabling ufw now..." | |
| if ! ufw enable; then | |
| echo "Error: Failed to enable ufw. Exiting." | |
| exit 1 | |
| fi | |
| else | |
| echo "ufw is already active. Proceeding." | |
| fi | |
| # Step 1: Install knockd only if not installed | |
| echo "=== Checking for knockd installation ===" | |
| if command -v knockd &> /dev/null; then | |
| echo "knockd is already installed. Skipping installation." | |
| else | |
| echo "knockd not found. Installing..." | |
| if ! apt-get update -y > /dev/null || ! apt-get install knockd -y > /dev/null; then | |
| echo "Error: Failed to install knockd. Check network or package sources." | |
| exit 1 | |
| fi | |
| echo "knockd installed successfully." | |
| fi | |
| # Step 2: Configure /etc/knockd.conf (only if not already configured with ufw) | |
| echo "=== Configuring knockd.conf ===" | |
| if grep -q "ufw allow from %IP% to any port 22/tcp" /etc/knockd.conf 2>/dev/null; then | |
| echo "knockd.conf is already configured with ufw. Skipping rewrite." | |
| else | |
| cat > /etc/knockd.conf << EOF | |
| [options] | |
| UseSyslog | |
| [openSSH] | |
| sequence = $OPEN_PORTS | |
| seq_timeout = $SEQ_TIMEOUT | |
| command = ufw allow from %IP% to any port 22/tcp | |
| tcpflags = syn | |
| [closeSSH] | |
| sequence = $CLOSE_PORTS | |
| seq_timeout = $SEQ_TIMEOUT | |
| command = ufw delete allow from %IP% to any port 22/tcp | |
| tcpflags = syn | |
| EOF | |
| echo "knockd.conf configured with ufw commands." | |
| fi | |
| # Step 3: Detect main network interface (exclude loopback) | |
| echo "=== Detecting main network interface ===" | |
| INTERFACE=$(ip -br addr show | grep -v LOOPBACK | awk '{print $1}' | head -n 1) | |
| if [ -z "$INTERFACE" ]; then | |
| echo "Error: No network interface detected. Set it manually in /etc/default/knockd." | |
| exit 1 | |
| fi | |
| echo "Detected main interface: $INTERFACE" | |
| # Step 4: Configure knockd service (auto-start and interface) only if not configured | |
| echo "=== Configuring knockd service ===" | |
| if grep -q "START_KNOCKD=1" /etc/default/knockd 2>/dev/null && grep -q "$INTERFACE" /etc/default/knockd 2>/dev/null; then | |
| echo "knockd service is already configured. Skipping." | |
| else | |
| cat > /etc/default/knockd << EOF | |
| START_KNOCKD=1 | |
| KNOCKD_OPTS="-i $INTERFACE" | |
| EOF | |
| echo "knockd service configured (auto-start and interface set)." | |
| fi | |
| # Step 5: Remove existing ufw rules for SSH (port 22) if any | |
| echo "=== Cleaning up existing SSH (port 22) rules in ufw ===" | |
| RULE_NUMBERS=$(ufw status numbered | grep -E '22/tcp' | awk -F'[][]' '{print $2}' | sort -nr) | |
| if [ -n "$RULE_NUMBERS" ]; then | |
| for num in $RULE_NUMBERS; do | |
| echo "Removing ufw rule $num (allows 22/tcp)" | |
| yes | ufw delete $num > /dev/null | |
| done | |
| else | |
| echo "No existing 22/tcp rules in ufw. Nothing to remove." | |
| fi | |
| # Step 6: Start/enable knockd only if not running | |
| echo "=== Managing knockd service ===" | |
| if systemctl is-active --quiet knockd; then | |
| echo "knockd is already running. Skipping start." | |
| else | |
| systemctl restart knockd | |
| systemctl enable knockd > /dev/null | |
| if systemctl is-active --quiet knockd; then | |
| echo "knockd started and enabled on boot." | |
| else | |
| echo "Error: Failed to start knockd. Check logs with 'journalctl -u knockd'." | |
| exit 1 | |
| fi | |
| fi | |
| # Step 7: Add hourly restart cron job only if missing | |
| echo "=== Setting up knockd auto-restart ===" | |
| if crontab -l 2>/dev/null | grep -q "systemctl restart knockd"; then | |
| echo "Auto-restart cron job already exists. Skipping." | |
| else | |
| (crontab -l 2>/dev/null; echo "@hourly systemctl restart knockd") | crontab - | |
| echo "Added cron job: Restart knockd every hour." | |
| fi | |
| # Final message | |
| echo "=== Setup completed successfully! ===" | |
| echo "Open SSH sequence: $OPEN_PORTS" | |
| echo "Close SSH sequence: $CLOSE_PORTS" | |
| echo "Use client script to send sequences before/after SSH access." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment