2

I have a mini listener/daemon to catch SNMP trap. This will listener executed while running the main project (spring web) on tomcat7. But I always got error java.net.BindException: Permission denied

I have try to use authbind (http://java-notes.com/), but my problem not solved. I also had tried to change the port to greater one, but I got error java.net.BindException: Cannot assign requested address

This is my application/trap-receiver code:

@Component
public class TrapReceiver extends Thread implements CommandResponder {

    @Inject
    private ApplicationContext applicationContext;

    @Inject
    private Executor executor;

    public TrapReceiver(){
    }

    List<PDUv1> listPdu = new ArrayList<PDUv1>();
    String message = "";
    long totReceivedTrap = 0;

    @PostConstruct
    public void init() {
        System.out.println("Running trap listener");
        this.start();
    }

    public synchronized void processPdu(CommandResponderEvent cmdRespEvent) {
        PDUv1 pdu = (PDUv1) cmdRespEvent.getPDU();
        listPdu.add(pdu);
        if (pdu != null) {
            if(listPdu.size() == 10){ //10 trap per thread
                List<PDUv1> temp = new ArrayList<PDUv1>();
                temp.addAll(listPdu);
                TrapInsertor trapInsertor = (TrapInsertor) applicationContext.getBean("trapInsertor");
                trapInsertor.setProperty(temp);
                executor.execute(trapInsertor);
                listPdu.clear();
            }
        }
    }

    public void run() {
        while (true) {
            try {
                this.listen(new UdpAddress(getIp()+"/162")); //alamat PDU akan listen
            } catch (Exception e) {
                e.printStackTrace();
            } 
        }
    }

    public synchronized void listen(TransportIpAddress address)
            throws IOException {
        AbstractTransportMapping transport;
        if (address instanceof TcpAddress) {
            transport = new DefaultTcpTransportMapping((TcpAddress) address);
        } else {
            transport = new DefaultUdpTransportMapping((UdpAddress) address);
        }

        ThreadPool threadPool = ThreadPool.create("DispatcherPool", 10);
        MessageDispatcher mDispathcher = new MultiThreadedMessageDispatcher(
                threadPool, new MessageDispatcherImpl());

        // add message processing models
        mDispathcher.addMessageProcessingModel(new MPv1());
        mDispathcher.addMessageProcessingModel(new MPv2c());

        // add all security protocols
        SecurityProtocols.getInstance().addDefaultProtocols();
        SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES());

        // Create Target
        CommunityTarget target = new CommunityTarget();
        target.setCommunity(new OctetString("public"));

        Snmp snmp = new Snmp(mDispathcher, transport);
        snmp.addCommandResponder(this);

        transport.listen();
        System.out.println("Listening on " + address);

        try {
            this.wait();
        } catch (InterruptedException ex) {
            Thread.currentThread().interrupt();
        }
    }

    //fungsi untuk mendapatkan real ip local (bukan 127.0.0.1)
    public static String getIp(){
        String ipAddress = null;
        Enumeration<NetworkInterface> net = null;
        try {
            net = NetworkInterface.getNetworkInterfaces();
        } catch (SocketException e) {
            throw new RuntimeException(e);
        }

        while(net.hasMoreElements()){
            NetworkInterface element = net.nextElement();
            Enumeration<InetAddress> addresses = element.getInetAddresses();
            while (addresses.hasMoreElements()){
                InetAddress ip = addresses.nextElement();
                if (ip instanceof Inet4Address){
                    if (ip.isSiteLocalAddress()){
                        ipAddress = ip.getHostAddress();
                    }
                }
            }
        }
        return ipAddress;
    }

}
Mahadi Siregar
  • 615
  • 3
  • 17
  • 38
  • Have you actually changed or added the port in Tomcat's `server.xml`? otherwise you probably only have 8080 available – Dragondraikk Jun 01 '15 at 07:56
  • The problem is on my snmp-listener, I want it on at port 162. There is no problem with my tomcat. Or is it also configured in server.xml? – Mahadi Siregar Jun 01 '15 at 08:06
  • Assuming your TrapReceiver registers with the SNMP server, it will supply its listening address and port number so it doesn't have to be 162. Though if for some other reason, you need to use that port, then I agree with existing answer from @atafar. – k1eran Jun 01 '15 at 10:48
  • Is it mean that I must configure it in server.xml? Adding port maybe? Sorry newbie :) – Mahadi Siregar Jun 01 '15 at 11:32
  • How do you today tell the SNMP agent to send traps to your traphandler (SNMP-manager) application ? – k1eran Jun 01 '15 at 13:23
  • My problem now is this error: java.net.BindException: Cannot assign requested address. My host config: 127.0.0.1 localhost 127.0.1.1 test-server 124.81.xx.x test-server.com – Mahadi Siregar Jun 02 '15 at 07:44
  • Your last comment perhaps should be in a separate question - or it still related to low ports? – k1eran Jun 02 '15 at 08:31
  • Oh., ok. I post it in new thread http://stackoverflow.com/questions/30611516/java-net-bindexception-cannot-assign-requested-address – Mahadi Siregar Jun 03 '15 at 05:30

3 Answers3

1

You need to be root to bind to a low port on Linux systems. Be sure to run your Java application with sufficient privileges. When connecting to a high port be sure it is not already in use by some other process/service.

See also Binding to a Privileged Port on Debian/Ubuntu about enabling AUTHBIND on Ubuntu.

Atafar
  • 697
  • 7
  • 10
  • Do you mean to change the tomcat7 user group to be root? (on /etc/default/tomcat7), in another thread said that it is not recommended. I have check if the port is listened, the port is unused. I had also try this http://mprabhat.com/2012/11/05/tomcat-java-net-bindexception-cannot-assign-requested-address-jvm_bind/, but not solving the problem – Mahadi Siregar Jun 01 '15 at 08:13
  • To be specific: All ports up to 1024 can only be used with root priviliges. See also http://stackoverflow.com/questions/413807/is-there-a-way-for-non-root-processes-to-bind-to-privileged-ports-1024-on-l – André Stannek Jun 01 '15 at 08:14
  • So it's need to change tomcat group on /etc/default/tomcat7. I still not try it, or maybe in another configuration file – Mahadi Siregar Jun 01 '15 at 08:20
  • If you do not wish to run Tomcat as root, you can have a look at [How to run Tomcat without root privileges?](http://wiki.apache.org/tomcat/HowTo#How_to_run_Tomcat_without_root_privileges.3F) – Atafar Jun 01 '15 at 08:37
  • i had try to change tomcat7 as root, but I got error java.net.BindException: Cannot assign requested address. My host config: 27.0.0.1 localhost 127.0.1.1 test-server # The following lines are desirable for IPv6 capable hosts #::1 localhost ip6-localhost ip6-loopback #ff02::1 ip6-allnodes #ff02::2 ip6-allrouters 124.81.xx.x test-server.com – Mahadi Siregar Jun 01 '15 at 10:18
  • Could be your firewall is blocking access. Check your logs for more information. – Atafar Jun 01 '15 at 11:52
0

You should be using a port beyond the range of 1024 since they are privileged ports. Try using 1048 and configure the same port in the application when you are providing SNMP Manager details.

Red John
  • 167
  • 10
0

Permission denied is a common exception, which means that the current user does not have enough accesses to open a port. One solution can be if you change you port number greater than 1024, Ports below 1024 are called Privileged Ports and in Linux (and most UNIX flavors and UNIX-like systems), they are not allowed to be opened by any non-root user.

confused
  • 151
  • 4