Friday, December 20, 2019

Linux Tables: Block All Incoming Traffic But Allow SSH

 This is very common scenario. You want to permit access to a remote machine only by SSH. You would like to block all incoming traffic to your system except ssh connection under Linux 

Add following rules to your iptables shell script:

/sbin/iptables

-A INPUT -p tcp --dport 22 -j ACCEPT

/sbin/iptables

-A OUTPUT -p tcp --sport 22 -j ACCEPT

 

First rule will accept incoming (INPUT) tcp connection on port 22 (ssh server) and second rule will send response of incoming ssh server to client (OUTPUT) from our ssh server source port 22.

However, iptables with kernel 2.4/2.6 provides very powerful facility to filter rule based upon different connection states such as established or new connection etc. Here is complete small script to do this task:

 

#!/bin/sh

#

My system IP/set ip address of

server

SERVER_IP="65.55.12.13"

#

Flushing all rules

iptables

-F

iptables

-X

#

Setting default filter policy

iptables

-P INPUT DROP

iptables

-P OUTPUT DROP

iptables

-P FORWARD DROP

#

Allow unlimited traffic on loopback

iptables

-A INPUT -i lo -j ACCEPT

iptables

-A OUTPUT -o lo -j ACCEPT

 

#

Allow incoming ssh only

iptables

-A INPUT -p tcp -s 0/0

-d $SERVER_IP --sport 513:65535

--dport 22 -m state --state

NEW,ESTABLISHED -j ACCEPT

iptables

-A OUTPUT -p tcp -s $SERVER_IP -d 0/0

--sport 22 --dport 513:65535

-m state --state ESTABLISHED -j ACCEPT

#

make sure nothing comes or goes

out of this box

iptables

-A INPUT -j DROP

iptables

-A OUTPUT -j DROP

This script is purely strict firewall. It only allows incoming ssh. No other incoming service or ping request or no outgoing service or request allowed. Incoming ssh connection can be either new or already established one and that is what specified by state rule '-m state --state NEW,ESTABLISHED'. Outgoing ssh connection state can be established only. By default this script allows everyone to ssh in by rule -s 0/0. If you want this access limited by IP or network address then replace -s 0/0 with IP address. For example allow incoming ssh from IP 202.54.1.20:

 

#

Allow incoming ssh only from IP

202.54.1.20

iptables

-A INPUT -p tcp -s 202.54.1.20 -d

$SERVER_IP --sport 513:65535

--dport 22 -m state --state

NEW,ESTABLISHED -j ACCEPT

iptables

-A OUTPUT -p tcp -s $SERVER_IP -d

202.54.1.20 --sport 22

--dport 513:65535

-m state --state ESTABLISHED -j ACCEPT

 

Linux Iptables allow or block ICMP ping request

The Internet Control Message Protocol (ICMP) has many messages that are identified by a "type" field. You need to use 0 and 8 ICMP code types.

=> Zero (0) is for echo-reply

=> Eight (8) is for echo-request.

To enable ICMP ping incoming client request use following iptables rule (you need to add following rules to script).

My default firewall policy is blocking everything.

Task: Enable or allow ICMP ping incoming client request

Rule to enable ICMP ping incoming client request ( assuming that default iptables policy is to drop all INPUT and OUTPUT packets)

SERVER_IP="202.54.10.20"

iptables

-A INPUT -p icmp --icmp-type 8 -s 0/0 -d $SERVER_IP -m state --state

NEW,ESTABLISHED,RELATED -j ACCEPT

iptables

-A OUTPUT -p icmp --icmp-type 0 -s $SERVER_IP -d 0/0 -m state --state

ESTABLISHED,RELATED -j ACCEPT

Task: Allow or enable outgoing ping request

To enable ICMP ping outgoing request use following iptables rule:

SERVER_IP="202.54.10.20"

iptables

-A OUTPUT -p icmp --icmp-type 8 -s $SERVER_IP -d 0/0 -m state --state

