Single Node with Firewall


This method is deprecated.Old technique using /etc/hosts.allow and /etc/hosts.deny files as Application Level Firewall for sshd

Note that this configuration works with public/private keys and not passowords.

In future; (no notice/consideration) will be given to (PAM users/password users).


sshd_firewall_single_node

This deprecated SSHD config uses legacy Application Level filtering via hosts.allow, now phased out in modern distros. Replaced by iptables and sshd_config controls.


#########################################################
# https://hiddenssh.com                                 #
#                                                       #
# sshd_firewall_single_node                             #
# version 1.4                                           #
# /etc/hosts.allow /etc/hosts.deny specific config file #
# Minor editing fixes                                   #
#                                                       #
# Standard practice: keep a known-good recovery backup  #   
# https://hiddenssh.com/backup-sshd-config              #
#########################################################
# Notes: if issues, run following commands.
# mkdir -p /run/sshd
# chmod 0755 /run/sshd
# chown root:root /run/sshd

# Network
# -------
# If you want to change the port on a SELinux (enforcing mode); 
# You need to change SELinux booleans, to allow this. 
# semanage port -a -t ssh_port_t -p tcp 2222
# Port tcp/22, is priority traffic but depends on network rules.
Protocol 2
Port 22
# Define inet; If you want to only listen on IPv4, 
# keep in mind you need to firewall twice; rules for IPv4 & IPv6, if you use both IPv4 & IPv6 at the same time.
# This is NOT recommended!
# AddressFamily any = IPv4 & IPv6
# AddressFamily inet = IPv4
# AddressFamily inet6 = IPv6
AddressFamily inet
# Use dedicated IP for sshd; From a Different Network block, 
# Trick from the 90s, credits "(Big Blue/IBM) worker".
# Seeing the IPv4 shortage today, this only works with IPv6 today.
# NOTE: Not recommended using (*/wildcard). 
# *Change me*
ListenAddress 192.168.0.1
# (VPN/If you are using a VPN) You need to listen to the IPv4 address inside the tunnel.
# Not recommended; adds chain of failure risk.
#ListenAddress 10.0.0.1
PermitTTY yes
TCPKeepAlive yes
# WARNING
AllowAgentForwarding no
AllowTcpForwarding no
PermitTunnel no
GatewayPorts no

# DEAMON
# -------
PidFile /var/run/sshd.pid

# Encryption
# ----------
# Syntax: ssh -Q cipher check what Encryption Ciphers your sshd has been (compiled with/supports).
# aes256-cbc uses AES in cipher-block chaining (CBC) mode, which can be vulnerable to certain attacks if not used correctly.
# aes256-gcm@openssh.com uses AES in Galois/Counter Mode (GCM), which provides both encryption and authentication, 
# making it resistant to certain types of attacks. However, it may not be as widely supported
# twofish256-ctr is a good option but not supported by all systems
# chacha20-poly1305@openssh.com is its performance. The ChaCha20 stream cipher is generally faster than AES, especially on systems without hardware s>
# Run /proc/cpuinfo to set the flags
# Use aes256-ctr if things break.
Ciphers aes256-gcm@openssh.com
# If you want to choose one MAC algorithm for the best security, hmac-sha2-512-etm@openssh.com would be the best choice.
MACs hmac-sha2-512-etm@openssh.com
# NIST P-curves are possibly back-doored by the U.S. National Security Agency.
# ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521
KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
# Public key types accepted
# ssh-rsa is most common default method.
# rsa-sha2-512 makes life easy for MacOS people.
# Profile(Hardware Security Key)      
#PubkeyAcceptedKeyTypes ssh-ed25519-cert-v01@openssh.com
# *Change me*
PubkeyAcceptedKeyTypes ssh-rsa,ssh-ed25519,rsa-sha2-512
RekeyLimit 4G 1h
# SSH compression can leak secrets via side-channel attacks: if attacker-controlled text is compressed with secrets, 
# output size changes reveal matching bytes, enabling gradual secret recovery. 
# Profile(hardened): Disable compression.
#Compression no
# Profile(Large data traffic):
Compression delayed 

# Logging
# -------
SyslogFacility AUTH
LogLevel info

