Configuring Firewall Packet Filtering Using iptables

This article was tested using iptables v1.3.5 running on CentOS.

Displaying Currently Active Rule

iptables -L -v -n

-v flag turns on verbose mode, and -n causes hostname to be resolved into IP when displaying.

Adding A New Rule

iptables -A INPUT -j ACCEPT -s 50.57.11.123 -m comment --comment 'Reverse proxy'

Above rule will be added to the end of INPUT chain, and when rule matches (packing coming from ip 50.57.11.123), it will be accepted

Rejecting Packets Created From Inbound Conenctions

In the following example all packets from inbound connection are rejected, but not outbound. The only inbound packets allowed are from 72.8.190.105 and 199.241.192.0/22

Chain INPUT (policy ACCEPT 704K packets, 218M bytes)
 pkts bytes target     prot opt in     out     source               destination
  36M 4776M ACCEPT     all  --  *      *       72.8.190.105         0.0.0.0/0       /* Allow incoming from Reverse Proxy*/
4439K  577M ACCEPT     all  --  *      *       199.241.192.0/22     0.0.0.0/0       /* Allow incoming from Reverse Proxy */
  10M 2897M ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0       state RELATED,ESTABLISHED /* Accept incoming packets from already established conn */
14586  878K REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0       /* Reject everything else */ reject-with icmp-port-unreachable

This is achieved by checking state. If incoming packet is associated with TCP connection with RELATED / ESTABLISHED then it will be allowed.

Such rule can be added using

iptables -A INPUT -j REJECT -m state --state ESTABLISHED,RELATED -m comment --comment 'Reject everything else'

Saving Rules

Use /sbin/service iptables save to persist changes for the next time the server is rebooted.

Looking up Command for Currently Configure Rules

When you saved your iptables settings, the command used to reconstruct the rules can be looked up on /etc/sysconfig/iptables file

Advertisements

Testing SMTP Server Using Telnet

SMTP server can be tested simply by using telnet client. On Windows 7 above telnet client has to be installed first via control panel (Windows Add/Remove Features)

Following is a sample SMTP commands to send for a standard mail server listening on IP 12.23.34.45 port 25, without authentication

C:\telnet 12.23.34.45 25
HELO mycompany.com
MAIL FROM:support@mycompany.com
RCPT TO:gerry@somedomain.com
DATA
To: Gerry Tan <gerry@somedomain.com>
From: My Company Support <support@mycompany.com>
Subject: Testing mail server via SMTP
Please ignore this email as this is just testing mail server via SMTP

.
quit

The two newlines and dot at the end is important.

SMTP Server With Authentication

To use SMTP username / password authentication, you first need to encrypt it to Base64. It can be done with command line perl:

 perl -MMIME::Base64 -e 'print encode_base64("gerrytan");'
 perl -MMIME::Base64 -e 'print encode_base64("Mypass123");'

Becareful if you username / password contains symbols meaningful to perl! An @ character can be interpreted as perl array. You have to escape it using \ (I spent an hour figuring out why authentication failed due to this).

And issue AUTH LOGIN command after HELO / EHLO. The server will prompt for username and password in Base 64

220 mail.tpg.com.au ESMTP (mail16) Sendmail ready.
EHLO mail.tpg.com.au
250-mail16.tpgi.com.au Hello webmail.mxtglobal.com [220.245.123.18], pleased to
meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE 28521268
250-DSN
250-AUTH LOGIN PLAIN
250-STARTTLS
250-DELIVERBY
250 HELP
AUTH LOGIN
334 VXNlcm5hbWU6
**********
334 UGFzc3dvcmQ6
**********
235 2.0.0 OK Authenticated
MAIL FROM:gerry@email.com
250 2.1.0 gerry@email.com... Sender ok
RCPT TO:bob@email.com
RC250 2.1.5 bob@email.com... Recipient ok

Thanks to http://exchange.mvps.org/smtp_frames.htm.

Using Spring Data MongoDB

Spring Data MongoDB provides a great third party support based on standard MongoDB Java Driver.

Dependencies

Following dependencies are required. Check for latest version via Nexus Central Repository:

  1. spring-data-mongodb
    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-mongodb</artifactId>
      <version>1.2.1.RELEASE</version>
    </dependency>
    
  2. mongo-java-driver
    <dependency>
      <groupId>org.mongodb</groupId>
      <artifactId>mongo-java-driver</artifactId>
      <version>2.11.1</version>
    </dependency>
    

Setup Mongo Connection, Template and Repository Scanning