NEW,ESTABLISHED,RELATED -j ACCEPT

iptables

-A INPUT -p icmp --icmp-type 0 -s 0/0 -d $SERVER_IP -m state --state

ESTABLISHED,RELATED -j ACCEPT

How do I disable outgoing ICMP request?

Use the following rules:

iptables

-A OUTPUT -p icmp --icmp-type echo-request -j DROP

OR

iptables

-A OUTPUT -p icmp --icmp-type 8 -j DROP

ICMP echo-request type will be block by above rule.

See ICMP TYPE NUMBERS (type fields). You can also get list of ICMP types, just type following command at shell prompt:# /sbin/iptables -p icmp -h

 

Linux Iptables: HowTo Block or Open HTTP/Web Service Port 80 & 443

By default Apache webserver listen on port 80 (http) and port 443 (https i.e. secure http). Apache webserver uses the TCP protocol to transfer information/data between server and browser. The default Iptables configuration does not allow inbound access to the HTTP (80) and HTTPS (443) ports used by the web server. This post explains how to allow inbound and outbound access to web services under Linux.

You can edit 
/etc/sysconfig/iptables file under RHEL / CentOS / Fedora Linux. Add the following lines, ensuring that they appear before the final LOG and DROP lines for the RH-Firewall-1-INPUT chain to open port 80 and 443:

 

-A

RH-Firewall-1-INPUT -m state --state NEW

-p tcp --dport 80 -j ACCEPT

-A

RH-Firewall-1-INPUT -m state --state NEW

-p tcp --dport 443 -j ACCEPT

 

Finally, restart the firewall:# service iptables restart
If you've your own shell script, try:

 

/sbin/iptables

-A INPUT -m state --state NEW -p tcp --dport 80

-j ACCEPT

/sbin/iptables

-A INPUT -m state --state NEW -p tcp --dport 443

-j ACCEPT

 

Allow incoming http/web traffic at port 80

 

SERVER_IP="202.54.10.20"

iptables

-A INPUT -p tcp -s 0/0

--sport 1024:65535

-d $SERVER_IP --dport 80

-m state --state NEW,ESTABLISHED -j ACCEPT

iptables

-A OUTPUT -p tcp -s $SERVER_IP --sport

80 -d 0/0

--dport 1024:65535

-m state --state ESTABLISHED -j ACCEPT

 

Allow incoming https/secure web traffic at port 443

 

SERVER_IP="202.54.10.20"

iptables

-A INPUT -p tcp -s 0/0

--sport 1024:65535

-d $SERVER_IP --dport 443

-m state --state NEW,ESTABLISHED -j ACCEPT

iptables

-A OUTPUT -p tcp -s $SERVER_IP --sport

443 -d 0/0

--dport 1024:65535

-m state --state ESTABLISHED -j ACCEPT

 

Allow outgoing http/web service traffic to port 80

 

SERVER_IP="202.54.10.20"

iptables

-A OUTPUT -p tcp -s $SERVER_IP --sport

1024:65535

-d 0/0

--dport 80 -m state --state

NEW,ESTABLISHED -j ACCEPT

iptables

-A INPUT -p tcp -s 0/0

--sport 80 -d $SERVER_IP

--dport 1024:65535

-m state --state ESTABLISHED -j ACCEPT

 

Allow outgoing https/secure web service traffic to port 443

 

SERVER_IP="202.54.10.20"

iptables

-A OUTPUT -p tcp -s $SERVER_IP --sport

1024:65535

-d 0/0

--dport 443 -m state --state

NEW,ESTABLISHED -j ACCEPT

iptables

-A INPUT -p tcp -s 0/0

--sport 443 -d $SERVER_IP

--dport 1024:65535

-m state --state ESTABLISHED -j ACCEPT

 

===============================================

How do I build a Simple Linux Firewall for DSL/Dial-up connection?

