Fighting with brute force attack on email service - linux

I am facing an issue and need your expert advice.
I get constant brute force attacks warnings in directadmin from IPs in Russia & China etc etc.
The messages are something like
Feb 27 04:31:15 host1 dovecot[2387]: pop3-login: Aborted login (auth failed, 1 attempts in 2 secs): user=<postmaster#domain.com>, method=PLAIN, rip=194.63.XXX.XXX, lip=XX.XX.99.210, session=<aC8bgAkQ2ADCP45l>
Feb 27 04:31:05 host1 exim[2385]: exim: Aborted login (auth failed, 10 attempts in 20 secs): user=<postmaster#domain.com>, method=PLAIN, rip=194.63.XXX.XXX, lip=XX.XX.99.210, session=<aC8bgAkQ2ADCP45l>
It is not a commercial hosting so only 4-5 different ip addresses actually logs into the email clients to check emails.
So I have decided to block all ip addresses accessing port 25, 465, 587 by putting this in the /etc/csf/csf.deny
tcp:in:d=25:s=0.0.0.0/0
tcp:in:d=465:s=0.0.0.0/0
tcp:in:d=587:s=0.0.0.0/0
And i allowed my ip addresses in the /etc/csf/csf.allow
Is this a good idea?
Can still outside world email me? Port 25 is blocked?
tcp:in:d=25:s=124.12.0.0/20
tcp:in:d=465:s=124.12.0.0/20
tcp:in:d=587:s=124.12.0.0/20
Please advise.
Thank you so much.
Server: Debian GNU/Linux 7.5 x86_64 / Direct Admin / CSF Firewall

A good solution would be to use Fail2ban.
Fail2ban is a Daemon to ban hosts that cause multiple authentication errors
And it uses iptables to do the work.
By default it won't block SMTP attacks, but you can edit its config file /etc/fail2ban/jail.local like this:
[...]
[sendmail]
enabled = true
port = smtp,ssmtp
filter = sendmail
logpath = /var/log/mail.log
bantime = 28800
action = iptables-multiport[name=sendmail, port="pop3,imap,smtp,pop3s,imaps,smtps", protocol=tcp]
Just make sure paths and ports are correct with your config.

Iptables has the ability to inspect the contents of a packet. With that you can look for authentication errors and add them to a ban list. Our mail server is under a constant dictionary attack from a number of sources and this has rate limited that from 10 per minute to one every 5 minutes or do. This is an abbreviated sample, the full script is at http://www.wiseoldcat.com/?q=node/32. The format is the CentOS/Redhat /etc/sysconfig/iptables or iptables-save. This approach could be adapted for imap and pop
:SMTP_Check_Auth_OUTPUT - [0:0]
:SMTP_Check_Auth_INPUT - [0:0]
....
# add jumps for NEW connections to our filters on the INPUT chain for the SMTP and SUBMISSION ports
-A INPUT -p tcp -m multiport --dports 25,587 -m state --state NEW -j SMTP_Check_Auth_INPUT
....
# Add the authentication filter on the OUTPUT side
-A OUTPUT -p tcp -m multiport --sports 25,587 -m state --state ESTABLISHED,RELATED -j SMTP_Check_Auth_OUTPUT
....
# one of our netblocks so RETURN
-A SMTP_Check_Auth_OUTPUT -d 123.123.123.0/24 -j RETURN
# if the contents packet do NOT have the authentication error string then RETURN - customize for your mailserver
-A SMTP_Check_Auth_OUTPUT -p tcp -m string --to 120 --algo kmp --string ! "535 5.7.0 authentication failed" -j RETURN
# set an entry in the recent table
-A SMTP_Check_Auth_OUTPUT -p tcp -m recent --name SMTP_AUTH_ERROR --set --rdest
-A SMTP_Check_Auth_OUTPUT -j LOG --log-prefix "SMTP_AUTH_FAIL: Strike: "
....
# Add the target for the INPUT side
# we are here because this is a new connection - if there hasn't been 3 hits in 20 minutes then RETURN - adjust to your needs
-A SMTP_Check_Auth_INPUT -m recent ! --rcheck --name SMTP_AUTH_ERROR --seconds 1200 --hitcount 3 --rsource -j RETURN
# tag it again
-A SMTP_Check_Auth_INPUT -p tcp -m recent --name SMTP_AUTH_ERROR --set --rsource
# and REJECT the connection
-A SMTP_Check_Auth_INPUT -j REJECT --reject-with icmp-port-unreachable

Related

iptables --sport vs --dport. INPUT vs OUTPUT

