Wednesday, May 16, 2012

Protecting WordPress from script fishing attacks with Fail2Ban

SkyHi @ Wednesday, May 16, 2012

I posted some previous ideas on this that were okay, but they turned out to be less-than-idea solutions. They work, but one of the blogs I watch over is a bit busy, and having Fail2Ban watching the Apache access.log was putting excessive load on the CPU.
So here’s a nicer approach, but it needs a bit more fiddling:
As /etc/fail2ban/filters.d/apache-phpmyadmin.conf
[Definition]
failregex =  [[]client []] (File does not exist|script ').*(phpMyAdmin|phpmyadmin|dbadmin|mysql|myadmin|w00t|muieblackcat|mysqladmin).*
ignoreregex =
As /etc/fail2ban/filters.d/apache-wp-login.conf
[Definition]
failregex =  [[]client []] WP login failed.*
ignoreregex =
As /etc/fail2ban/filters.d/apache-wp-timthumb.conf
[Definition]
failregex =  [[]client []] (File does not exist|script ').*(timthumb\.php).*
ignoreregex =
The relevant sections of /etc/fail2ban/jail.local should be something like these. This allows a few failed logins, but only one attempt to hit a phpMyAdmin directory or the TimThumb exploit. But maxretry and findtime can be whatever you want.
[apache-wp-login]
enabled = true
port    = http,https
filter  = apache-wp-login
logpath = /var/log/apache*/*error.log
maxretry = 3
findtime = 120

[apache-phpmyadmin]
action = %(action_mwl)s
enabled = true
port    = http,https
filter  = apache-phpmyadmin
logpath = /var/log/apache*/*error.log
maxretry = 1
findtime = 60

[apache-wp-timthumb]
action = %(action_mwl)s
enabled = true
port    = http,https
filter  = apache-wp-timthumb
logpath = /var/log/apache*/*error.log
maxretry = 1
findtime = 60
So now all of the jails are watching error.log, which hopefully gets significantly less traffic than access.log. But we need to make sure WordPress logs the information we need.
If pretty permalinks is turned on, WP handles 404s and does not output to a log. Add a 404.php to the active theme that looks like this, or if there is already one, just add the error_log line:


And add this to the functions.php in your theme too, to handle the login attempts:
 // Log login errors to Apache error log
 add_action('wp_login_failed', 'log_wp_login_fail'); // hook failed login

 function log_wp_login_fail($username) {
  error_log("WP login failed for username: $username");
 }
Restart Fail2Ban server to pickup the changes, start some logging, and do some testing.
sudo service fail2ban restart
tail -n 100 -f /var/log/fail2ban.log








REFERENCES
http://blog.somsip.com/2012/02/using-fail2ban-to-protect-wordpress/
http://blog.somsip.com/2012/01/protecting-wordpress-from-script-fishing-attacks-with-fail2ban-more/
http://blog.somsip.com/2011/12/protecting-wordpress-from-script-fishing-attacks-with-fail2ban/

Friday, May 11, 2012

AWStats logfile analyzer 7.0 Documentation

SkyHi @ Friday, May 11, 2012


AWStats logfile analyzer 7.0 Documentation
 



Glossary


Unique Visitor:
A unique visitor is a person or computer (host) that has made at least 1 hit on 1 page of your web site during the current period shown by the report. If this user makes several visits during this period, it is counted only once. Visitors are tracked by IP address, so if multiple users are accessing your site from the same IP (such as a home or office network), they will be counted as a single unique visitor.
The period shown by AWStats reports is by default the current month.
However if you use AWStats as a CGI you can click on the "year" link to have a report for all the year. In such a report, period is a full year, so Unique Visitors are number of hosts that have made at least 1 hit on 1 page of your web site during the year.

Visits:
Number of visits made by all visitors.
Think "session" here, say a unique IP accesses a page, and then requests three other pages within an hour. All of the "pages" are included in the visit, therefore you should expect multiple pages per visit and multiple visits per unique visitor (assuming that some of the unique IPs are logged with more than an hour between requests)

Pages:
The number of "pages" viewed by visitors. Pages are usually HTML, PHP or ASP files, not images or other files requested as a result of loading a "Page" (like js,css... files). Files listed in the NotPageList config parameter (and match an entry of OnlyFiles config parameter if used) are not counted as "Pages".
Hits:
Any files requested from the server (including files that are "Pages") except those that match the SkipFiles config parameter.

Bandwidth:
Total number of bytes for pages, images and files downloaded by web browsing.
Note 1: Of course, this number includes only traffic for web only (or mail only, or ftp only depending on value of LogType).
Note 2: This number does not include technical header data size used inside the HTTP or HTTPS protocol or by protocols at a lower level (TCP, IP...).
Because of two previous notes, this number is often lower than bandwith reported by your provider (your provider counts in most cases bandwitdh at a lower level and includes all IP and UDP traffic).

Entry Page:
First page viewed by a visitor during its visit.
Note: When a visit started at end of month to end at beginning of next month, you might have an Entry page for the month report and no Exit pages.
That's why Entry pages can be different than Exit pages.

Exit Page:
Last page viewed by a visitor during its visit.
Note: When a visit started at end of month to end at beginning of next month, you might have an Entry page for the month report and no Exit pages.
That's why Entry pages can be different than Exit pages.

Session Duration:
The time a visitor spent on your site for each visit.
Some Visits durations are 'unknown' because they can't always be calculated. This is the major reason for this:
- Visit was not finished when 'update' occured.
- Visit started the last hour (after 23:00) of the last day of a month (A technical reason prevents AWStats from calculating duration of such sessions).

Grabber:
A browser that is used primarily for copying locally an entire site. These include for example "teleport", "webcapture", "webcopier"...

Direct access / Bookmark:
This number represent the number of hits or ratio of hits when a visit to your site comes from a direct access. This means the first page of your web site was called:
- By typing your URL on the web browser address bar
- By clicking on your URL stored by a visitor inside its favorites
- By clicking on your URL found everywhere but not another internet web pages (a link in a document, an application, etc...)
- Clicking an URL of your site inside a mail is often counted here.

Add To Favourites:
This value, available in the "miscellanous chart", reports an estimated indicator that can be used to have an idea of the number of times a visitor has added your web site into its favourite bookmarks.
The technical rules for that is the following formula:
Number of Add to Favourites = round((x+y) / r)
where
x = Number of hits made by IE browsers for "/anydir/favicon.ico", with a referer field not defined, and with no 404 error code
y = Number of hits made by IE browsers for "/favicon.ico", with a referer field not defined, with or without 404 error code
r = Ratio of hits made by IE browsers compared to hits made by all browsers (r <= 1)

As you can see in formula, only IE is used to count reliable "add", the "Add to favourites" for other browsers are estimated using ratio of other browsers usage compared to ratio of IE usage. The reason is that only IE do a hit on favicon.ico nearly ONLY when a user add the page to its favourites. The other browsers make often hits on this file also for other reasons so we can't count one "hit" as one "add" since it might be a hit for another reason.
AWStats differentiate also hits with error and not to avoid counting multiple hits made recursively in upper path when favicon.ico file is not found in deeper directory of path.
Note that this number is just an indicator that is in most case higher than true value. The reason is that even IE browser sometimes make hit on favicon without an "Add to favourites" action by a user.
HTTP Status Codes:
HTTP status codes are returned by web servers to indicate the status of a request. Codes 200 and 304 are used to tell the browser the page can be viewed. 206 codes indicate partial downloading of content and is reported in the Downloads section. All other codes generates hits and traffic 'not seen' by the visitor. For example a return code 301 or 302 will tell the browser to ask another page. The browser will do another hit and should finaly receive the page with a return code 200 and 304. All codes that are 'unseen' traffic are isolated by AWStats in the HTTP Status report chart, enabled by the directives ShowHTTPErrorsStats. in config file. You can also change value for 'not error' hits (set by default to 200 and 304 with the ValidHTTPcodesdirective. The following table outlines all status codes defined for the HTTP/1.1 draft specification outlined in IETF rfc 2068.
They are 3-digit codes where the first digit of this code identifies the class of the status code and the remaining 2 digits correspond to the specific condition within the response class. They are classified in 5 categories:
1xx class - Informational
Informational status codes are provisional responses from the web server... they give the client a heads-up on what the server is doing. Informational codes do not indicate an error condition. 
100100 Continue
The continue status code tells the browser to continue sending a request to the server. 
101101 Switching Protocols
The server sends this response when the client asks to switch from HTTP/1.0 to HTTP/1.1 
2xx class - Successful
This class of status code indicates that the client's request was received, understood, and successful. 
200200 Successful
201201 Created
202202 Accepted
203203 Non-Authorative Information
204204 No Content
205205 Reset Content
206206 Partial Content
The partial content success code is issued when the server fulfills a partial GET request. This happens when the client is downloading a multi-part document or part of a larger file. 
3xx class - Redirection
This code tells the client that the browser should be redirected to another URL in order to complete the request. This is not an error condition. 
300300 Multiple Choices
301301 Moved Permanently
302302 Moved Temporarily
303303 See Other
304304 Not Modified
305305 Use Proxy
4xx class - Client Error
This status code indicates that the client has sent bad data or a malformed request to the server. Client errors are generally issued by the webserver when a client tries to gain access to a protected area using a bad username and password. 
400400 Bad Request
401401 Unauthorized
402402 Payment Required
403403 Forbidden
404404 Not Found
405400 Method Not Allowed
406400 Not Acceptable
407400 Proxy Authentication Required
408400 Request Timeout
409409 Conflict
410410 Gone
411411 Length Required
412412 Precondition Failed
413413 Request Entity Too Long
414414 Request-URI Too Long
415415 Unsupported Media Type
5xx class - Server Error
This status code indicates that the client's request couldn't be succesfully processed due to some internal error in the web server. These error codes may indicate something is seriously wrong with the web server. 
500500 Internal Server Error
An internal server error has caused the server to abort your request. This is an error condition that may also indicate a misconfiguration with the web server. However, the most common reason for 500 server errors is when you try to execute a script that has syntax errors. 
501501 Not Implemented
This code is generated by a webserver when the client requests a service that is not implemented on the server. Typically, not implemented codes are returned when a client attempts to POST data to a non-CGI (ie, the form action tag refers to a non-executable file). 
502502 Bad Gateway
The server, when acting as a proxy, issues this response when it receives a bad response from an upstream or support server. 
503503 Service Unavailable
The web server is too busy processing current requests to listen to a new client. This error represents a serious problem with the webserver (normally solved with a reboot). 
504504 Gateway Timeout
Gateway timeouts are normally issued by proxy servers when an upstream or support server doesn't respond to a request in a timely fashion. 
505505 HTTP Version Not Supported
The server issues this status code when a client tries to talk using an HTTP protocol that the server doesn't support or is configured to ignore.


SMTP Status Codes:
SMTP status codes are returned by mail servers to indicate the status of a sending/receiving mail. The status code depends on mail server and preprocessor used to analyze log file.
All codes that are failure codes are isolated by AWStats in the SMTP Status report chart, enabled by the directives 
ShowSMTPErrorsStats in AWStats config file. You can decide which codes are successfull mail transfer that should not appear in this chart with the ValidSMTPCodes directive.
Here are values reported for most mail servers (This should also be values when mail log file is preprocessing with maillogconvert.pl).
SMTP Errors are classified in 3 categories:
2xx/3xx class - Success
They are SMTP protocols successfull answers
200200 Non standard success response
Non standard success response
211211 System status, or system help reply
System status, or system help reply
214214 Help message
Help message
220220 Service ready
Service ready
221221 Service closing transmission channel
Service closing transmission channel
250250 Requested mail action taken and completed
Your ISP mail server have successfully executes a command and the DNS is reporting a positive delivery.
251251 User not local: will forward to 
Your message to a specified email address is not local to the mail server, but it will accept and forward the message to a different recipient email address.
252252 Recipient cannot be verified
Recipient cannot be verified but mail server accepts the message and attempts delivery
354354 Start mail input and end with .
Indicates mail server is ready to accept the message or instruct your mail client to send the message body after the mail server have received the message headers.
4xx class - Temporary Errors
Those codes are temporary error message. They are used to tell client sender that an error occured but he can try to solve it but trying again, so in most cases, clients that receive such codes will keep the mail in their queue and will try again later.
421421 Service not available, closing transmission channel
This may be a reply to any command if the service knows it must shut down.
450450 Requested mail action not taken: mailbox busy or access denied
Your ISP mail server indicates that an email address does not exist or the mailbox is busy. It could be the network connection went down while sending, or it could also happen if the remote mail server does not want to accept mail from you for some reason i.e. (IP address, From address, Recipient, etc.)
451451 Requested mail action aborted: error in processing
Your ISP mail server indicates that the mailing has been interrupted, usually due to overloading from too many messages or transient failure is one in which the message sent is valid, but some temporary event prevents the successful sending of the message. Sending in the future may be successful.
452452 Requested mail action not taken: insufficient system storage
Your ISP mail server indicates, probable overloading from too many messages and sending in the future may be successful.
453453 Too many messages
Some mail servers have the option to reduce the number of concurrent connection and also the number of messages sent per connection. If you have a lot of messages queued up it could go over the max number of messages per connection. To see if this is the case you can try submitting only a few messages to that domain at a time and then keep increasing the number until you find the maximum number accepted by the server.
5xx class - Permanent Errors
This are permanent error codes. Mail transfer is definitly a failure. No other try will be done.
500500 Syntax error, command unrecognized or command line too long
501501 Syntax error in parameters or arguments
502502 Command not implemented
503503 Server encountered bad sequence of commands
504504 Command parameter not implemented
521521 does not accept mail or closing transmission channel
You must be pop-authenticated before you can use this SMTP server and you must use your mail address for the Sender/From field.
530530 Access denied
A sendmailism ?
550550 Requested mail action not taken (Relaying not allowed, Unknown recipient user, ...)
Sending an email to recipients outside of your domain are not allowed or your mail server does not know that you have access to use it for relaying messages and authentication is required. Or to prevent the sending of SPAM some mail servers will not allow (relay) send mail to any e-mail using another company’s network and computer resources.
551551 User not local: please try or Invalid Address: Relay request denied
552552 Requested mail action aborted: exceeded storage allocation
ISP mail server indicates, probable overloading from too many messages.
553553 Requested mail action not taken: mailbox name not allowed
Some mail servers have the option to reduce the number of concurrent connection and also the number of messages sent per connection. If you have a lot of messages queued up (being sent) for a domain, it could go over the maximum number of messages per connection and/or some change to the message and/or destination must be made for successful delivery.
554554 Requested mail action rejected: access denied
557557 Too many duplicate messages
Resource temporarily unavailable Indicates (probable) that there is some kind of anti-spam system on the mail server.


Last revision: $Date: 2010/06/22 21:35:24 $


REFERENCES
http://awstats.sourceforge.net/docs/awstats_glossary.html

Monday, April 23, 2012

Awstats Rebuilding files from old logs

SkyHi @ Monday, April 23, 2012

This is using AWStats 6.3 on Windows Server 2003 and IIS 6.0
My log files will not be processed for 2010. The stats are all fine up to 31/12/2009.
The last file in my DirData folder is 'awstats122009.[config].txt' – there is no 'awstats012010.[config].txt' or later.
If I change my LogFile entry in the conf file to LogFile="C:/Inetpub/vhosts/[domain]/statistics/logs/W3SVC[nnnnn]/ex100101.log" and run "perl awstats.pl -config=[domain] -update", the expected awstats012010.[config].txt is not generated and I get:
Update for config "./awstats.[domain].conf"
With data in log file "C:/Inetpub/vhosts/[domain]/statistics/logs/W3SVC[nnnnn]
/ex100101.log"…
Phase 1 : First bypass old records, searching new record…
Direct access to last remembered record has fallen on another record.
So searching new records from beginning of log file…
Jumped lines in file: 0
Parsed lines in file: 35616
 Found 6 dropped records,
 Found 18 corrupted records,
 Found 35592 old records,
 Found 0 new qualified records.
Attempts at subsequent log files result in the same problem; AWStats thinks these are all old records even though the file for that month does not exist. Any pointers to how to resolve this would be greatly appreciated.



Solution:

Temporarily move all files contained in DirData to another directory and try again. This will allow you to generate the AWStats data files for January 2010. When this is done, move the 2009 data files back to DirData.

OR
backup and comment the "highlighted part" /var/lib/awstats/domain.txt


# LastLine    = Date of last record processed - Last record line number in last log - Last record offset in la
st log - Last record signature value
# FirstTime   = Date of first visit for history file
# LastTime    = Date of last visit for history file
# LastUpdate  = Date of last update - Nb of parsed records - Nb of parsed old records - Nb of parsed new records - Nb of parsed corrupted - Nb of parsed dropped
# TotalVisits = Number of visits
# TotalUnique = Number of unique visitors
# MonthHostsKnown   = Number of hosts known
# MonthHostsUnKnown = Number of hosts unknown
BEGIN_GENERAL 8
LastLine 20120101000113 257865 25669630 36390796923
FirstTime 20111201000008
LastTime 20111231235838
LastUpdate 20120101040228 26376 0 26375 0 0
TotalVisits 16978
TotalUnique 7482
MonthHostsKnown 0
MonthHostsUnknown 11032
END_GENERAL




 So you have a bunch of old logs and you want to put it all together into AWStats to put the historical data in.  Firstly you have to remove any existing AWStats monthly data files from the data directory as AWStats won't enter log information from the past.

Then you need to use a script like the one below to feed the logfiles back into AWStats and have it regenerate the monthly data files:
for %i in (D:\sites\www.fridaynightgaming.com\logs\W3SVC2008\*.log) do perl awstats.pl -config=fridaynightgaming -logfile=%i -update
Obviously change out the example logfile path above for your own.  This is the only way I know of how to import historical log data into AWstats.




REFERENCES
http://www.internetofficer.com/forum/awstats-iis-installation-and-configuration/problem-generating-old-files/
http://www.nakedmcse.com/Home/tabid/39/forumid/1/postid/9/scope/posts/Default.aspx



WordPress Vulnerabilities and How to Fix Them

SkyHi @ Monday, April 23, 2012
Did you know that more than 73 million web sites in the world run on the WordPress publishing platform? This makes WordPress more popular than Microsoft SharePoint, Blogger, or Drupal. It also means that WordPress is a large target for hackers.
Half of the WordPress sites out there are self-hosted, which means that the WordPress administrator carries the lion's share of responsibility for a secure installation. Out of the box, there are several ways that WordPress security can be tightened down, but only a fraction of sites actually do so. This makes WordPress an even more popular target for hackers.
The following five strategies can help any WordPress installation become significantly more secure, and raise awareness of the types of vulnerabilities to defend against.

Vulnerability # 1: SQL Injection & URL Hacking.

The problem: WordPress is a database-backed platform that executes server-side scripts in PHP. Both of these characteristic can make WordPress vulnerable to malicious URL insertion attacks. Commands are sent to WordPress via URL parameters, which can be abused by hackers who know how to construct parameters that WordPress may misinterpret or act on without authorization.
SQL injection describes a class of these attacks in which hackers embed commands in a URL that trigger behaviors from the database. (SQL is the command language used by the MySQL database.) These attacks can reveal sensitive information about the database, potentially giving hackers entrance to modifying the actual content of your site. Many of today's web site defacement attacks are accomplished by some form of SQL Injection.
Other versions of URL hacks can trigger unintended PHP commands which, again, can lead to injecting malware or revealing sensitive information.
The defense: Most WordPress installations are hosted on the popular Apache web server. Apache uses a file named.htaccess to define the access rules for your web site. A thorough set of rules can prevent many types of SQL Injection and URL hacks from being interpreted.
The code below represents a strong set of rules that you can insert into your web site's .htaccess file that will strip URL requests of many dangerous attack injections:

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_METHOD} ^(HEAD|TRACE|DELETE|TRACK) [NC]
RewriteRule ^(.*)$ - [F,L]
RewriteCond %{QUERY_STRING} \.\.\/ [NC,OR]
RewriteCond %{QUERY_STRING} boot\.ini [NC,OR]
RewriteCond %{QUERY_STRING} tag\= [NC,OR]
RewriteCond %{QUERY_STRING} ftp\:  [NC,OR]
RewriteCond %{QUERY_STRING} http\:  [NC,OR]
RewriteCond %{QUERY_STRING} https\:  [NC,OR]
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|%3D) [NC,OR]
RewriteCond %{QUERY_STRING} base64_encode.*\(.*\) [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(\[|\]|\(|\)|<|>|ê|"|;|\?|\*|=$).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*("|'|<|>|\|{||).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(%24&x).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(%0|%A|%B|%C|%D|%E|%F|127\.0).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(globals|encode|localhost|loopback).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(request|select|insert|union|declare).* [NC]
RewriteCond %{HTTP_COOKIE} !^.*wordpress_logged_in_.*$
RewriteRule ^(.*)$ - [F,L]

Vulnerability # 2: Access to Sensitive Files.

The problem: A typical WordPress install contains a number of files which you don’t want outsiders to access. These files, such as the WordPress configuration file, install script, and even the “readme” file should be kept private.
The defense: As with preventing URL hacking, you can add commands to the Apache .htaccess file to block access to sensitive private files. For a typical WordPress installation, the following code will block access to directory listings, plus a set of specific files related to WordPress and the Web server itself.
Options All -Indexes

Order allow,deny
Deny from all


Order allow,deny
Deny from all


Order allow,deny
Deny from all


Order allow,deny
Deny from all


Order allow,deny
Deny from all


Order allow,deny
Deny from all


Order allow,deny
Deny from all


Order allow,deny
Deny from all

Vulnerability # 3: Default Admin User Account.

The problem: Many default WordPress installs include an administrator user account whose username is simply “admin”. Hackers may try to log into this account using guessed passwords.
The defense: Any element of predictability gives hackers an edge. Although a hacker would still need to guess or brute-force your password to access the admin account, you are even more secure without an “admin” account at all.
Instead, log into WordPress and create a new user with an unpredictable name. Assign administrator privileges to this user. Now delete the account named “admin”. A hacker would now need to guess both the username and password to gain administrator access, a significantly more challenging feat.

Vulnerability # 4: Default Prefix for Database Tables

The problem: The WordPress database consists of numerous tables. In many WordPress installs, these tables are named with a default prefix that begins with “wp_“. For hackers, the ability to predict anything can provide an extra advantage.
The defense: Changing the prefix of your WordPress tables can eliminate this predictability. Some security experts argue that this will not stop a savvy hacker who can use other means to determine the table names in your installation. While this is true when talking about a knowledgeable hacker, many amateur hackers use pre-packaged scripts to perform their dirty work and these are more likely to be successfully blocked by eliminating predictable table names.
When setting up a new WordPress install, you can specify the database table prefix yourself. This gives you the opportunity to choose something unique and unpredictable. If WordPress is already installed, you can retroactively change the table names. Although this can be done manually, the process requires directly manipulating the database in several places.
An easier way to change table prefixes for an existing WordPress installation is by using the plugin named Better WP Security. This plugin contains several defenses including some discussed elsewhere in this article, with a simple point-and-click interface to change your table names to include a randomly-generated prefix.

Vulnerability # 5: Brute-Force Login Attempts

The problem: Hackers often rely on automated scripts to do their dirty work. These scripts can make numerous attempts to log into your WordPress administration page by trying thousands and millions of combinations of usernames and passwords. Not only can being bombed with login attempts slow down your web site for legitimate users, it may also succeed—giving hackers complete control of your site.
The defense: Of course, you should start with always using strong passwords. A longer, mixed-type password will take longer for a brute-force attack to decode. These attacks typically use combinations of dictionary words and numbers. (But remember that malware can render strong passwords useless.)
An even more effective defense is to install a login limiter for WordPress. A login limiter can essentially block or quarantine an IP address or username which tries and fails to send login requests above a threshold rate. For example, a login limit of 10 attempts per 5 minutes can be backed up with a penalty timeout of 1 hour.
A successful brute-force attack against a strong password effectively becomes impossible with these limits in place, because the hacker can never try enough variations (or rather, it would take many years of continuous attempts).
Two WordPress plugins which let you enforce a login limiter are Limit Login Attempts and the aforementioned Better WP Security.
These five strategies are the beginning of effective WordPress security—not the end. Like any form of security, defending WordPress is an ongoing process that must involve awareness of new threats combined with specific details about your own install environment.

REFERENCES

Friday, April 20, 2012

Iptables: My most used commands

SkyHi @ Friday, April 20, 2012

This is a small manual of iptables, I’ll show some basic commands, you may need to know to keep your computer secure.

Basic commands

List rules
iptables -L
This is going, list the default table “Filter”.
Edit: You may prefer to use iptables -L -vn to get more information, and to see ports as numbers instead of its names.
List rules in specific table
iptables -L -t nat
You can also list the other tables like: mangle, raw and security. You should consider reading a bit more about tables. You can do it in the Tables section in the man page of iptables
Delete all rules
iptables -F
Delete specific table liket nat
iptables -t nat -F
Specify chain policies
iptables let’s you configure default policies for chains in the filter table, where INPUT, FORWARD and OUTPUT, are the main ones (or at least the most used). Users can even define new chains.
These aforementioned chains, are better explained in this graph that comes from Wikipedia.
iptables chains
You can see the original image here
iptables -P INPUT DROP
iptables -P FORWARD ACCEPT
iptables -P OUTPUT DROP
You can define the default policy as ACCEPT and then deny specific traffic, or define default policies as DROP and then open specific traffic to and/or from your box. The last one is more secure, but require more job.
Block IP traffic from an specific IP or Network.
Block from an IP
iptables -A INPUT -s 11.22.33.44 -j DROP
If you want to block only on an specific NIC
iptables -A INPUT -s 11.22.33.44 -i eth0 -j DROP
Or an specific port
iptables -A INPUT -s 11.22.33.44 -p tcp -dport 22 -j DROP
Using a Network and not only one IP
iptables -A INPUT -s 11.22.33.0/24 -j DROP
Block traffic from a specific MAC address
Suppose you want to bloc traffic some a MAC address instead of an IP address. This is handy if a DHCP server is changing the IP of the maching you want to protect from.
iptables -A INPUT -m mac --mac-source 00:11:2f:8f:f8:f8 -j DROP
Block a specific port
If all you want is to block a port, iptables can still do it.
And you can block incoming or outgoing traffic.
Block incoming traffic to a port
Suppose we need to block port 21 for incoming traffic:
iptables -A INPUT -p tcp --destination-port 21 -j DROP
But if you have two-NIC server, with one NIC facing the Internet and the other facing your local private Network, and you only one to block FTP access from outside world.
iptables -A INPUT -p tcp -i eth1 -p tcp --destination-port 21 -j DROP
In this case I’m assuming eth1 is the one facing the Internet.
You can also block a port from a specific IP address:
iptables -A INPUT -p tcp -s 22.33.44.55 --destination-port 21 -j DROP
Or even block access to a port from everywhere but a specific IP range.
iptables -A INPUT p tcp -s ! 22.33.44.0/24 --destination-port 21 -j DROP
Block outgoing traffic to a port
If you want to forbid outgoing traffic to port 25, this is useful, in the case you are running a Linux firewall for your office, and you want to stop virus from sending emails.
iptables -A FORWARD -p tcp --dport 25 -j DROP
I’m using FORWARD, as in this example the server is a firewall, but you can use OUTPUT too, to block also server self traffic.
Log traffic, before taking action
If you want to log the traffic before blocking it, for example, there is a rule in an office, where all employees have been said not to log into a given server, and you want to be sure everybody obeys the rule by blocking access to ssh port. But, at the same time you want to find the one who tried it.
iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "dropped access to port 22"
iptables -A INPUT -p tcp --dport 22 -j DROP
You will be able to see which IP tried to access the server, but of course he couldn’t.

Tips and Tricks

Because iptables executes the rules in order, if you want to change something you need to insert the rule in the specific position, or the desired effect is not going to be achieved.
List rules with numbers
iptables -nL --line-numbers
This is going to list all your rules with numbers preceding the rules. Determine where you want the inserted rule and write:
List specific chains
iptables -nL INPUT
Will list all INPUT rules.
iptables -nL FORWARD
Will list all OUTPUT rules
Insert rules
iptables -I INPUT 3 -s 10.0.0.0/8 -j ACCEPT
That is going to add a rule in position 3 of the “array”
Delete rules
iptables -D INPUT 3
That is going to remove the rule inserted above. You can also remove it, by matching it.
iptables -D INPUT -s 10.0.0.0/8 -j ACCEPT
Delete flush all rules and chains
This steps are very handy if you want to start with a completely empty and default tables:
iptables --flush
iptables --table nat --flush
iptables --table mangle --flush
iptables --delete-chain
iptables --table nat --delete-chain
iptables --table mangle --delete-chain
NOTE: do not execute this rules if you are connected via ssh or something similar, you may get locked out

Simple scripts for specific needs

How to stop brute force attacks
You can also use iptables to stop brute force attacks to your server, for example: Allow only three attempts to log through ssh before banning the IP for 15 minutes, this should let legitimate users to log to the servers, but bots will not be able. Remember to always use strong passwords
iptables -F
iptables -A INPUT -i lo -p all -j ACCEPT
iptables -A OUTPUT -o lo -p all -j ACCEPT                    
iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport ssh -j ACCEPT
iptables -A INPUT -p tcp --dport www -j ACCEPT
iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --update --seconds 900 --hitcount 3 -j DROP
iptables -P INPUT DROP
How to NAT with iptables
iptables is also very useful to configure NAT routers, a Linux mashing can act as a router, and share its public IP with a private networks behind it. It is also useful to configure the DHCP in the same server.
To configure a NAT router, you will be better with a server with two NICs, let’s suppose you have:
  • eth0: 12.13.14.15
  • eth1: 10.1.1.1
Now configure NAT to forward all traffic from 10.1.1.0 network through eth0 IP. You may want to empty all tables and start with a fresh chains and tables (see how above).
iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE
iptables --append FORWARD --in-interface eth1 -j ACCEPT
That is it, you only have to enable kernel forwarding now:
echo 1 > /proc/sys/net/ipv4/ip_forward



REFERENCES