If you're new to Linux, here's a simple firewall that can be setup in minutes. Especially those coming from a Windows background, often lost themselves while creating linux firewall.
This is the most common question asked by Linux newbies (noobs). How do I install a personal firewall on a standalone Desktop Linux computer. In other words "I wanna a simple firewall that allows or permits me to visit anything from my computer but it should block everything from outside world".
Well that is pretty easy first remember INPUT means incoming and OUTPUT means outgoing connection/access. With following little script and discussion you should able to setup your own firewall.

Step # 1: Default Firewall policy

Set up default access policy to drop all incoming traffic but allow all outgoing traffic. This will allow you to make unlimited outgoing connections from any port but not incoming traffic/ports are allowed.iptables -p INPUT DROP
iptables -p OUTPUT ACCEPT

Step # 2: Allow unlimited traffic from loopback (lo) device

iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -i lo -j ACCEPT

Step # 3: Setup connection oriented access

Some protocol such as a FTP, DNS queries and UDP traffic needs an established connection access. In other words you need to allow all related connection using iptables state modules.iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

Step # 4: Drop everything else and log it

iptables -A INPUT -j LOG
iptables -A INPUT -j REJECT

But wait you cannot type all above commands at a shell command prompt. It is a good idea to create a script called fw.start as follows (copy and paste following script in fw.start file):

#!/bin/sh

#

A simple

iptables

-F

iptables

-X

iptables

-t nat -F

iptables

-t nat -X

iptables

-t mangle -F

iptables

-t mangle -X

modprobe

ip_conntrack

modprobe

ip_conntrack_ftp

#

Setting default filter policy

iptables

-P INPUT DROP

iptables

-P OUTPUT ACCEPT

#

Unlimited access to loop back

iptables

-A INPUT -i lo -j ACCEPT

iptables

-A OUTPUT -o lo -j ACCEPT

#

Allow UDP, DNS and Passive FTP

iptables

-A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

#

DROP everything and Log it

iptables

-A INPUT -j LOG

iptables

-A INPUT -j DROP

You can enhance your tiny firewall with

·         Create a script to stop a firewall

·         This is optional, if you wish to start a firewall automatically as soon as Debian Linux boots up use the instruction outlined here

·         Finally if you wanna open incoming ssh (port 22) or http (port 80) then insert following two rules before #DROP everything and Log it line in above script:

iptables -A INPUT -p tcp -i eth0 --dport 22 -m state --state NEW -j ACCEPT
iptables -A INPUT -p tcp -i eth0 --dport 80 -m state --state NEW -j ACCEPT

Easy to use Linux firewall programs/tools

·         GUI tools - firestarter :: A graphical interfaced Open Source firewall for Linux. (highly recommended for Linux desktop users)

·         IPCop Firewall and SmoothWall :: Setup a dedicated firewall box. (highly recommended for Linux server and LAN/WAN users)

======================================================================

Linux Iptables: How to specify a range of IP addresses or ports

How can I save time and script size by specifying a range of IP addresses or ports using iptables?

In old version of iptables IP address ranges are only valid in the nat table (see below for example). However newer version does support option that allows you to specify a range of IP addresses or ports for regular tables such as input.

Iptables set range of IP addresses

You need to use following options with match extensions (-m Ext).

iprange : This matches on a given arbitrary range of IPv4 addresses.

·         [!]--src-range ip-ip: Match source IP in the specified range.

·         [!]--dst-range ip-ip: Match destination IP in the specified range.

Syntax:

-m iprange --src-range IP-IP -j ACTION
-m iprange --dst-range IP-IP -j ACTION

For example, allow incoming request on a port 22 for source IP in the 192.168.1.100-192.168.1.200 range only. You need to add something as follows to your iptables script:

iptables

-A INPUT -p tcp --destination-port 22 -m iprange --src-range

192.168.1.100-192.168.1.200 -j ACCEPT 

Port range

if --protocol tcp (-p tcp) is specified, you can specify source port range with following syntax:

·         --source-port port:port

·         --sport port:port

And destination port range specification with following option :