I am having some trouble understanding iptables. I know it acts as a filter but something isn't clicking because it isn't working the way I think it should. Let me start by saying that I'm creating a white list, so all policies (INPUT, FORWARD, OUTPUT) default to DROP.
I have the following rules related to SMTP:
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p tcp --dport 25 -j ACCEPT
-A OUTPUT -p tcp --dport 25 -j ACCEPT //needed for receiving?
-A OUTPUT -p tcp --sport 25 -j ACCEPT //needed for sending?
*these 3 lines also exist verbatim for ports 587 & 465
If I remove the first OUTPUT line then my server won't receive emails & if I remove the last line it won't send emails. What I don't understand is why. Shouldn't:
-A INPUT -p tcp --dport 25 -j ACCEPT
-A OUTPUT -p tcp --sport 25 -j ACCEPT
be enough to let everything through? AFAIK all SMTP communication should go over 25, 587 or 465. My current understanding says an SMTP packet should always match one of these two rules. All input packets should come to port 25, and all output packets be sent from 25? What am I missing?
For SMTP you don't need any --sport rule. The source and destination don't depend on direction - they're match on the packet's source and destination ports. Every connection will have a random source port, so there's nothing to match on.
If I remove the first OUTPUT line then my server won't receive emails & if I remove the last line it won't send emails.
This is wrong. Only the INPUT line matters for receiving emails. Also, only the OUTPUT --dport 25 line matters for sending emails. So these rules should be enough:
-A INPUT -p tcp --dport 25 -j ACCEPT
-A OUTPUT -p tcp --dport 25 -j ACCEPT
The problem may be that you set OUTPUT to default to DROP, but allowed established connection on INPUT only. Usually people leave OUTPUT defaulting to ACCEPT. If you want to continue using a whitelist for OUTPUT, you'll have to add:
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Also, please read up on SMTP ports. Some of those you listed are only needed for email submissions and deprecated encryption, not for server-to-server communication. This may change how you plan your rules.
Previous answer state: Also, only the OUTPUT --dport 25 line matters for sending emails.
This is not always true. For instance some systems are configured as smarthost where the MTA become a client. In such case, the MTA will connect to a remote server on submission port (587) USING SASL authentication to send mails.
To resume, a client is sending mail through a remote server and the remote server itself connect to another remote server on port 587 with SASL authentication.
In such case, the following iptable rules applies (for the smarthost)
iptables -I OUTPUT -p -tcp -dport 597 -j ACCEPT
iptables -I INPUT -p -tcp -sport 587 -j ACCEPT

How to restrict direct access to a node.js server

I have an apache web server where most of my content is hosted, and then I have a node.js server I'm using for various tasks as well. I want users to be able to get information from my node.js server only through reverse proxy from my apache server. I understand how to set up a reverse proxy using mod_proxy on the apache side, but how can I restrict access to the node server except through an apache virtual host? One option I'm sure would work is to host my node server on a separate box and block any ip address except the apache server. Is there a way though that I could have them both running on the same machine and configure node to reject requests except from the apache server?
You could have the running on the same box. In the Node server have something like the following:
if(req.socket.remoteAddress !== '127.0.0.1'){
res.writeHead(403, {"Content-Type": "text/plain"});
res.write('403 Access Denied');
res.end();
} else {
// allow access
doSomething();
}
Of course, that allows other processes on the same box to connect to the Node server.
I've done this using iptables, allowing incoming connections to port 80 for the webserver. Access to port 3000 from the webserver is allowed because it's coming from the same host.
Here's an example rule file:
*filter
# Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT
# Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allows all outbound traffic
# You could modify this to only allow certain traffic
-A OUTPUT -j ACCEPT
# Allows connections for HTTP
-A INPUT -p tcp --dport 80 -j ACCEPT
# Allows SSH connections
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT
# Now you should read up on iptables rules and consider whether ssh access
# for everyone is really desired. Most likely you will only allow access from certain IPs.
# Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
# log iptables denied calls (access via 'dmesg' command)
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
# Reject all other inbound - default deny unless explicitly allowed policy:
-A INPUT -j REJECT
-A FORWARD -j REJECT
COMMIT
Put this file on your server (e.g. /etc/iptables.up.rules), and run the iptables command to update your iptables rules.
iptables-restore < /etc/iptables.up.rules

How to regulate output traffic with iptables

