How to grant access permission on network interface?

1,418

You need to be root to do the kind of snooping that tcpflow and tcpdump do. So you either need sudo or a setuid root wrapper.

Well, technically all you need the CAP_NET_RAW capability. If you install the libcap2-bin package¹, you can use the setcap command to create a “setcap-CAP_NET_RAW” wrapper around tcpflow, rather than a setuid wrapper. But that only helps make a security hole in the wrapper be a little less damaging (a user who obtains CAP_NET_RAW access can probably gain root with little effort).

You can use sudo or a setuid root wrapper to let user1 run a command like tcpflow -i eth0 tcp and \( src host 1.2.3.4 and src port 3000 or dst host 1.2.3.4 and src port 3000 \). Note that you can't just let user1 run an arbitrary tcpflow command: that would allow user1 to run things like tcpflow -r … -r /path/to/foo and read (at least partially) /path/to/foo with root permissions.

I don't think you'll be decently able to allow the user to specify an expression to match packets. Rather than give extra permissions to run tcpflow, I suggest giving extra permissions to run a fixed tcpdump command (writing to stdout, let the user redirect into a file if necessary). Then the user can run tcpflow -r to analyze tcpdump output (even in real time, through a pipe).

Now for lo, allow user1 to run this exact command:

tcpdump -i lo tcp

For other interfaces, I think the following command selects tcp ports 3000–3999 (but make extensive tests to be sure):

tcpdump -i eth0 tcp and \( \
  \( src host 1.2.3.4 and 'tcp[0:2] >= 3000' and 'tcp[0:2] <= 3999' \) or
  \( dst host 1.2.3.4 and 'tcp[2:2] >= 3000' and 'tcp[2:2] <= 3999' \) \)

Replace 1.2.3.4 by the IP address associated with the interface. I don't have a good solution to offer if the IP address isn't fixed: if you read it from ifconfig output or otherwise at the beginning of the wrapper script, it's open to a race condition.

My recommendation for a wrapper is not to use a shell script (I don't know if any of the shells in Debian is suitable for writing setuid scripts — shells tend to use a lot of environment variables), but rather Perl (where this kind of thing is explicitly supported), like this:

#!/usr/bin/perl -T
exec '/usr/sbin/tmpdump', '-i', 'lo', 'tcp'

Make the script an ordinary executable (mode 755), and allow user1 to run it through sudo.

¹ For other Linux distributions: you need kernel 2.6.24 or above and the setcap command.

Share:
1,418
zhouxiang
Author by

zhouxiang

Updated on September 17, 2022

Comments

  • zhouxiang
    zhouxiang over 1 year

    i'm using centos 6 and jboss 7.1.1 final. i using this command to start jboss:./domain.sh,when it start,it output a lot of logs,and the worst thing is just when i disconnect the ssh,the server is down.i've already tried another command ./domain.sh & ,nothing changes. in the domain.sh,it says,

         if [ "x$LAUNCH_JBOSS_IN_BACKGROUND" = "x" ]; then
          # Execute the JVM in the foreground
          eval \"$JAVA\" -D\"[Process Controller]\" $PROCESS_CONTROLLER_JAVA_OPTS \
             \"-Dorg.jboss.boot.log.file=$JBOSS_LOG_DIR/process-controller.log\" \
             \"-Dlogging.configuration=file:$JBOSS_CONFIG_DIR/logging.properties\" \
             -jar \"$JBOSS_HOME/jboss-modules.jar\" \
             -mp \"${JBOSS_MODULEPATH}\" \
             org.jboss.as.process-controller \
             -jboss-home \"$JBOSS_HOME\" \
             -jvm \"$JAVA_FROM_JVM\" \
             -mp \"${JBOSS_MODULEPATH}\" \
             -- \
             \"-Dorg.jboss.boot.log.file=$JBOSS_LOG_DIR/host-controller.log\" \
             \"-Dlogging.configuration=file:$JBOSS_CONFIG_DIR/logging.properties\" \
             $HOST_CONTROLLER_JAVA_OPTS \
             -- \
             -default-jvm \"$JAVA_FROM_JVM\" \
             "$@"
          JBOSS_STATUS=$?
       else
          # Execute the JVM in the background
          eval \"$JAVA\" -D\"[Process Controller]\" $PROCESS_CONTROLLER_JAVA_OPTS \
             \"-Dorg.jboss.boot.log.file=$JBOSS_LOG_DIR/process-controller.log\" \
             \"-Dlogging.configuration=file:$JBOSS_CONFIG_DIR/logging.properties\" \
             -jar \"$JBOSS_HOME/jboss-modules.jar\" \
             -mp \"${JBOSS_MODULEPATH}\" \
             org.jboss.as.process-controller \
             -jboss-home \"$JBOSS_HOME\" \
             -jvm \"$JAVA_FROM_JVM\" \
             -mp \"${JBOSS_MODULEPATH}\" \
             -- \
             \"-Dorg.jboss.boot.log.file=$JBOSS_LOG_DIR/host-controller.log\" \
             \"-Dlogging.configuration=file:$JBOSS_CONFIG_DIR/logging.properties\" \
             $HOST_CONTROLLER_JAVA_OPTS \
             -- \
             -default-jvm \"$JAVA_FROM_JVM\" \
             "$@" "&"
          JBOSS_PID=$!
          # Trap common signals and relay them to the jboss process
          trap "kill -HUP  $JBOSS_PID" HUP
          trap "kill -TERM $JBOSS_PID" INT
          trap "kill -QUIT $JBOSS_PID" QUIT
          trap "kill -PIPE $JBOSS_PID" PIPE
          trap "kill -TERM $JBOSS_PID" TERM
          if [ "x$JBOSS_PIDFILE" != "x" ]; then
            echo $JBOSS_PID > $JBOSS_PIDFILE
          fi
          # Wait until the background process exits
          WAIT_STATUS=128
          while [ "$WAIT_STATUS" -ge 128 ]; do
             wait $JBOSS_PID 2>/dev/null
             WAIT_STATUS=$?
             if [ "$WAIT_STATUS" -gt 128 ]; then
                SIGNAL=`expr $WAIT_STATUS - 128`
                SIGNAL_NAME=`kill -l $SIGNAL`
                echo "*** JBossAS process ($JBOSS_PID) received $SIGNAL_NAME signal ***" >&2
             fi
          done
          if [ "$WAIT_STATUS" -lt 127 ]; then
             JBOSS_STATUS=$WAIT_STATUS
          else
             JBOSS_STATUS=0
          fi
          if [ "$JBOSS_STATUS" -ne 10 ]; then
                # Wait for a complete shudown
                wait $JBOSS_PID 2>/dev/null
          fi
          if [ "x$JBOSS_PIDFILE" != "x" ]; then
                grep "$JBOSS_PID" $JBOSS_PIDFILE && rm $JBOSS_PIDFILE
          fi
       fi
       if [ "$JBOSS_STATUS" -eq 10 ]; then
          echo "Restarting JBoss..."
       else
          exit $JBOSS_STATUS
       fi
    

    i tried to remove the if clause,but there is no miracle

    or how to install the jboss 7 as service.thanks a lot.

    • Guntram Blohm
      Guntram Blohm over 10 years
      Better ask this on serverfault.com or possibly superuser.com, since it's more of an administration problem than a programming problem.
  • Xiè Jìléi
    Xiè Jìléi over 13 years
    Very detailed explanation!