·         --destination-port port:port

·         --dport port:port

For example block lock all incoming ssh access at port 22, for source port range 513:65535:

iptables

-A INPUT -p tcp -s 0/0 --sport 513:65535 -d 195.55.55.78 --dport 22

-m state --state NEW,ESTABLISHED -j DROP

On the other hand, just allow incoming ssh request with following port range:

iptables

-A INPUT -p tcp -s 0/0 -d 195.55.55.78 --sport 513:65535 --dport 22

-m state --state NEW,ESTABLISHED -j ACCEPT

iptables

-A OUTPUT -p tcp -s 195.55.55.78 -d 0/0 --sport 22 --dport 513:65535

-m state --state ESTABLISHED -j ACCEPT

NAT table - range option

If you are using NAT table use options --to-source and --to-destination. For example IP address range:

iptables

-t nat -A POSTROUTING -j SNAT --to-source 192.168.1.100-192.168.1.200

ALTERNATIVELY, try range of ports:

iptables

-t nat -A POSTROUTING -j SNAT --to-source 192.168.1.100:2000-3000

Linux Iptables block or open DNS / bind service port 53

 

 

The domain name service provided by BIND (named) software. It uses both UDP and TCP protocol and listen on port 53. DNS queries less than 512 bytes are transferred using UDP protocol and large queries are handled by TCP protocol such as zone transfer.

i) named/bind server – TCP/UDP port 53

ii)Client (browser, dig etc) – port > 1023

Allow outgoing DNS client request:

Following iptables rules can be added to your shell script.

SERVER_IP is your server ip address

DNS_SERVER stores the nameserver (DNS) IP address provided by ISP or your own name servers.

Following rules are useful when you run single web/smtp server or even DSL/LL/dialup Internet connections:

SERVER_IP="202.54.10.20"

DNS_SERVER="202.54.1.5

202.54.1.6"

for

ip in $DNS_SERVER

do

iptables

-A OUTPUT -p udp -s $SERVER_IP --sport 1024:65535 -d $ip --dport 53

-m state --state NEW,ESTABLISHED -j ACCEPT

iptables

-A INPUT -p udp -s $ip --sport 53 -d $SERVER_IP --dport 1024:65535 -m

state --state ESTABLISHED -j ACCEPT

iptables

-A OUTPUT-p tcp -s $SERVER_IP --sport 1024:65535 -d $ip --dport 53 -m

state --state NEW,ESTABLISHED -j ACCEPT

iptables

-A INPUT -p tcp -s $ip --sport 53 -d $SERVER_IP --dport 1024:65535 -m

state --state ESTABLISHED -j ACCEPT

done

(B) Allow incoming DNS request at port 53:

Use following rules only if you are protecting dedicated DNS server.

SERVER_IP is IP address where BIND(named) is listing on port 53 for incoming DNS queries.

Please note that here I'm not allowing TCP protocol as I don't have secondary DNS server to do zone transfer.

SERVER_IP="202.54.10.20"

iptables

-A INPUT -p udp -s 0/0 --sport 1024:65535 -d $SERVER_IP --dport 53 -m

state --state NEW,ESTABLISHED -j ACCEPT

iptables

-A OUTPUT -p udp -s $SERVER_IP --sport 53 -d 0/0 --dport 1024:65535

-m state --state ESTABLISHED -j ACCEPT

iptables

-A INPUT -p udp -s 0/0 --sport 53 -d $SERVER_IP --dport 53 -m state

--state NEW,ESTABLISHED -j ACCEPT

iptables

-A OUTPUT -p udp -s $SERVER_IP --sport 53 -d 0/0 --dport 53 -m state

--state ESTABLISHED -j ACCEPT

Please note if you have secondary server, add following rules to above rules so that secondary server can do zone transfer from primary DNS server:

DNS2_IP="202.54.10.2"

iptables

-A INPUT -p tcp -s $DNS2_IP --sport 1024:65535 -d $SERVER_IP --dport