# Info
# ----
# Greating for brutforces, Shows up as.  
# debug1: Remote protocol version 2.0, remote software version OpenSSH_8.7 HiddenSSH-cloud
# debug1: compat_banner: match: OpenSSH_8.7 HiddenSSH-cloud pat OpenSSH* compat 
# *Change me*
VersionAddendum hiddenssh-firewall-x11
# Print before login
Banner /etc/ssh/login.txt
# Print /etc/motd at succesful login
PrintMotd yes
# Show last login IPs
PrintLastLog yes

# Hardening login
# ---------------
LoginGraceTime 2m
StrictModes yes
MaxAuthTries 5
MaxSessions 5
MaxStartups 10:30:100
ChallengeResponseAuthentication no
UseDNS yes
UsePAM no
PermitRootLogin no
PermitEmptyPasswords no
# Access filter: sshd first resolves real accounts; unknown users fail normally.
# Existing users/groups listed here are denied before authentication succeeds.
# But its gona check them still before denial.
DenyGroups root ubuntu
DenyUsers root admin ubuntu administrator user test guest webmaster backup ftp ssh postgres mysql oracle tomcat apache www-data git docker mail pi
ClientAliveInterval 0
ClientAliveCountMax 5
HostbasedAuthentication no
IgnoreUserKnownHosts no
ChrootDirectory none

# INFORMATION
# -----------
# Needed for: SCP sshfs (Disable if you dont use them). 
# Recommended: rsync -azvP -e "ssh" file.txt user1@host:/tmp/file.txt (No sftp needed)
Subsystem sftp  /usr/libexec/openssh/sftp-server

# User Settings
# --------
# With this option set to "yes", users can set arbitrary environment variables that can potentially override system settings and be used to launch ma>
# or perform unauthorized actions. This can be especially dangerous if the user connecting via SSH has administrative privileges on the system.
PermitUserEnvironment yes
     Match user user1,user2
Match all
    PermitUserEnvironment yes
PasswordAuthentication no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys .ssh/authorized_backup
#TrustedUserCAKeys /etc/ssh/certificate-auth/user_user1-cert.pub

# Environment variables
# --------------------- 
# https://hiddenssh.com/sshd-env
# echo $hiddenssh
# env
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
AcceptEnv hiddenssh oraclesecretkey oracleauthtoken cloudflaretoken openaikey

hosts.allow file is needed to be modified for OpenSSH firewall layer to work correctly.

Example: /etc/hosts.allow


# With logging
sshd: 10.0.0. : spawn /bin/echo `date` %c %d >> /var/log/vpn/ssh_user1_auth.log
# with out logging
sshd: 192.168.0.
sshd: 10.0.0.100

The hosts.deny file is used to block all connections by default, ensuring only explicitly allowed IPs in /etc/hosts.allow can access SSH.

Example: /etc/hosts.deny


# Block all connections unless explicitly allowed in /etc/hosts.allow
ALL: ALL
🔒 Why Set ALL: ALL in /etc/hosts.deny?

⚠️ Note: Some modern Linux distributions (Debian 10+, RHEL 9+) have deprecated hosts.allow and hosts.deny.

Example: Iptables Ip filtering

Pay close attention to ssh-ingress chain, and Policy of the CHAIN: DROP


Chain INPUT (policy DROP)
target             prot opt source               destination
ACCEPT             0    --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
ssh-ingress        2    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22

Chain OUTPUT (policy DROP)
target             prot opt source               destination
ACCEPT             0    --  0.0.0.0/0            0.0.0.0/0            ctstate ESTABLISHED /* NEEDED for 2 way communication */

Chain ssh-ingress (1 references)
target             prot opt source               destination
ACCEPT             all  --  192.168.0.0/32	 anywhere             ctstate NEW,ESTABLISHED /* User1 */
ACCEPT             all  --  10.0.0.10/32         anywhere             ctstate NEW,ESTABLISHED /* User2 */

Iptables

Iptables and firewall integration.


iptables -N ssh-ingress
iptables -A INPUT -j ssh-ingress
iptables -P INPUT DROP
iptables -A ssh-ingress -s 192.168.0.0/32 -d 192.168.0.1/32 -i Interface -p tcp -m tcp --dport 22 \
  -m state --state NEW,RELATED,ESTABLISHED \
  -m comment --comment "User1" -j ACCEPT