This is similar idea with setting up db datasource. In this example the mongo database server is located at localhost:27017 (default). The MongoDB database name used is enrollment. The <mongo:repositories ...> tag specifies the base package to scan for repository classes

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:mongo="http://www.springframework.org/schema/data/mongo"
  xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.2.xsd
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  <mongo:mongo host="localhost" port="27017" />

  <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg ref="mongo" />
    <constructor-arg value="enrollment" />
  </bean>
  
  <mongo:repositories base-package="com.gerrydevstory.enrollment"/>
</beans>

Domain / Entity Class

Example on this post will be based on a simple Student entity class with only id and name field:

import org.springframework.data.annotation.Id;

public class Student {
  @Id private String id;
  private String name;
  // getters & setters..
}

Without explicit configuration this entity class will be mapped into MongoDB collection name student. To override this default behavior use @Document(collection = "...") annotation.

Repository Class

Simply add an interface extending Spring Data Repository interface. Below sample uses PagingAndSortingRepository, which extends CrudRepository which provides most basic operation. The type parameter specifies this repository operates over Student entity, with the ID type being String. Spring Data will automatically generate an implementation of this interface.

public interface StudentRepository extends PagingAndSortingRepository<Student, String> {

}

This repository can now be injected into controllers:

@Controller
@RequestMapping("/student")
public class StudentController {

  @Autowired private StudentRepository studentRepository;

  @RequestMapping(method = GET)
  public String get(Model model) {
    Iterable<Student> students = studentRepository.findAll();
    return "student";
  }

  @RequestMapping(value = "/new", method = POST)
  public String addNew(@ModelAttribute("student") Student student) {
    studentRepository.save(student);
  }

  ...
}

Read More

Learn more about Spring Data and MongoDB:

Eclipse Unable to Detect Glassfish 3 Server Is Started

Found this problem on my Windows 7 PC where when I tried to start my Glassfish 3 server via Eclipse it seems to start alright, but Eclipse could not detect it has started.

On the server panel progress bar is stuck at “Starting glassfish..” message, and after few minutes it will say “Unable to start server on time”.. yet the server process is still running on the background.

glassfish

Thanks to this StackOverflow answer by HAmark, this problem seem to be caused by Java unable to resolve the host name “localhost”.

This can be resolved by adding following entry on your C:\Windows\System32\drivers\etc\hosts file:

127.0.0.1 localhost

Sending E-Mail Using GMail SMTP via Apache Commons Emails

GMail provides a handy and reliable SMTP mail server for your program / script. Following are GMail SMTP configuration settings:

  • SMTP Host Name: smtp.gmail.com
  • SMTP Port: 587
  • TLS Enabled: Yes
  • Username: <your GMail email>
  • Password: <your gmail password>

In Java you can use commons-email to simply send an E-Mail using your GMail account.

First add commons-email jar into your classpath. If you use Maven, simply add following dependency (or newer version if any):

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-email</artifactId>
  <version>1.3.1</version>
</dependency>

Following example assumes your GMail email is johndoe@gmail.com and password abcd1234.

Email email = new SimpleEmail();
email.setSmtpPort(587);
email.setHostName("smtp.gmail.com");
email.setAuthentication("johndoe@gmail.com", "abcd1234");
email.setStartTLSEnabled(true);
email.setFrom("johndoe@gmail.com", "John Doe");
email.setSubject("Hi this is testing email only");
email.setMsg("Hello there testing to send email from GMail");
email.addTo("someone@outhere.com");
email.send();

Note that by default GMail only allows email to be sent from your address (johndoe@gmail.com), you cannot send as somebody else for security reason. You need to perform additional configuration to allow external email to be sent via your GMail account.

Using Maven to Include All Java EE API Into Classpath

If you use full Java EE container such as JBoss or Glassfish — and you (are fortunate enough) to use Maven. Here’s a simple way to pull all Java EE dependencies into your classpath. Add following dependency into your pom.xml:

<dependency>
  <groupId>javax</groupId>
  <artifactId>javaee-api</artifactId>
  <version>6.0</version>
  <scope>provided</scope>
</dependency>

Notice the scope is set to provided, this is important because on runtime all those classes will be provided by your container.

Also the above is for Java EE 6. You can use following for Java EE 7:

<dependency>
  <groupId>javax</groupId>
  <artifactId>javaee-api</artifactId>
  <version>7.0</version>
  <scope>provided</scope>
</dependency>

Java EE Tutorial Sample Codes

If you ever tried to obtain Java EE tutorial sample codes according to the official getting started guide you must feel how frustrating it is.

Fortunately the tutorial sample code can be easily obtained from SVN:

Thanks to the guys on this Stack Overflow Q&A.