53 -m state --state NEW,ESTABLISHED -j ACCEPT

iptables

-A OUTPUT -p tcp -s $SERVER_IP --sport 53 -d $DNS2_IP --dport

1024:65535 -m state --state ESTABLISHED -j ACCEPT

==============================================

Linux Iptables Limit the number of incoming tcp connection / syn-flood attacks

 

A SYN flood is a form of denial-of-service attack in which an attacker sends a succession of SYN requests to a target's system. This is a well known type of attack and is generally not effective against modern networks. It works if a server allocates resources after receiving a SYN, but before it has received the ACK.

if Half-open connections bind resources on the server, it may be possible to take up all these resources by flooding the server with SYN messages. Syn flood is common attack and it can be block with following iptables rules:

iptables

-A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j RETURN

All incoming connection are allowed till limit is reached:

·         --limit 1/s: Maximum average matching rate in seconds

·         --limit-burst 3: Maximum initial number of packets to match

Open our iptables script, add the rules as follows:

#

Limit the number of incoming tcp connections

#

Interface 0 incoming syn-flood protection

iptables

-N syn_flood

iptables

-A INPUT -p tcp --syn -j syn_flood

iptables

-A syn_flood -m limit --limit 1/s --limit-burst 3 -j RETURN

iptables

-A syn_flood -j DROP

#Limiting

the incoming icmp ping request:

iptables

-A INPUT -p icmp -m limit --limit  1/s --limit-burst 1 -j ACCEPT

iptables

-A INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -j LOG

--log-prefix PING-DROP:

iptables

-A INPUT -p icmp -j DROP

iptables

-A OUTPUT -p icmp -j ACCEPT

First rule will accept ping connections to 1 per second, with an initial burst of 1. If this level crossed it will log the packet with PING-DROP in /var/log/message file. Third rule will drop packet if it tries to cross this limit. Fourth and final rule will allow you to use the continue established ping request of existing connection.
Where,

·         ‐‐limit rate: Maximum average matching rate: specified as a number, with an optional ‘/second’, ‘/minute’, ‘/hour’, or ‘/day’ suffix; the default is 3/hour.

·         ‐‐limitburst number: Maximum initial number of packets to match: this number gets recharged by one every time the limit specified above is not reached, up to this number; the default is 5.

You need to adjust the –limit-rate and –limit-burst according to your network traffic and requirements.

Let us assume that you need to limit incoming connection to ssh server (port 22) no more than 10 connections in a 10 minute:

iptables

-I INPUT -p tcp -s 0/0 -d $SERVER_IP --sport 513:65535 --dport 22 -m

state --state NEW,ESTABLISHED -m recent --set -j ACCEPT

iptables

-I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update

--seconds 600 --hitcount 11 -j DROP

iptables

-A OUTPUT -p tcp -s $SERVER_IP -d 0/0 --sport 22 --dport 513:65535 -m

state --state ESTABLISHED -j ACCEPT

==================================================================================================
Linux Iptables: How to block or open mail server / SMTP protocol

 

SMTP is used to send mail. Sendmail, Qmail, Postfix, Exim etc all are used on Linux as mail server. Mail server uses the TCP port 25. Following two iptable rule allows incoming SMTP request on port 25 for server IP address 202.54.1.20 (open port 25):
iptables -A INPUT -p tcp -s 0/0 --sport 1024:65535 -d 202.54.1.20 --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT

iptables -A OUTPUT -p tcp -s 202.54.1.20 --sport 25 -d 0/0 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT

In order to block port 25 simply use target REJECT instead of ACCEPT in above rules.

And following two iptables rules allows outgoing SMTP server request for server IP address 202.54.1.20:
iptables -A OUTPUT -p tcp -s 202.54.1.20 --sport 1024:65535 -d 0/0 --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT

iptables -A INPUT -p tcp -s 0/0 --sport 25 -d 202.54.1.20 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT

 

===========================================

Linux Iptables open Bittorrent tcp ports 6881 to 6889

 