I'm hosting several websites, and some of them use scripts to ddos externals servers from my server.
There is a possibility to control the outgoing traffic by, for example, limiting the number of request per second or so ?
Here are some example to prevent DOS, you can man iptables to search the keyword 'limit, connlimit, hitcount' for more informations.
Allow 5 new connection packets per second
iptables -A OUTPUT -p tcp --syn -m limit --limit 1/s --limit-burst 5 -j ACCEPT
Allow 30 connections during 60 seconds each IP.
iptables -A OUTPUT -p tcp --dport 80 -m recent --name BAD_HTTP_ACCESS --update --seconds 60 --hitcount 30 -j REJECT
50 max connections per IP to httpd
iptables -A OUTPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j REJECT

Confluence is very slow behind firewall

I've installed Confluence on Debian Linux 7.0. It runs on 8081 port (for connector, 8091 is used as TomCat server port). I've configured Apache to act as reverse proxy and serve on https://confluence.<mydomain>.com (SSL is configured on Apache side).
The configuration worked perfect unless I set up firewall rules. It still works as expected but became extremely slow (memory and CPU utilisations are low). Switching firewall off brings the performance back to normal. The set of firewall rules for IPv4 is:
*filter
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT ACCEPT
# Allow all loopback (lo0) traffic
-A INPUT -i lo -j ACCEPT
# Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
# Allows SSH connections
-A INPUT -p tcp --dport 22 -j ACCEPT
# Allow all HTTP and HTTPS connections
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
COMMIT
IPv6 traffic is completely disabled:
*filter
-P INPUT DROP
-P FORWARD DROP
-P OUTPUT DROP
COMMIT
I'm using Oracle JVM (1.7), startup options are configured in the following way:
JAVA_OPTS="-Xms512m -Xmx2048m -XX:MaxPermSize=1024m $JAVA_OPTS -Djava.awt.headless=true"
Confluence version is "Confluence 5.4.2 - Standalone (TAR.GZ Archive)", license is Starter (10 users). Database is locally installed PostreSQL.
Anyone has an idea on what I'm doing wrong?

Iptables or something to redirect IP in gateway (GNU/Linux)

Im writing a bash scripting to account traffic in my network server:
WAN:eth1 -> GNU/Linux Server:eth0 -> Users
The GNU/Linux server uses squid, bind, QoS, mysql, lighttpd.
After an IP exceed the established quota a new QoS rule is applied for that IP (user) too exist one "flag" to decide when is restored the IP counter to Zero.
Some IPs and subnets work without quotas, other gruop of ips/subnets work with new QoS after quota is exceeded, and now I wanna work with a third group with redirection after quota is exceeded.
When an IP exceed the established quota all http traffic must be redirected to host (lighttpd runing on GNU/Linux ) and DROP all other traffic generated for that IP. In webserver exist a webpage with: "You exceed your daily quote of traffic, please wait "x" hours or call to your provider to purchase an extra navigation package" or something like that.
Is possible using a chain, or how can I do that?.
The most topics that I found in Internet, are related to block all and create a new chain to let out to Internet (not work for me). And other redirect only IP by IP, but how can I create something that a "chain" and attach the IPs to must me redirected to can after restore that IPs easly?
Thanks for help and sorry for my poor English :S.
Are you looking for something like this?
iptables -t nat -A PREROUTING -s 192.168.100.66 -p tcp --dport 80 -j REDIRECT --to-ports 80
iptables -I INPUT 1 -i lo -s 192.168.100.66 -j ACCEPT
iptables -I INPUT 2 -i eth1 -d 192.168.100.66 -j DROP
This will redirect packets from 192.168.100.66 on port 80 to the local webserver on the loopback interface, allow that conversation, then reject all other packets being routed to 192.168.100.66 on the WAN interface.
To restore the connection back to normal you will want to delete those firewall entries:
iptables -t nat -D PREROUTING -s 192.168.100.66 -p tcp --dport 80 -j REDIRECT --to-ports 80
iptables -D INPUT -i lo -s 192.168.100.66 -j ACCEPT
iptables -D INPUT -i eth1 -d 192.168.100.66 -j DROP
Note that iptables itself (well, the xtables-addons extension set providing quota2) can already do the quota matching magic and you can (re)set the values through procfs, combined with REDIRECT as #resmon6 says:
-t nat -s user1addr -m quota2 --name user1 ! --quota 0 -j REDIRECT...
-t nat -s user2addr -m quota2 --name user2 ! --quota 0 -j REDIRECT...
The syntax is a arguably a little odd right now (0 is the initial value only and is independent from the runtime quota test involving the negational !. Noticing this just now, a patch may make it in to unroll this confusing syntax in the future).

Resources