I already wrote about Linux command line bittorrent client. However, I received few more queries regarding firewall issues. Basically you need to open ports using iptables.

Bittorrent client by default uses tcp 6881 to 6889 ports only. In order to work with Bittorrent client you need to open these ports on firewall. Remember, if you are behind a firewall (hardware or software) you need to enable port forwarding to internal systems.

Scenario # 1: Windows or Linux desktop behind router firewall

Internet

->     Hardware Router    -> Your Linux Desktop

 

         with

port forwarding          Client

 

             enabled

You have router (ADSL/DSL/Cable modem+router) and you have already enabled port forwarding on router (open web browser > Open router web admin interface > Find port forwarding > Enable port forwarding for bittorent protocol). You also need to open port using following iptables rules on Linux desktop (open TCP port 6881 to 6999):

iptables

-A INPUT -p tcp --destination-port 6881:6999 -j ACCEPT

iptables

-A OUTPUT -p tcp --source-port 6881:6999 -j ACCEPT

Here is a complete sample firewall script:

#!/bin/sh

iptables

-F

iptables

-X

iptables

-t nat -F

iptables

-t nat -X

iptables

-t mangle -F

iptables

-t mangle -X

modprobe

ip_conntrack

modprobe

ip_conntrack_ftp

#

Setting default filter policy

iptables

-P INPUT DROP

iptables

-P OUTPUT ACCEPT

#

Unlimited access to loop back

iptables

-A INPUT -i lo -j ACCEPT

iptables

-A OUTPUT -o lo -j ACCEPT

#

Allow UDP, DNS and Passive FTP

iptables

-A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT

#allow

bittorent incomming client request

iptables

-A INPUT -p tcp --destination-port 6881:6999 -j ACCEPT

#Uncomment

below to allow sshd incoming client request

#iptables

-A INPUT -p tcp -dport 22 -j ACCEPT

#

DROP everything and Log it

iptables

-A INPUT -j LOG

iptables

-A INPUT -j DROP

Scenario # 2

Internet

-> Linux computer Router  ->  Your Linux Desktop

 

        with

port forwarding      OR Windows XP client

 

        enabled

using IPTABLES       IP:192.168.1.2

 

          IP:192.168.1.254

Here you are using a Linux as software firewall and iptables as your NAT (firewall) for internal network (192.168.1.2). You need to enable port forwarding to a internal Linux desktop (may be Windows XP desktop) for BitTorrent client system. Add following two line of code to your existing NAT firewall script.

iptables

-t nat -A PREROUTING -p tcp --dport 6881:6889

-j

DNAT --to-destination 192.168.1.2

iptables

-A FORWARD -s 192.168.1.2 -p tcp --dport 6881:6889

-j

ACCEPT

======================================================================================

Linux Iptables allow LDAPS server incoming client request

Secure LDAP (LDAP over SSL) incoming client request service by default listen on TCP port 636 for queries. Following iptable rules allows incoming client request (open port TCP port 636) for server IP address 202.54.1.20 :iptables -A INPUT -p tcp -s 0/0 --sport 1024:65535 -d 202.54.1.20 --dport 636 -m state --state NEW,ESTABLISHED -j ACCEPT

iptables -A OUTPUT -p tcp -s 202.54.1.20 --sport 636 -d 0/0 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT

Restrict access to LDAPS database server from your network is essential, following iptables allows incoming LDAPS client request from IP address 202.54.1.0/24 network only:
iptables -A INPUT -p tcp -s 202.54.1.0/24 --sport 1024:65535 -d 202.54.1.20 --dport 636 -m state --state NEW,ESTABLISHED -j ACCEPT

iptables -A OUTPUT -p tcp -s 202.54.1.20 --sport 636 -d 202.54.1.0/24 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT

 


Linux Tables: Block All Incoming Traffic But Allow SSH

  This is very common scenario. You want to permit access to a remote machine only by SSH. You would like to block all incoming traffic to y...